From 6b3974fe1c4616d8b9872d88d737623cc48c4368 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 2 Jul 2022 22:10:55 -0600 Subject: subvolumes --- pkg/btrfs/btrfsitem/item_rootref.go | 34 ++++++++++++++++++++++++++++++++++ pkg/btrfs/btrfsitem/item_uuid.go | 3 +++ pkg/btrfs/btrfsitem/items.txt | 2 ++ pkg/btrfs/btrfsitem/items_gen.go | 5 +++++ pkg/btrfs/internal/itemtype.go | 4 ++++ pkg/btrfsmisc/print_tree.go | 18 +++++++++++++----- 6 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 pkg/btrfs/btrfsitem/item_rootref.go (limited to 'pkg') diff --git a/pkg/btrfs/btrfsitem/item_rootref.go b/pkg/btrfs/btrfsitem/item_rootref.go new file mode 100644 index 0000000..567e9c7 --- /dev/null +++ b/pkg/btrfs/btrfsitem/item_rootref.go @@ -0,0 +1,34 @@ +package btrfsitem + +import ( + "lukeshu.com/btrfs-tools/pkg/binstruct" + "lukeshu.com/btrfs-tools/pkg/btrfs/internal" +) + +type RootRef struct { // ROOT_REF=156 ROOT_BACKREF=144 + DirID internal.ObjID `bin:"off=0x00, siz=0x8"` + Sequence int64 `bin:"off=0x08, siz=0x8"` + NameLen uint16 `bin:"off=0x10, siz=0x2"` // [ignored-when-writing] + binstruct.End `bin:"off=0x12"` + Name []byte `bin:"-"` +} + +func (o *RootRef) UnmarshalBinary(dat []byte) (int, error) { + n, err := binstruct.UnmarshalWithoutInterface(dat, o) + if err != nil { + return n, err + } + o.Name = dat[n : n+int(o.NameLen)] + n += int(o.NameLen) + return n, nil +} + +func (o RootRef) MarshalBinary() ([]byte, error) { + o.NameLen = uint16(len(o.Name)) + dat, err := binstruct.MarshalWithoutInterface(o) + if err != nil { + return dat, err + } + dat = append(dat, o.Name...) + return dat, nil +} diff --git a/pkg/btrfs/btrfsitem/item_uuid.go b/pkg/btrfs/btrfsitem/item_uuid.go index d66e102..6b47547 100644 --- a/pkg/btrfs/btrfsitem/item_uuid.go +++ b/pkg/btrfs/btrfsitem/item_uuid.go @@ -7,6 +7,9 @@ import ( // The Key for this item is a UUID, and the item is a list of // subvolume IDs (ObjectIDs) that that UUID maps to. +// +// key.objectid = first half of UUID +// key.offset = second half of UUID type UUIDMap []internal.ObjID // UUID_SUBVOL=251 UUID_RECEIVED_SUBVOL=252 func (o *UUIDMap) UnmarshalBinary(dat []byte) (int, error) { diff --git a/pkg/btrfs/btrfsitem/items.txt b/pkg/btrfs/btrfsitem/items.txt index a5f247f..2820788 100644 --- a/pkg/btrfs/btrfsitem/items.txt +++ b/pkg/btrfs/btrfsitem/items.txt @@ -17,7 +17,9 @@ METADATA_ITEM=169 Metadata ORPHAN_ITEM=48 Empty PERSISTENT_ITEM=249 DevStats QGROUP_RELATION=246 Empty +ROOT_BACKREF=144 RootRef ROOT_ITEM=132 Root +ROOT_REF=156 RootRef SHARED_BLOCK_REF=182 Empty SHARED_DATA_REF=184 SharedDataRef TREE_BLOCK_REF=176 Empty diff --git a/pkg/btrfs/btrfsitem/items_gen.go b/pkg/btrfs/btrfsitem/items_gen.go index 92e2523..030202b 100644 --- a/pkg/btrfs/btrfsitem/items_gen.go +++ b/pkg/btrfs/btrfsitem/items_gen.go @@ -28,7 +28,9 @@ const ( ORPHAN_ITEM_KEY = internal.ORPHAN_ITEM_KEY PERSISTENT_ITEM_KEY = internal.PERSISTENT_ITEM_KEY QGROUP_RELATION_KEY = internal.QGROUP_RELATION_KEY + ROOT_BACKREF_KEY = internal.ROOT_BACKREF_KEY ROOT_ITEM_KEY = internal.ROOT_ITEM_KEY + ROOT_REF_KEY = internal.ROOT_REF_KEY SHARED_BLOCK_REF_KEY = internal.SHARED_BLOCK_REF_KEY SHARED_DATA_REF_KEY = internal.SHARED_DATA_REF_KEY TREE_BLOCK_REF_KEY = internal.TREE_BLOCK_REF_KEY @@ -58,7 +60,9 @@ var keytype2gotype = map[Type]reflect.Type{ ORPHAN_ITEM_KEY: reflect.TypeOf(Empty{}), PERSISTENT_ITEM_KEY: reflect.TypeOf(DevStats{}), QGROUP_RELATION_KEY: reflect.TypeOf(Empty{}), + ROOT_BACKREF_KEY: reflect.TypeOf(RootRef{}), ROOT_ITEM_KEY: reflect.TypeOf(Root{}), + ROOT_REF_KEY: reflect.TypeOf(RootRef{}), SHARED_BLOCK_REF_KEY: reflect.TypeOf(Empty{}), SHARED_DATA_REF_KEY: reflect.TypeOf(SharedDataRef{}), TREE_BLOCK_REF_KEY: reflect.TypeOf(Empty{}), @@ -88,5 +92,6 @@ func (Inode) isItem() {} func (InodeRefList) isItem() {} func (Metadata) isItem() {} func (Root) isItem() {} +func (RootRef) isItem() {} func (SharedDataRef) isItem() {} func (UUIDMap) isItem() {} diff --git a/pkg/btrfs/internal/itemtype.go b/pkg/btrfs/internal/itemtype.go index e4b1302..60731aa 100644 --- a/pkg/btrfs/internal/itemtype.go +++ b/pkg/btrfs/internal/itemtype.go @@ -26,7 +26,9 @@ const ( ORPHAN_ITEM_KEY = ItemType(48) PERSISTENT_ITEM_KEY = ItemType(249) QGROUP_RELATION_KEY = ItemType(246) + ROOT_BACKREF_KEY = ItemType(144) ROOT_ITEM_KEY = ItemType(132) + ROOT_REF_KEY = ItemType(156) SHARED_BLOCK_REF_KEY = ItemType(182) SHARED_DATA_REF_KEY = ItemType(184) TREE_BLOCK_REF_KEY = ItemType(176) @@ -57,7 +59,9 @@ func (t ItemType) String() string { ORPHAN_ITEM_KEY: "ORPHAN_ITEM", PERSISTENT_ITEM_KEY: "PERSISTENT_ITEM", QGROUP_RELATION_KEY: "QGROUP_RELATION", + ROOT_BACKREF_KEY: "ROOT_BACKREF", ROOT_ITEM_KEY: "ROOT_ITEM", + ROOT_REF_KEY: "ROOT_REF", SHARED_BLOCK_REF_KEY: "SHARED_BLOCK_REF", SHARED_DATA_REF_KEY: "SHARED_DATA_REF", TREE_BLOCK_REF_KEY: "TREE_BLOCK_REF", diff --git a/pkg/btrfsmisc/print_tree.go b/pkg/btrfsmisc/print_tree.go index 76eb19c..f78f653 100644 --- a/pkg/btrfsmisc/print_tree.go +++ b/pkg/btrfsmisc/print_tree.go @@ -97,10 +97,18 @@ func PrintTree(fs *btrfs.FS, root btrfsvol.LogicalAddr) error { fmt.Printf("\t\tstime %v\n", fmtTime(body.STime)) fmt.Printf("\t\trtime %v\n", fmtTime(body.RTime)) } - //case btrfsitem.ROOT_REF_KEY: - // // TODO - //case btrfsitem.ROOT_BACKREF_KEY: - // // TODO + case btrfsitem.RootRef: + var tag string + switch item.Head.Key.ItemType { + case btrfsitem.ROOT_REF_KEY: + tag = "ref" + case btrfsitem.ROOT_BACKREF_KEY: + tag = "backref" + default: + tag = fmt.Sprintf("(error: unhandled RootRef item type: %v)", item.Head.Key.ItemType) + } + fmt.Printf("\t\troot %v key dirid %v sequence %v name %s\n", + tag, body.DirID, body.Sequence, body.Name) case btrfsitem.Extent: fmt.Printf("\t\trefs %v gen %v flags %v\n", body.Head.Refs, body.Head.Generation, body.Head.Flags) @@ -340,7 +348,7 @@ func FmtKey(key btrfs.Key) string { case btrfsitem.QGROUP_RELATION_KEY: //TODO, btrfsitem.QGROUP_INFO_KEY, btrfsitem.QGROUP_LIMIT_KEY: panic("not implemented") case btrfsitem.UUID_SUBVOL_KEY, btrfsitem.UUID_RECEIVED_SUBVOL_KEY: - fmt.Fprintf(&out, " %v)", btrfsvol.PhysicalAddr(key.Offset)) + fmt.Fprintf(&out, " %#08x)", key.Offset) case btrfsitem.ROOT_ITEM_KEY: fmt.Fprintf(&out, " %v)", btrfs.ObjID(key.Offset)) default: -- cgit v1.2.3-54-g00ecf