From 8dde45b09728fb753b072c73ff624dde832c073b Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 1 Jun 2022 10:09:47 -0600 Subject: update main --- cmd/btrfs-dump-tree/main.go | 72 +++++++++++++----------------------- pkg/btrfs/btrfsitem/item_inoderef.go | 32 +++++++++++++++- pkg/btrfs/btrfsitem/items.txt | 2 +- pkg/btrfs/btrfsitem/items_gen.go | 22 +++++------ 4 files changed, 68 insertions(+), 60 deletions(-) diff --git a/cmd/btrfs-dump-tree/main.go b/cmd/btrfs-dump-tree/main.go index 46fd741..a1c7a03 100644 --- a/cmd/btrfs-dump-tree/main.go +++ b/cmd/btrfs-dump-tree/main.go @@ -5,7 +5,6 @@ import ( "os" "strings" - "lukeshu.com/btrfs-tools/pkg/binstruct" "lukeshu.com/btrfs-tools/pkg/btrfs" "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem" "lukeshu.com/btrfs-tools/pkg/util" @@ -76,19 +75,11 @@ func Main(imgfilename string) (err error) { return err } } - if err := fs.WalkTree(superblock.Data.RootTree, func(key btrfs.Key, dat []byte) error { + if err := fs.WalkTree(superblock.Data.RootTree, func(key btrfs.Key, body btrfsitem.Item) error { if key.ItemType != btrfsitem.ROOT_ITEM_KEY { return nil } - var obj btrfsitem.Root - n, err := binstruct.Unmarshal(dat, &obj) - if err != nil { - return err - } - if n != len(dat) { - return fmt.Errorf("left over data: got %d bytes but only consumed %d", len(dat), n) - } - return printTree(fs, obj.ByteNr) + return printTree(fs, body.(btrfsitem.Root).ByteNr) }); err != nil { return err } @@ -123,22 +114,15 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) error { fmtKey(item.Head.Key), item.Head.DataOffset, item.Head.DataSize) - switch item.Head.Key.ItemType { + switch body := item.Body.(type) { //case btrfsitem.UNTYPED_KEY: // // TODO //case btrfsitem.INODE_ITEM_KEY: // // TODO(!) - case btrfsitem.INODE_REF_KEY: - dat := item.Body - for len(dat) > 0 { - var ref btrfsitem.InodeRef - n, err := binstruct.Unmarshal(dat, &ref) - if err != nil { - return err - } + case btrfsitem.InodeRefList: + for _, ref := range body { fmt.Printf("\t\tindex %d namelen %d name: %s\n", ref.Index, ref.NameLen, ref.Name) - dat = dat[n:] } //case btrfsitem.INODE_EXTREF_KEY: // // TODO @@ -146,36 +130,32 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) error { // // TODO //case btrfsitem.DIR_LOG_INDEX_KEY, btrfsitem.DIR_LOG_ITEM_KEY: // // TODO - case btrfsitem.ORPHAN_ITEM_KEY: - fmt.Printf("\t\torphan item\n") - case btrfsitem.ROOT_ITEM_KEY: - var obj btrfsitem.Root - n, err := binstruct.Unmarshal(item.Body, &obj) - if err != nil { - return err + case btrfsitem.Empty: + switch item.Head.Key.ItemType { + case btrfsitem.ORPHAN_ITEM_KEY: + fmt.Printf("\t\torphan item\n") + default: + return fmt.Errorf("unhandled empty item type: %v", item.Head.Key.ItemType) } - if n != len(item.Body) { - return fmt.Errorf("left over data: got %d bytes but only consumed %d", len(item.Body), n) - } - + case btrfsitem.Root: fmt.Printf("\t\tgeneration %d root_dirid %d bytenr %d byte_limit %d bytes_used %d\n", - obj.Generation, obj.RootDirID, obj.ByteNr, obj.ByteLimit, obj.BytesUsed) + body.Generation, body.RootDirID, body.ByteNr, body.ByteLimit, body.BytesUsed) fmt.Printf("\t\tlast_snapshot %d flags %s refs %d\n", - obj.LastSnapshot, obj.Flags, obj.Refs) + body.LastSnapshot, body.Flags, body.Refs) fmt.Printf("\t\tdrop_progress %s drop_level %d\n", - fmtKey(obj.DropProgress), obj.DropLevel) + fmtKey(body.DropProgress), body.DropLevel) fmt.Printf("\t\tlevel %d generation_v2 %d\n", - obj.Level, obj.GenerationV2) - if obj.Generation == obj.GenerationV2 { - fmt.Printf("\t\tuuid %s\n", obj.UUID) - fmt.Printf("\t\tparent_uuid %s\n", obj.ParentUUID) - fmt.Printf("\t\treceived_uuid %s\n", obj.ReceivedUUID) + body.Level, body.GenerationV2) + if body.Generation == body.GenerationV2 { + fmt.Printf("\t\tuuid %s\n", body.UUID) + fmt.Printf("\t\tparent_uuid %s\n", body.ParentUUID) + fmt.Printf("\t\treceived_uuid %s\n", body.ReceivedUUID) fmt.Printf("\t\tctransid %d otransid %d stransid %d rtransid %d\n", - obj.CTransID, obj.OTransID, obj.STransID, obj.RTransID) - fmt.Printf("\t\tctime %s\n", fmtTime(obj.CTime)) - fmt.Printf("\t\totime %s\n", fmtTime(obj.OTime)) - fmt.Printf("\t\tstime %s\n", fmtTime(obj.STime)) - fmt.Printf("\t\trtime %s\n", fmtTime(obj.RTime)) + body.CTransID, body.OTransID, body.STransID, body.RTransID) + fmt.Printf("\t\tctime %s\n", fmtTime(body.CTime)) + fmt.Printf("\t\totime %s\n", fmtTime(body.OTime)) + fmt.Printf("\t\tstime %s\n", fmtTime(body.STime)) + fmt.Printf("\t\trtime %s\n", fmtTime(body.RTime)) } //case btrfsitem.ROOT_REF_KEY: // // TODO @@ -221,7 +201,7 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) error { // // TODO //case btrfsitem.QGROUP_LIMIT_KEY: // // TODO - case btrfsitem.UUID_SUBVOL_KEY, btrfsitem.UUID_RECEIVED_SUBVOL_KEY: + case btrfsitem.UUIDMap: // TODO //case btrfsitem.STRING_ITEM_KEY: // // TODO diff --git a/pkg/btrfs/btrfsitem/item_inoderef.go b/pkg/btrfs/btrfsitem/item_inoderef.go index 05426b2..e59c4b3 100644 --- a/pkg/btrfs/btrfsitem/item_inoderef.go +++ b/pkg/btrfs/btrfsitem/item_inoderef.go @@ -4,8 +4,36 @@ import ( "lukeshu.com/btrfs-tools/pkg/binstruct" ) -type InodeRef struct { // INODE_REF=12 - Index int64 `bin:"off=0x0, siz=0x8"` +type InodeRefList []InodeRef // INODE_REF=12 + +func (o *InodeRefList) UnmarshalBinary(dat []byte) (int, error) { + n := 0 + for n < len(dat) { + var ref InodeRef + _n, err := binstruct.Unmarshal(dat, &ref) + n += _n + if err != nil { + return n, err + } + *o = append(*o, ref) + } + return n, nil +} + +func (o InodeRefList) MarshalBinary() ([]byte, error) { + var ret []byte + for _, ref := range o { + bs, err := binstruct.Marshal(ref) + ret = append(ret, bs...) + if err != nil { + return ret, err + } + } + return ret, nil +} + +type InodeRef struct { + Index int64 `bin:"off=0x0, siz=0x8"` NameLen uint16 `bin:"off=0x8, siz=0x2"` binstruct.End `bin:"off=0xa"` Name []byte `bin:"-"` diff --git a/pkg/btrfs/btrfsitem/items.txt b/pkg/btrfs/btrfsitem/items.txt index 02c1d24..f38af3f 100644 --- a/pkg/btrfs/btrfsitem/items.txt +++ b/pkg/btrfs/btrfsitem/items.txt @@ -4,7 +4,7 @@ DEV_EXTENT=204 DevExtent UNTYPED=0, Empty QGROUP_RELATION=246 Empty INODE_ITEM=1 Inode -INODE_REF=12 InodeRef +INODE_REF=12 InodeRefList ORPHAN_ITEM=48 Orphan PERSISTENT_ITEM=249 DevStats ROOT_ITEM=132 Root diff --git a/pkg/btrfs/btrfsitem/items_gen.go b/pkg/btrfs/btrfsitem/items_gen.go index 40a0b53..63a5ac1 100644 --- a/pkg/btrfs/btrfsitem/items_gen.go +++ b/pkg/btrfs/btrfsitem/items_gen.go @@ -28,7 +28,7 @@ var keytype2gotype = map[Type]reflect.Type{ UNTYPED_KEY: reflect.TypeOf(Empty{}), QGROUP_RELATION_KEY: reflect.TypeOf(Empty{}), INODE_ITEM_KEY: reflect.TypeOf(Inode{}), - INODE_REF_KEY: reflect.TypeOf(InodeRef{}), + INODE_REF_KEY: reflect.TypeOf(InodeRefList{}), ORPHAN_ITEM_KEY: reflect.TypeOf(Orphan{}), PERSISTENT_ITEM_KEY: reflect.TypeOf(DevStats{}), ROOT_ITEM_KEY: reflect.TypeOf(Root{}), @@ -36,13 +36,13 @@ var keytype2gotype = map[Type]reflect.Type{ UUID_RECEIVED_SUBVOL_KEY: reflect.TypeOf(UUIDMap{}), } -func (Chunk) isItem() {} -func (Dev) isItem() {} -func (DevExtent) isItem() {} -func (DevStats) isItem() {} -func (Empty) isItem() {} -func (Inode) isItem() {} -func (InodeRef) isItem() {} -func (Orphan) isItem() {} -func (Root) isItem() {} -func (UUIDMap) isItem() {} +func (Chunk) isItem() {} +func (Dev) isItem() {} +func (DevExtent) isItem() {} +func (DevStats) isItem() {} +func (Empty) isItem() {} +func (Inode) isItem() {} +func (InodeRefList) isItem() {} +func (Orphan) isItem() {} +func (Root) isItem() {} +func (UUIDMap) isItem() {} -- cgit v1.2.3-2-g168b