From 32840c8b2314164848c30305315eba6907f4acad Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 5 Jun 2022 09:27:38 -0600 Subject: more --- cmd/btrfs-dump-tree/main.go | 70 +++++++++++++++++++++++++++++++--- pkg/btrfs/Makefile | 2 +- pkg/btrfs/btrfsitem/item_dir.go | 38 +++++++++--------- pkg/btrfs/btrfsitem/item_extent.go | 10 ++--- pkg/btrfs/btrfsitem/item_inode.go | 24 ++++++------ pkg/btrfs/btrfsitem/item_persistent.go | 2 +- pkg/btrfs/btrfsitem/item_root.go | 2 +- pkg/btrfs/internal_objid.go | 1 + 8 files changed, 105 insertions(+), 44 deletions(-) diff --git a/cmd/btrfs-dump-tree/main.go b/cmd/btrfs-dump-tree/main.go index b87778b..6a8a7e6 100644 --- a/cmd/btrfs-dump-tree/main.go +++ b/cmd/btrfs-dump-tree/main.go @@ -80,6 +80,30 @@ func Main(imgfilename string) (err error) { if key.ItemType != btrfsitem.ROOT_ITEM_KEY { return nil } + treeName, ok := map[btrfs.ObjID]string{ + btrfs.ROOT_TREE_OBJECTID: "root", + btrfs.EXTENT_TREE_OBJECTID: "extent", + btrfs.CHUNK_TREE_OBJECTID: "chunk", + btrfs.DEV_TREE_OBJECTID: "device", + btrfs.FS_TREE_OBJECTID: "fs", + btrfs.ROOT_TREE_DIR_OBJECTID: "directory", + btrfs.CSUM_TREE_OBJECTID: "checksum", + btrfs.ORPHAN_OBJECTID: "orphan", + btrfs.TREE_LOG_OBJECTID: "log", + btrfs.TREE_LOG_FIXUP_OBJECTID: "log fixup", + btrfs.TREE_RELOC_OBJECTID: "reloc", + btrfs.DATA_RELOC_TREE_OBJECTID: "data reloc", + btrfs.EXTENT_CSUM_OBJECTID: "extent checksum", + btrfs.QUOTA_TREE_OBJECTID: "quota", + btrfs.UUID_TREE_OBJECTID: "uuid", + btrfs.FREE_SPACE_TREE_OBJECTID: "free space", + btrfs.MULTIPLE_OBJECTIDS: "multiple", + btrfs.BLOCK_GROUP_TREE_OBJECTID: "block group", + }[key.ObjectID] + if !ok { + treeName = "file" + } + fmt.Printf("%s tree %s \n", treeName, fmtKey(key)) return printTree(fs, body.(btrfsitem.Root).ByteNr) }, }); err != nil { @@ -174,10 +198,19 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) error { // // TODO //case btrfsitem.ROOT_BACKREF_KEY: // // TODO - //case btrfsitem.EXTENT_ITEM_KEY: - // // TODO - //case btrfsitem.METADATA_ITEM_KEY: - // // TODO + case btrfsitem.Extent: + fmt.Printf("\t\trefs %d gen %d flags %v\n", + body.Head.Refs, body.Head.Generation, body.Head.Flags) + if body.Head.Flags.Has(btrfsitem.EXTENT_FLAG_TREE_BLOCK) { + fmt.Printf("\t\ttree block %s level %d\n", + fmtKey(body.Info.Key), body.Info.Level) + } + printExtentInlineRefs(body.Refs) + case btrfsitem.Metadata: + fmt.Printf("\t\trefs %d gen %d flags %v\n", + body.Head.Refs, body.Head.Generation, body.Head.Flags) + fmt.Printf("\t\ttree block skinny level %d\n", item.Head.Key.Offset) + printExtentInlineRefs(body.Refs) //case btrfsitem.TREE_BLOCK_REF_KEY: // fmt.Printf("\t\ttree block backref\n") //case btrfsitem.SHARED_BLOCK_REF_KEY: @@ -250,7 +283,7 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) error { case btrfsitem.ORPHAN_ITEM_KEY: fmt.Printf("\t\torphan item\n") default: - return fmt.Errorf("unhandled empty item type: %v", item.Head.Key.ItemType) + fmt.Printf("\t\t(error) unhandled empty item type: %v\n", item.Head.Key.ItemType) } case btrfsitem.Error: fmt.Printf("\t\t(error) error item: %v\n", body.Err) @@ -300,6 +333,33 @@ func printHeaderInfo(node btrfs.Node) { fmt.Printf("chunk uuid %s\n", node.Head.ChunkTreeUUID) } +// printExtentInlineRefs mimics part of btrfs-progs kernel-shared/print-tree.c:print_extent_item() +func printExtentInlineRefs(refs []btrfsitem.ExtentInlineRef) { + for _, ref := range refs { + switch subitem := ref.Body.(type) { + case btrfsitem.Empty: + switch ref.Type { + case btrfsitem.TREE_BLOCK_REF_KEY: + fmt.Printf("\t\ttree block backref root %v\n", + btrfs.ObjID(ref.Offset)) + case btrfsitem.SHARED_BLOCK_REF_KEY: + fmt.Printf("\t\tshared block backref parent %d\n", + ref.Offset) + default: + fmt.Printf("\t\t(error) unexpected empty sub-item type: %v\n", ref.Type) + } + case btrfsitem.ExtentDataRef: + fmt.Printf("\t\textent data backref root %v objectid %d offset %d count %d\n", + subitem.Root, subitem.ObjectID, subitem.Offset, subitem.Count) + case btrfsitem.SharedDataRef: + fmt.Printf("\t\tshared data backref parent %d count %d\n", + ref.Offset, subitem.Count) + default: + fmt.Printf("\t\t(error) unexpected sub-item type: %T\n", subitem) + } + } +} + // mimics print-tree.c:btrfs_print_key() func fmtKey(key btrfs.Key) string { var out strings.Builder diff --git a/pkg/btrfs/Makefile b/pkg/btrfs/Makefile index 33d3793..9777cbe 100644 --- a/pkg/btrfs/Makefile +++ b/pkg/btrfs/Makefile @@ -57,7 +57,7 @@ internal_objid.go: internal/objid.go $(MAKEFILE_LIST) echo '"lukeshu.com/btrfs-tools/pkg/btrfs/internal"'; \ echo ')'; \ echo 'const('; \ - sed -En 's/^\s*(\S*_OBJECTID)\s*=.*/\1 = internal.\1/p' <$<; \ + sed -En 's/^\s*(\S*_OBJECTIDS?)\s*=.*/\1 = internal.\1/p' <$<; \ echo ')'; \ } | gofmt >$@ files += internal_objid.go diff --git a/pkg/btrfs/btrfsitem/item_dir.go b/pkg/btrfs/btrfsitem/item_dir.go index 2e0529e..44cfb75 100644 --- a/pkg/btrfs/btrfsitem/item_dir.go +++ b/pkg/btrfs/btrfsitem/item_dir.go @@ -73,29 +73,29 @@ func (o Dir) MarshalBinary() ([]byte, error) { type FileType uint8 const ( - BTRFS_FT_UNKNOWN = FileType(0) - BTRFS_FT_REG_FILE = FileType(1) - BTRFS_FT_DIR = FileType(2) - BTRFS_FT_CHRDEV = FileType(3) - BTRFS_FT_BLKDEV = FileType(4) - BTRFS_FT_FIFO = FileType(5) - BTRFS_FT_SOCK = FileType(6) - BTRFS_FT_SYMLINK = FileType(7) - BTRFS_FT_XATTR = FileType(8) - BTRFS_FT_MAX = FileType(9) + FT_UNKNOWN = FileType(0) + FT_REG_FILE = FileType(1) + FT_DIR = FileType(2) + FT_CHRDEV = FileType(3) + FT_BLKDEV = FileType(4) + FT_FIFO = FileType(5) + FT_SOCK = FileType(6) + FT_SYMLINK = FileType(7) + FT_XATTR = FileType(8) + FT_MAX = FileType(9) ) func (ft FileType) String() string { names := map[FileType]string{ - BTRFS_FT_UNKNOWN: "UNKNOWN", - BTRFS_FT_REG_FILE: "REG_FILE", - BTRFS_FT_DIR: "DIR", - BTRFS_FT_CHRDEV: "CHRDEV", - BTRFS_FT_BLKDEV: "BLKDEV", - BTRFS_FT_FIFO: "FIFO", - BTRFS_FT_SOCK: "SOCK", - BTRFS_FT_SYMLINK: "SYMLINK", - BTRFS_FT_XATTR: "XATTR", + FT_UNKNOWN: "UNKNOWN", + FT_REG_FILE: "REG_FILE", + FT_DIR: "DIR", + FT_CHRDEV: "CHRDEV", + FT_BLKDEV: "BLKDEV", + FT_FIFO: "FIFO", + FT_SOCK: "SOCK", + FT_SYMLINK: "SYMLINK", + FT_XATTR: "XATTR", } if name, ok := names[ft]; ok { return name diff --git a/pkg/btrfs/btrfsitem/item_extent.go b/pkg/btrfs/btrfsitem/item_extent.go index 7d3eb05..b0b208d 100644 --- a/pkg/btrfs/btrfsitem/item_extent.go +++ b/pkg/btrfs/btrfsitem/item_extent.go @@ -10,7 +10,7 @@ import ( type Extent struct { // EXTENT_ITEM=168 Head ExtentHeader - Info TreeBlockInfo // only if .Head.Flags.Has(BTRFS_EXTENT_FLAG_TREE_BLOCK) + Info TreeBlockInfo // only if .Head.Flags.Has(EXTENT_FLAG_TREE_BLOCK) Refs []ExtentInlineRef } @@ -19,7 +19,7 @@ func (o *Extent) UnmarshalBinary(dat []byte) (int, error) { if err != nil { return n, err } - if o.Head.Flags.Has(BTRFS_EXTENT_FLAG_TREE_BLOCK) { + if o.Head.Flags.Has(EXTENT_FLAG_TREE_BLOCK) { _n, err := binstruct.Unmarshal(dat[n:], &o.Info) n += _n if err != nil { @@ -44,7 +44,7 @@ func (o Extent) MarshalBinary() ([]byte, error) { if err != nil { return dat, err } - if o.Head.Flags.Has(BTRFS_EXTENT_FLAG_TREE_BLOCK) { + if o.Head.Flags.Has(EXTENT_FLAG_TREE_BLOCK) { bs, err := binstruct.Marshal(o.Info) dat = append(dat, bs...) if err != nil { @@ -77,8 +77,8 @@ type TreeBlockInfo struct { type ExtentFlags uint64 const ( - BTRFS_EXTENT_FLAG_DATA = ExtentFlags(1 << iota) - BTRFS_EXTENT_FLAG_TREE_BLOCK + EXTENT_FLAG_DATA = ExtentFlags(1 << iota) + EXTENT_FLAG_TREE_BLOCK ) var extentFlagNames = []string{ diff --git a/pkg/btrfs/btrfsitem/item_inode.go b/pkg/btrfs/btrfsitem/item_inode.go index 175b900..e7ae666 100644 --- a/pkg/btrfs/btrfsitem/item_inode.go +++ b/pkg/btrfs/btrfsitem/item_inode.go @@ -30,18 +30,18 @@ type Inode struct { // INODE_ITEM=1 type InodeFlags uint64 const ( - BTRFS_INODE_NODATASUM = InodeFlags(1 << iota) - BTRFS_INODE_NODATACOW - BTRFS_INODE_READONLY - BTRFS_INODE_NOCOMPRESS - BTRFS_INODE_PREALLOC - BTRFS_INODE_SYNC - BTRFS_INODE_IMMUTABLE - BTRFS_INODE_APPEND - BTRFS_INODE_NODUMP - BTRFS_INODE_NOATIME - BTRFS_INODE_DIRSYNC - BTRFS_INODE_COMPRESS + INODE_NODATASUM = InodeFlags(1 << iota) + INODE_NODATACOW + INODE_READONLY + INODE_NOCOMPRESS + INODE_PREALLOC + INODE_SYNC + INODE_IMMUTABLE + INODE_APPEND + INODE_NODUMP + INODE_NOATIME + INODE_DIRSYNC + INODE_COMPRESS ) var inodeFlagNames = []string{ diff --git a/pkg/btrfs/btrfsitem/item_persistent.go b/pkg/btrfs/btrfsitem/item_persistent.go index 3221800..fd69c3d 100644 --- a/pkg/btrfs/btrfsitem/item_persistent.go +++ b/pkg/btrfs/btrfsitem/item_persistent.go @@ -14,6 +14,6 @@ const ( ) type DevStats struct { // PERSISTENT_ITEM=249 - Values [DEV_STAT_VALUES_MAX]int64 `bin:"off=0, siz=40"` + Values [DEV_STAT_VALUES_MAX]int64 `bin:"off=0, siz=40"` binstruct.End `bin:"off=40"` } diff --git a/pkg/btrfs/btrfsitem/item_root.go b/pkg/btrfs/btrfsitem/item_root.go index 9dd43f8..69d2d97 100644 --- a/pkg/btrfs/btrfsitem/item_root.go +++ b/pkg/btrfs/btrfsitem/item_root.go @@ -39,7 +39,7 @@ type Root struct { // ROOT_ITEM=132 type RootFlags uint64 const ( - BTRFS_ROOT_SUBVOL_RDONLY = RootFlags(1 << iota) + ROOT_SUBVOL_RDONLY = RootFlags(1 << iota) ) var rootFlagNames = []string{ diff --git a/pkg/btrfs/internal_objid.go b/pkg/btrfs/internal_objid.go index c101eb6..12a58a2 100644 --- a/pkg/btrfs/internal_objid.go +++ b/pkg/btrfs/internal_objid.go @@ -28,6 +28,7 @@ const ( EXTENT_CSUM_OBJECTID = internal.EXTENT_CSUM_OBJECTID FREE_SPACE_OBJECTID = internal.FREE_SPACE_OBJECTID FREE_INO_OBJECTID = internal.FREE_INO_OBJECTID + MULTIPLE_OBJECTIDS = internal.MULTIPLE_OBJECTIDS FIRST_FREE_OBJECTID = internal.FIRST_FREE_OBJECTID LAST_FREE_OBJECTID = internal.LAST_FREE_OBJECTID FIRST_CHUNK_TREE_OBJECTID = internal.FIRST_CHUNK_TREE_OBJECTID -- cgit v1.2.3-2-g168b