diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-12 16:17:34 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-12 16:17:34 -0700 |
commit | c55326b0cb6994bb802cf6aac4a296acfb0e41ff (patch) | |
tree | 020cb033adb3809bcc8ffed5f56ba8d167b32dd1 /lib | |
parent | cfcc753dc8906817e15b1b7c36b4dc12462d12e4 (diff) | |
parent | acbbfafa07922b458506b91a58f3a082da453fd1 (diff) |
Merge branch 'lukeshu/enums'
Diffstat (limited to 'lib')
-rw-r--r-- | lib/btrfs/Makefile | 11 | ||||
-rw-r--r-- | lib/btrfs/btrfsitem/item_dir.go | 47 | ||||
-rw-r--r-- | lib/btrfs/btrfsitem/item_extent.go | 2 | ||||
-rw-r--r-- | lib/btrfs/btrfsitem/item_fileextent.go | 40 | ||||
-rw-r--r-- | lib/btrfs/btrfsitem/item_freespaceinfo.go | 2 | ||||
-rw-r--r-- | lib/btrfs/btrfsitem/item_inode.go | 2 | ||||
-rw-r--r-- | lib/btrfs/btrfsitem/item_root.go | 2 | ||||
-rw-r--r-- | lib/btrfs/btrfsprim/itemtype.go | 168 | ||||
-rw-r--r-- | lib/btrfs/btrfsprim/misc.go | 29 | ||||
-rw-r--r-- | lib/btrfs/btrfsprim/objid.go | 177 | ||||
-rw-r--r-- | lib/btrfs/btrfssum/csum.go | 37 | ||||
-rw-r--r-- | lib/btrfs/btrfstree/path.go | 3 | ||||
-rw-r--r-- | lib/btrfs/btrfstree/types_node.go | 6 | ||||
-rw-r--r-- | lib/btrfs/btrfstree/types_superblock.go | 2 | ||||
-rw-r--r-- | lib/btrfs/btrfsvol/blockgroupflags.go | 2 | ||||
-rw-r--r-- | lib/btrfsprogs/btrfsinspect/print_tree.go | 53 | ||||
-rw-r--r-- | lib/containers/rbtree.go | 4 | ||||
-rw-r--r-- | lib/fmtutil/bitfield.go | 2 |
18 files changed, 303 insertions, 286 deletions
diff --git a/lib/btrfs/Makefile b/lib/btrfs/Makefile index a1fe747..b98a1b7 100644 --- a/lib/btrfs/Makefile +++ b/lib/btrfs/Makefile @@ -77,16 +77,13 @@ btrfsprim/itemtype.go: btrfsitem/items.txt $(MAKEFILE_LIST) echo 'import "fmt"'; \ echo 'type ItemType uint8'; \ echo 'const ('; \ - sed -E 's,(.*)=([^:]*)(:.*)? (trivial|complex) (.*),\1_KEY=ItemType(\2),' $< | uniq; \ + sed -E 's,(.*)=([^:]*)(:.*)? (trivial|complex) (.*),\1_KEY ItemType=\2,' $< | uniq; \ echo ')'; \ echo 'func (t ItemType) String() string {'; \ - echo ' names := map[ItemType]string{'; \ - sed -E 's@(.*)=(.*) (trivial|complex) (.*)@\1_KEY: "\1",@' $< | sed 's/"UUID_/&KEY_/'; \ + echo ' switch t {'; \ + sed -E 's@(.*)=(.*) (trivial|complex) (.*)@case \1_KEY: return "\1"@' $< | sed 's/"UUID_/&KEY_/'; \ + echo ' default: return fmt.Sprintf("%d", t)'; \ echo ' }'; \ - echo ' if name, ok := names[t]; ok {'; \ - echo ' return name'; \ - echo ' }'; \ - echo ' return fmt.Sprintf("%d", t)'; \ echo '}'; \ } | gofmt >$@ files += btrfsprim/itemtype.go diff --git a/lib/btrfs/btrfsitem/item_dir.go b/lib/btrfs/btrfsitem/item_dir.go index 0049072..c1b3c09 100644 --- a/lib/btrfs/btrfsitem/item_dir.go +++ b/lib/btrfs/btrfsitem/item_dir.go @@ -84,33 +84,34 @@ func (o DirEntry) MarshalBinary() ([]byte, error) { type FileType uint8 const ( - 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_UNKNOWN FileType = iota + FT_REG_FILE + FT_DIR + FT_CHRDEV + FT_BLKDEV + FT_FIFO + FT_SOCK + FT_SYMLINK + FT_XATTR - FT_MAX = FileType(9) + FT_MAX ) +var fileTypeNames = []string{ + "UNKNOWN", + "FILE", // NB: Just "FILE", despite corresponding to "REG_FILE" + "DIR", + "CHRDEV", + "BLKDEV", + "FIFO", + "SOCK", + "SYMLINK", + "XATTR", +} + func (ft FileType) String() string { - names := map[FileType]string{ - FT_UNKNOWN: "UNKNOWN", - FT_REG_FILE: "FILE", // XXX - 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 + if ft < FT_MAX { + return fileTypeNames[ft] } return fmt.Sprintf("DIR_ITEM.%d", uint8(ft)) } diff --git a/lib/btrfs/btrfsitem/item_extent.go b/lib/btrfs/btrfsitem/item_extent.go index 3789cfe..871ed90 100644 --- a/lib/btrfs/btrfsitem/item_extent.go +++ b/lib/btrfs/btrfsitem/item_extent.go @@ -111,7 +111,7 @@ type TreeBlockInfo struct { type ExtentFlags uint64 const ( - EXTENT_FLAG_DATA = ExtentFlags(1 << iota) + EXTENT_FLAG_DATA ExtentFlags = 1 << iota EXTENT_FLAG_TREE_BLOCK ) diff --git a/lib/btrfs/btrfsitem/item_fileextent.go b/lib/btrfs/btrfsitem/item_fileextent.go index 30a14ef..6b08897 100644 --- a/lib/btrfs/btrfsitem/item_fileextent.go +++ b/lib/btrfs/btrfsitem/item_fileextent.go @@ -101,11 +101,17 @@ func (o FileExtent) MarshalBinary() ([]byte, error) { type FileExtentType uint8 const ( - FILE_EXTENT_INLINE = FileExtentType(iota) + FILE_EXTENT_INLINE FileExtentType = iota FILE_EXTENT_REG FILE_EXTENT_PREALLOC ) +var fileExtentTypeNames = []string{ + "inline", + "regular", + "prealloc", +} + func (o FileExtent) Size() (int64, error) { switch o.Type { case FILE_EXTENT_INLINE: @@ -118,14 +124,9 @@ func (o FileExtent) Size() (int64, error) { } func (fet FileExtentType) String() string { - names := map[FileExtentType]string{ - FILE_EXTENT_INLINE: "inline", - FILE_EXTENT_REG: "regular", - FILE_EXTENT_PREALLOC: "prealloc", - } - name, ok := names[fet] - if !ok { - name = "unknown" + name := "unknown" + if int(fet) < len(fileExtentTypeNames) { + name = fileExtentTypeNames[fet] } return fmt.Sprintf("%d (%s)", fet, name) } @@ -133,22 +134,23 @@ func (fet FileExtentType) String() string { type CompressionType uint8 const ( - COMPRESS_NONE = CompressionType(iota) + COMPRESS_NONE CompressionType = iota COMPRESS_ZLIB COMPRESS_LZO COMPRESS_ZSTD ) +var compressionTypeNames = []string{ + "none", + "zlib", + "lzo", + "zstd", +} + func (ct CompressionType) String() string { - names := map[CompressionType]string{ - COMPRESS_NONE: "none", - COMPRESS_ZLIB: "zlib", - COMPRESS_LZO: "lzo", - COMPRESS_ZSTD: "zstd", - } - name, ok := names[ct] - if !ok { - name = "unknown" + name := "unknown" + if int(ct) < len(compressionTypeNames) { + name = compressionTypeNames[ct] } return fmt.Sprintf("%d (%s)", ct, name) } diff --git a/lib/btrfs/btrfsitem/item_freespaceinfo.go b/lib/btrfs/btrfsitem/item_freespaceinfo.go index 0699367..9b886af 100644 --- a/lib/btrfs/btrfsitem/item_freespaceinfo.go +++ b/lib/btrfs/btrfsitem/item_freespaceinfo.go @@ -20,7 +20,7 @@ type FreeSpaceInfo struct { // trivial FREE_SPACE_INFO=198 type FreeSpaceFlags uint32 const ( - FREE_SPACE_USING_BITMAPS = FreeSpaceFlags(1 << iota) + FREE_SPACE_USING_BITMAPS FreeSpaceFlags = 1 << iota ) var freeSpaceFlagNames = []string{ diff --git a/lib/btrfs/btrfsitem/item_inode.go b/lib/btrfs/btrfsitem/item_inode.go index 69f8445..6951c76 100644 --- a/lib/btrfs/btrfsitem/item_inode.go +++ b/lib/btrfs/btrfsitem/item_inode.go @@ -36,7 +36,7 @@ type Inode struct { // trivial INODE_ITEM=1 type InodeFlags uint64 const ( - INODE_NODATASUM = InodeFlags(1 << iota) + INODE_NODATASUM InodeFlags = 1 << iota INODE_NODATACOW INODE_READONLY INODE_NOCOMPRESS diff --git a/lib/btrfs/btrfsitem/item_root.go b/lib/btrfs/btrfsitem/item_root.go index c0db900..d39bd70 100644 --- a/lib/btrfs/btrfsitem/item_root.go +++ b/lib/btrfs/btrfsitem/item_root.go @@ -48,7 +48,7 @@ type Root struct { // trivial ROOT_ITEM=132 type RootFlags uint64 const ( - ROOT_SUBVOL_RDONLY = RootFlags(1 << iota) + ROOT_SUBVOL_RDONLY RootFlags = 1 << iota ) var rootFlagNames = []string{ diff --git a/lib/btrfs/btrfsprim/itemtype.go b/lib/btrfs/btrfsprim/itemtype.go index 0b6baee..f33179a 100644 --- a/lib/btrfs/btrfsprim/itemtype.go +++ b/lib/btrfs/btrfsprim/itemtype.go @@ -7,77 +7,107 @@ import "fmt" type ItemType uint8 const ( - BLOCK_GROUP_ITEM_KEY = ItemType(192) - CHUNK_ITEM_KEY = ItemType(228) - DEV_EXTENT_KEY = ItemType(204) - DEV_ITEM_KEY = ItemType(216) - DIR_INDEX_KEY = ItemType(96) - DIR_ITEM_KEY = ItemType(84) - EXTENT_CSUM_KEY = ItemType(128) - EXTENT_DATA_KEY = ItemType(108) - EXTENT_DATA_REF_KEY = ItemType(178) - EXTENT_ITEM_KEY = ItemType(168) - FREE_SPACE_BITMAP_KEY = ItemType(200) - FREE_SPACE_EXTENT_KEY = ItemType(199) - FREE_SPACE_INFO_KEY = ItemType(198) - INODE_ITEM_KEY = ItemType(1) - INODE_REF_KEY = ItemType(12) - METADATA_ITEM_KEY = ItemType(169) - ORPHAN_ITEM_KEY = ItemType(48) - PERSISTENT_ITEM_KEY = ItemType(249) - QGROUP_INFO_KEY = ItemType(242) - QGROUP_LIMIT_KEY = ItemType(244) - QGROUP_RELATION_KEY = ItemType(246) - QGROUP_STATUS_KEY = ItemType(240) - 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) - UNTYPED_KEY = ItemType(0) - UUID_RECEIVED_SUBVOL_KEY = ItemType(252) - UUID_SUBVOL_KEY = ItemType(251) - XATTR_ITEM_KEY = ItemType(24) + BLOCK_GROUP_ITEM_KEY ItemType = 192 + CHUNK_ITEM_KEY ItemType = 228 + DEV_EXTENT_KEY ItemType = 204 + DEV_ITEM_KEY ItemType = 216 + DIR_INDEX_KEY ItemType = 96 + DIR_ITEM_KEY ItemType = 84 + EXTENT_CSUM_KEY ItemType = 128 + EXTENT_DATA_KEY ItemType = 108 + EXTENT_DATA_REF_KEY ItemType = 178 + EXTENT_ITEM_KEY ItemType = 168 + FREE_SPACE_BITMAP_KEY ItemType = 200 + FREE_SPACE_EXTENT_KEY ItemType = 199 + FREE_SPACE_INFO_KEY ItemType = 198 + INODE_ITEM_KEY ItemType = 1 + INODE_REF_KEY ItemType = 12 + METADATA_ITEM_KEY ItemType = 169 + ORPHAN_ITEM_KEY ItemType = 48 + PERSISTENT_ITEM_KEY ItemType = 249 + QGROUP_INFO_KEY ItemType = 242 + QGROUP_LIMIT_KEY ItemType = 244 + QGROUP_RELATION_KEY ItemType = 246 + QGROUP_STATUS_KEY ItemType = 240 + 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 + UNTYPED_KEY ItemType = 0 + UUID_RECEIVED_SUBVOL_KEY ItemType = 252 + UUID_SUBVOL_KEY ItemType = 251 + XATTR_ITEM_KEY ItemType = 24 ) func (t ItemType) String() string { - names := map[ItemType]string{ - BLOCK_GROUP_ITEM_KEY: "BLOCK_GROUP_ITEM", - CHUNK_ITEM_KEY: "CHUNK_ITEM", - DEV_EXTENT_KEY: "DEV_EXTENT", - DEV_ITEM_KEY: "DEV_ITEM", - DIR_INDEX_KEY: "DIR_INDEX", - DIR_ITEM_KEY: "DIR_ITEM", - EXTENT_CSUM_KEY: "EXTENT_CSUM", - EXTENT_DATA_KEY: "EXTENT_DATA", - EXTENT_DATA_REF_KEY: "EXTENT_DATA_REF", - EXTENT_ITEM_KEY: "EXTENT_ITEM", - FREE_SPACE_BITMAP_KEY: "FREE_SPACE_BITMAP", - FREE_SPACE_EXTENT_KEY: "FREE_SPACE_EXTENT", - FREE_SPACE_INFO_KEY: "FREE_SPACE_INFO", - INODE_ITEM_KEY: "INODE_ITEM", - INODE_REF_KEY: "INODE_REF", - METADATA_ITEM_KEY: "METADATA_ITEM", - ORPHAN_ITEM_KEY: "ORPHAN_ITEM", - PERSISTENT_ITEM_KEY: "PERSISTENT_ITEM", - QGROUP_INFO_KEY: "QGROUP_INFO", - QGROUP_LIMIT_KEY: "QGROUP_LIMIT", - QGROUP_RELATION_KEY: "QGROUP_RELATION", - QGROUP_STATUS_KEY: "QGROUP_STATUS", - 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", - UNTYPED_KEY: "UNTYPED", - UUID_RECEIVED_SUBVOL_KEY: "UUID_KEY_RECEIVED_SUBVOL", - UUID_SUBVOL_KEY: "UUID_KEY_SUBVOL", - XATTR_ITEM_KEY: "XATTR_ITEM", + switch t { + case BLOCK_GROUP_ITEM_KEY: + return "BLOCK_GROUP_ITEM" + case CHUNK_ITEM_KEY: + return "CHUNK_ITEM" + case DEV_EXTENT_KEY: + return "DEV_EXTENT" + case DEV_ITEM_KEY: + return "DEV_ITEM" + case DIR_INDEX_KEY: + return "DIR_INDEX" + case DIR_ITEM_KEY: + return "DIR_ITEM" + case EXTENT_CSUM_KEY: + return "EXTENT_CSUM" + case EXTENT_DATA_KEY: + return "EXTENT_DATA" + case EXTENT_DATA_REF_KEY: + return "EXTENT_DATA_REF" + case EXTENT_ITEM_KEY: + return "EXTENT_ITEM" + case FREE_SPACE_BITMAP_KEY: + return "FREE_SPACE_BITMAP" + case FREE_SPACE_EXTENT_KEY: + return "FREE_SPACE_EXTENT" + case FREE_SPACE_INFO_KEY: + return "FREE_SPACE_INFO" + case INODE_ITEM_KEY: + return "INODE_ITEM" + case INODE_REF_KEY: + return "INODE_REF" + case METADATA_ITEM_KEY: + return "METADATA_ITEM" + case ORPHAN_ITEM_KEY: + return "ORPHAN_ITEM" + case PERSISTENT_ITEM_KEY: + return "PERSISTENT_ITEM" + case QGROUP_INFO_KEY: + return "QGROUP_INFO" + case QGROUP_LIMIT_KEY: + return "QGROUP_LIMIT" + case QGROUP_RELATION_KEY: + return "QGROUP_RELATION" + case QGROUP_STATUS_KEY: + return "QGROUP_STATUS" + case ROOT_BACKREF_KEY: + return "ROOT_BACKREF" + case ROOT_ITEM_KEY: + return "ROOT_ITEM" + case ROOT_REF_KEY: + return "ROOT_REF" + case SHARED_BLOCK_REF_KEY: + return "SHARED_BLOCK_REF" + case SHARED_DATA_REF_KEY: + return "SHARED_DATA_REF" + case TREE_BLOCK_REF_KEY: + return "TREE_BLOCK_REF" + case UNTYPED_KEY: + return "UNTYPED" + case UUID_RECEIVED_SUBVOL_KEY: + return "UUID_KEY_RECEIVED_SUBVOL" + case UUID_SUBVOL_KEY: + return "UUID_KEY_SUBVOL" + case XATTR_ITEM_KEY: + return "XATTR_ITEM" + default: + return fmt.Sprintf("%d", t) } - if name, ok := names[t]; ok { - return name - } - return fmt.Sprintf("%d", t) } diff --git a/lib/btrfs/btrfsprim/misc.go b/lib/btrfs/btrfsprim/misc.go index da661f6..ca2e313 100644 --- a/lib/btrfs/btrfsprim/misc.go +++ b/lib/btrfs/btrfsprim/misc.go @@ -22,8 +22,35 @@ type Key struct { binstruct.End `bin:"off=0x11"` } +// mimics print-tree.c:btrfs_print_key() +func (key Key) Format(tree ObjID) string { + switch tree { + case UUID_TREE_OBJECTID: + return fmt.Sprintf("(%v %v %#08x)", + key.ObjectID.Format(tree), + key.ItemType, + key.Offset) + case ROOT_TREE_OBJECTID, QUOTA_TREE_OBJECTID: + return fmt.Sprintf("(%v %v %v)", + key.ObjectID.Format(tree), + key.ItemType, + ObjID(key.Offset).Format(tree)) + default: + if key.Offset == math.MaxUint64 { + return fmt.Sprintf("(%v %v -1)", + key.ObjectID.Format(tree), + key.ItemType) + } else { + return fmt.Sprintf("(%v %v %v)", + key.ObjectID.Format(tree), + key.ItemType, + key.Offset) + } + } +} + func (key Key) String() string { - return fmt.Sprintf("{%v %v %v}", key.ObjectID, key.ItemType, key.Offset) + return key.Format(0) } var MaxKey = Key{ diff --git a/lib/btrfs/btrfsprim/objid.go b/lib/btrfs/btrfsprim/objid.go index 8ad290b..1aea030 100644 --- a/lib/btrfs/btrfsprim/objid.go +++ b/lib/btrfs/btrfsprim/objid.go @@ -14,130 +14,111 @@ const maxUint64pp = 0x1_00000000_00000000 const ( // The IDs of the various trees - ROOT_TREE_OBJECTID = ObjID(1) // holds pointers to all of the tree roots - EXTENT_TREE_OBJECTID = ObjID(2) // stores information about which extents are in use, and reference counts - CHUNK_TREE_OBJECTID = ObjID(3) // chunk tree stores translations from logical -> physical block numbering - DEV_TREE_OBJECTID = ObjID(4) // stores info about which areas of a given device are in use; one per device - FS_TREE_OBJECTID = ObjID(5) // one per subvolume, storing files and directories - ROOT_TREE_DIR_OBJECTID = ObjID(6) // directory objectid inside the root tree - CSUM_TREE_OBJECTID = ObjID(7) // holds checksums of all the data extents - QUOTA_TREE_OBJECTID = ObjID(8) - UUID_TREE_OBJECTID = ObjID(9) // for storing items that use the UUID_*_KEY - FREE_SPACE_TREE_OBJECTID = ObjID(10) // tracks free space in block groups. - BLOCK_GROUP_TREE_OBJECTID = ObjID(11) // hold the block group items. + ROOT_TREE_OBJECTID ObjID = 1 // holds pointers to all of the tree roots + EXTENT_TREE_OBJECTID ObjID = 2 // stores information about which extents are in use, and reference counts + CHUNK_TREE_OBJECTID ObjID = 3 // chunk tree stores translations from logical -> physical block numbering + DEV_TREE_OBJECTID ObjID = 4 // stores info about which areas of a given device are in use; one per device + FS_TREE_OBJECTID ObjID = 5 // one per subvolume, storing files and directories + ROOT_TREE_DIR_OBJECTID ObjID = 6 // directory objectid inside the root tree + CSUM_TREE_OBJECTID ObjID = 7 // holds checksums of all the data extents + QUOTA_TREE_OBJECTID ObjID = 8 + UUID_TREE_OBJECTID ObjID = 9 // for storing items that use the UUID_*_KEY + FREE_SPACE_TREE_OBJECTID ObjID = 10 // tracks free space in block groups. + BLOCK_GROUP_TREE_OBJECTID ObjID = 11 // hold the block group items. // Objects in the DEV_TREE - DEV_STATS_OBJECTID = ObjID(0) // device stats in the device tree + DEV_STATS_OBJECTID ObjID = 0 // device stats in the device tree // ??? - BALANCE_OBJECTID = ObjID(maxUint64pp - 4) // for storing balance parameters in the root tree - ORPHAN_OBJECTID = ObjID(maxUint64pp - 5) // orphan objectid for tracking unlinked/truncated files - TREE_LOG_OBJECTID = ObjID(maxUint64pp - 6) // does write ahead logging to speed up fsyncs - TREE_LOG_FIXUP_OBJECTID = ObjID(maxUint64pp - 7) - TREE_RELOC_OBJECTID = ObjID(maxUint64pp - 8) // space balancing - DATA_RELOC_TREE_OBJECTID = ObjID(maxUint64pp - 9) - EXTENT_CSUM_OBJECTID = ObjID(maxUint64pp - 10) // extent checksums all have this objectid - FREE_SPACE_OBJECTID = ObjID(maxUint64pp - 11) // For storing free space cache - FREE_INO_OBJECTID = ObjID(maxUint64pp - 12) // stores the inode number for the free-ino cache - - MULTIPLE_OBJECTIDS = ObjID(maxUint64pp - 255) // dummy objectid represents multiple objectids + BALANCE_OBJECTID ObjID = maxUint64pp - 4 // for storing balance parameters in the root tree + ORPHAN_OBJECTID ObjID = maxUint64pp - 5 // orphan objectid for tracking unlinked/truncated files + TREE_LOG_OBJECTID ObjID = maxUint64pp - 6 // does write ahead logging to speed up fsyncs + TREE_LOG_FIXUP_OBJECTID ObjID = maxUint64pp - 7 + TREE_RELOC_OBJECTID ObjID = maxUint64pp - 8 // space balancing + DATA_RELOC_TREE_OBJECTID ObjID = maxUint64pp - 9 + EXTENT_CSUM_OBJECTID ObjID = maxUint64pp - 10 // extent checksums all have this objectid + FREE_SPACE_OBJECTID ObjID = maxUint64pp - 11 // For storing free space cache + FREE_INO_OBJECTID ObjID = maxUint64pp - 12 // stores the inode number for the free-ino cache + + MULTIPLE_OBJECTIDS ObjID = maxUint64pp - 255 // dummy objectid represents multiple objectids // All files have objectids in this range. - FIRST_FREE_OBJECTID = ObjID(256) - LAST_FREE_OBJECTID = ObjID(maxUint64pp - 256) - - FIRST_CHUNK_TREE_OBJECTID = ObjID(256) + FIRST_FREE_OBJECTID ObjID = 256 + LAST_FREE_OBJECTID ObjID = maxUint64pp - 256 // Objects in the CHUNK_TREE - DEV_ITEMS_OBJECTID = ObjID(1) + DEV_ITEMS_OBJECTID ObjID = 1 + FIRST_CHUNK_TREE_OBJECTID ObjID = 256 // ??? - EMPTY_SUBVOL_DIR_OBJECTID = ObjID(2) + EMPTY_SUBVOL_DIR_OBJECTID ObjID = 2 ) -func (id ObjID) Format(typ ItemType) string { - switch typ { - case PERSISTENT_ITEM_KEY: - names := map[ObjID]string{ - DEV_STATS_OBJECTID: "DEV_STATS", - } - if name, ok := names[id]; ok { +var ( + objidCommonNames = map[ObjID]string{ + BALANCE_OBJECTID: "BALANCE", + ORPHAN_OBJECTID: "ORPHAN", + TREE_LOG_OBJECTID: "TREE_LOG", + TREE_LOG_FIXUP_OBJECTID: "TREE_LOG_FIXUP", + TREE_RELOC_OBJECTID: "TREE_RELOC", + DATA_RELOC_TREE_OBJECTID: "DATA_RELOC_TREE", + EXTENT_CSUM_OBJECTID: "EXTENT_CSUM", + FREE_SPACE_OBJECTID: "FREE_SPACE", + FREE_INO_OBJECTID: "FREE_INO", + MULTIPLE_OBJECTIDS: "MULTIPLE", + } + objidDevTreeNames = map[ObjID]string{ + DEV_STATS_OBJECTID: "DEV_STATS", + } + objidChunkTreeNames = map[ObjID]string{ + DEV_ITEMS_OBJECTID: "DEV_ITEMS", + FIRST_CHUNK_TREE_OBJECTID: "FIRST_CHUNK_TREE", + } + objidRootTreeNames = map[ObjID]string{ + ROOT_TREE_OBJECTID: "ROOT_TREE", + EXTENT_TREE_OBJECTID: "EXTENT_TREE", + CHUNK_TREE_OBJECTID: "CHUNK_TREE", + DEV_TREE_OBJECTID: "DEV_TREE", + FS_TREE_OBJECTID: "FS_TREE", + ROOT_TREE_DIR_OBJECTID: "ROOT_TREE_DIR", + CSUM_TREE_OBJECTID: "CSUM_TREE", + QUOTA_TREE_OBJECTID: "QUOTA_TREE", + UUID_TREE_OBJECTID: "UUID_TREE", + FREE_SPACE_TREE_OBJECTID: "FREE_SPACE_TREE", + BLOCK_GROUP_TREE_OBJECTID: "BLOCK_GROUP_TREE", + } +) + +func (id ObjID) Format(tree ObjID) string { + switch tree { + case DEV_TREE_OBJECTID: + if name, ok := objidDevTreeNames[id]; ok { return name } return fmt.Sprintf("%d", int64(id)) - case DEV_EXTENT_KEY: - return fmt.Sprintf("%d", int64(id)) - case QGROUP_RELATION_KEY: + case QUOTA_TREE_OBJECTID: + if id == 0 { + return "0" + } //nolint:gomnd // The left 48 bits are the "qgroup level", and the right 16 bits are the subvolume ID. return fmt.Sprintf("%d/%d", uint64(id)>>48, uint64(id)&((1<<48)-1)) - case UUID_SUBVOL_KEY, UUID_RECEIVED_SUBVOL_KEY: + case UUID_TREE_OBJECTID: return fmt.Sprintf("%#016x", uint64(id)) - case DEV_ITEM_KEY: - names := map[ObjID]string{ - BALANCE_OBJECTID: "BALANCE", - ORPHAN_OBJECTID: "ORPHAN", - TREE_LOG_OBJECTID: "TREE_LOG", - TREE_LOG_FIXUP_OBJECTID: "TREE_LOG_FIXUP", - TREE_RELOC_OBJECTID: "TREE_RELOC", - DATA_RELOC_TREE_OBJECTID: "DATA_RELOC_TREE", - EXTENT_CSUM_OBJECTID: "EXTENT_CSUM", - FREE_SPACE_OBJECTID: "FREE_SPACE", - FREE_INO_OBJECTID: "FREE_INO", - MULTIPLE_OBJECTIDS: "MULTIPLE", - - DEV_ITEMS_OBJECTID: "DEV_ITEMS", - } - if name, ok := names[id]; ok { + case CHUNK_TREE_OBJECTID: + if name, ok := objidCommonNames[id]; ok { return name } - return fmt.Sprintf("%d", int64(id)) - case CHUNK_ITEM_KEY: - names := map[ObjID]string{ - BALANCE_OBJECTID: "BALANCE", - ORPHAN_OBJECTID: "ORPHAN", - TREE_LOG_OBJECTID: "TREE_LOG", - TREE_LOG_FIXUP_OBJECTID: "TREE_LOG_FIXUP", - TREE_RELOC_OBJECTID: "TREE_RELOC", - DATA_RELOC_TREE_OBJECTID: "DATA_RELOC_TREE", - EXTENT_CSUM_OBJECTID: "EXTENT_CSUM", - FREE_SPACE_OBJECTID: "FREE_SPACE", - FREE_INO_OBJECTID: "FREE_INO", - MULTIPLE_OBJECTIDS: "MULTIPLE", - - FIRST_CHUNK_TREE_OBJECTID: "FIRST_CHUNK_TREE", - } - if name, ok := names[id]; ok { + if name, ok := objidChunkTreeNames[id]; ok { return name } return fmt.Sprintf("%d", int64(id)) default: - names := map[ObjID]string{ - BALANCE_OBJECTID: "BALANCE", - ORPHAN_OBJECTID: "ORPHAN", - TREE_LOG_OBJECTID: "TREE_LOG", - TREE_LOG_FIXUP_OBJECTID: "TREE_LOG_FIXUP", - TREE_RELOC_OBJECTID: "TREE_RELOC", - DATA_RELOC_TREE_OBJECTID: "DATA_RELOC_TREE", - EXTENT_CSUM_OBJECTID: "EXTENT_CSUM", - FREE_SPACE_OBJECTID: "FREE_SPACE", - FREE_INO_OBJECTID: "FREE_INO", - MULTIPLE_OBJECTIDS: "MULTIPLE", - - ROOT_TREE_OBJECTID: "ROOT_TREE", - EXTENT_TREE_OBJECTID: "EXTENT_TREE", - CHUNK_TREE_OBJECTID: "CHUNK_TREE", - DEV_TREE_OBJECTID: "DEV_TREE", - FS_TREE_OBJECTID: "FS_TREE", - ROOT_TREE_DIR_OBJECTID: "ROOT_TREE_DIR", - CSUM_TREE_OBJECTID: "CSUM_TREE", - QUOTA_TREE_OBJECTID: "QUOTA_TREE", - UUID_TREE_OBJECTID: "UUID_TREE", - FREE_SPACE_TREE_OBJECTID: "FREE_SPACE_TREE", - BLOCK_GROUP_TREE_OBJECTID: "BLOCK_GROUP_TREE", + if name, ok := objidCommonNames[id]; ok { + return name } - if name, ok := names[id]; ok { + if name, ok := objidRootTreeNames[id]; ok { return name } return fmt.Sprintf("%d", int64(id)) @@ -145,5 +126,5 @@ func (id ObjID) Format(typ ItemType) string { } func (id ObjID) String() string { - return id.Format(UNTYPED_KEY) + return id.Format(0) } diff --git a/lib/btrfs/btrfssum/csum.go b/lib/btrfs/btrfssum/csum.go index f436e2c..157371e 100644 --- a/lib/btrfs/btrfssum/csum.go +++ b/lib/btrfs/btrfssum/csum.go @@ -52,35 +52,36 @@ func (csum CSum) Format(f fmt.State, verb rune) { type CSumType uint16 const ( - TYPE_CRC32 = CSumType(iota) + TYPE_CRC32 CSumType = iota TYPE_XXHASH TYPE_SHA256 TYPE_BLAKE2 ) +var csumTypeNames = []string{ + "crc32c", + "xxhash64", + "sha256", + "blake2", +} + +var csumTypeSizes = []int{ + 4, + 8, + 32, + 32, +} + func (typ CSumType) String() string { - names := map[CSumType]string{ - TYPE_CRC32: "crc32c", - TYPE_XXHASH: "xxhash64", - TYPE_SHA256: "sha256", - TYPE_BLAKE2: "blake2", - } - if name, ok := names[typ]; ok { - return name + if int(typ) < len(csumTypeNames) { + return csumTypeNames[typ] } return fmt.Sprintf("%d", typ) } func (typ CSumType) Size() int { - //nolint:gomnd // This is where we define the magic numbers. - sizes := map[CSumType]int{ - TYPE_CRC32: 4, - TYPE_XXHASH: 8, - TYPE_SHA256: 32, - TYPE_BLAKE2: 32, - } - if size, ok := sizes[typ]; ok { - return size + if int(typ) < len(csumTypeSizes) { + return csumTypeSizes[typ] } return len(CSum{}) } diff --git a/lib/btrfs/btrfstree/path.go b/lib/btrfs/btrfstree/path.go index d9bf216..dd2cb74 100644 --- a/lib/btrfs/btrfstree/path.go +++ b/lib/btrfs/btrfstree/path.go @@ -9,7 +9,6 @@ import ( "io" "strings" - "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsprim" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" ) @@ -104,7 +103,7 @@ func (path TreePath) String() string { return "(empty-path)" } else { var ret strings.Builder - fmt.Fprintf(&ret, "%s->", path[0].FromTree.Format(btrfsitem.ROOT_ITEM_KEY)) + fmt.Fprintf(&ret, "%s->", path[0].FromTree.Format(btrfsprim.ROOT_TREE_OBJECTID)) if len(path) == 1 && path[0] == (TreePathElem{FromTree: path[0].FromTree, FromItemIdx: -1}) { ret.WriteString("(empty-path)") } else { diff --git a/lib/btrfs/btrfstree/types_node.go b/lib/btrfs/btrfstree/types_node.go index fd4c939..0a89e05 100644 --- a/lib/btrfs/btrfstree/types_node.go +++ b/lib/btrfs/btrfstree/types_node.go @@ -58,7 +58,7 @@ var ( ) const ( - NodeWritten = NodeFlags(1 << iota) + NodeWritten NodeFlags = 1 << iota NodeReloc ) @@ -73,8 +73,8 @@ func (f NodeFlags) String() string { return fmtutil.BitfieldString(f, no type BackrefRev uint8 const ( - OldBackrefRev = BackrefRev(iota) - MixedBackrefRev = BackrefRev(iota) + OldBackrefRev BackrefRev = iota + MixedBackrefRev ) // Node: main ////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/btrfs/btrfstree/types_superblock.go b/lib/btrfs/btrfstree/types_superblock.go index 140d4a1..a9b1633 100644 --- a/lib/btrfs/btrfstree/types_superblock.go +++ b/lib/btrfs/btrfstree/types_superblock.go @@ -199,7 +199,7 @@ type RootBackup struct { type IncompatFlags uint64 const ( - FeatureIncompatMixedBackref = IncompatFlags(1 << iota) + FeatureIncompatMixedBackref IncompatFlags = 1 << iota FeatureIncompatDefaultSubvol FeatureIncompatMixedGroups FeatureIncompatCompressLZO diff --git a/lib/btrfs/btrfsvol/blockgroupflags.go b/lib/btrfs/btrfsvol/blockgroupflags.go index 0125664..37442de 100644 --- a/lib/btrfs/btrfsvol/blockgroupflags.go +++ b/lib/btrfs/btrfsvol/blockgroupflags.go @@ -11,7 +11,7 @@ import ( type BlockGroupFlags uint64 const ( - BLOCK_GROUP_DATA = BlockGroupFlags(1 << iota) + BLOCK_GROUP_DATA BlockGroupFlags = 1 << iota BLOCK_GROUP_SYSTEM BLOCK_GROUP_METADATA BLOCK_GROUP_RAID0 diff --git a/lib/btrfsprogs/btrfsinspect/print_tree.go b/lib/btrfsprogs/btrfsinspect/print_tree.go index 8acf9cc..240c72f 100644 --- a/lib/btrfsprogs/btrfsinspect/print_tree.go +++ b/lib/btrfsprogs/btrfsinspect/print_tree.go @@ -7,8 +7,6 @@ package btrfsinspect import ( "context" "io" - "math" - "strings" "github.com/datawire/dlib/dlog" @@ -81,7 +79,7 @@ func DumpTrees(ctx context.Context, out io.Writer, fs *btrfs.FS) { if !ok { treeName = "file" } - textui.Fprintf(out, "%v tree %v \n", treeName, fmtKey(item.Key)) + textui.Fprintf(out, "%v tree key %v \n", treeName, item.Key.Format(btrfsprim.ROOT_TREE_OBJECTID)) printTree(ctx, out, fs, item.Key.ObjectID) return nil }, @@ -105,26 +103,28 @@ func printTree(ctx context.Context, out io.Writer, fs *btrfs.FS, treeID btrfspri itemOffset = nodeRef.Data.Size - uint32(nodeHeaderSize) return nil }, - PreKeyPointer: func(_ btrfstree.TreePath, item btrfstree.KeyPointer) error { - textui.Fprintf(out, "\t%v block %v gen %v\n", - fmtKey(item.Key), + PreKeyPointer: func(path btrfstree.TreePath, item btrfstree.KeyPointer) error { + treeID := path[0].FromTree + textui.Fprintf(out, "\tkey %v block %v gen %v\n", + item.Key.Format(treeID), item.BlockPtr, item.Generation) return nil }, Item: func(path btrfstree.TreePath, item btrfstree.Item) error { + treeID := path[0].FromTree i := path.Node(-1).FromItemIdx bs, _ := binstruct.Marshal(item.Body) itemSize := uint32(len(bs)) itemOffset -= itemSize - textui.Fprintf(out, "\titem %v %v itemoff %v itemsize %v\n", + textui.Fprintf(out, "\titem %v key %v itemoff %v itemsize %v\n", i, - fmtKey(item.Key), + item.Key.Format(treeID), itemOffset, itemSize) switch body := item.Body.(type) { case *btrfsitem.FreeSpaceHeader: - textui.Fprintf(out, "\t\tlocation %v\n", fmtKey(body.Location)) + textui.Fprintf(out, "\t\tlocation key %v\n", body.Location.Format(treeID)) textui.Fprintf(out, "\t\tcache generation %v entries %v bitmaps %v\n", body.Generation, body.NumEntries, body.NumBitmaps) case *btrfsitem.Inode: @@ -147,8 +147,8 @@ func printTree(ctx context.Context, out io.Writer, fs *btrfs.FS, treeID btrfspri // case btrfsitem.INODE_EXTREF_KEY: // // TODO case *btrfsitem.DirEntry: - textui.Fprintf(out, "\t\tlocation %v type %v\n", - fmtKey(body.Location), body.Type) + textui.Fprintf(out, "\t\tlocation key %v type %v\n", + body.Location.Format(treeID), body.Type) textui.Fprintf(out, "\t\ttransid %v data_len %v name_len %v\n", body.TransID, body.DataLen, body.NameLen) textui.Fprintf(out, "\t\tname: %s\n", body.Name) @@ -162,8 +162,8 @@ func printTree(ctx context.Context, out io.Writer, fs *btrfs.FS, treeID btrfspri body.Generation, body.RootDirID, body.ByteNr, body.ByteLimit, body.BytesUsed) textui.Fprintf(out, "\t\tlast_snapshot %v flags %v refs %v\n", body.LastSnapshot, body.Flags, body.Refs) - textui.Fprintf(out, "\t\tdrop_progress %v drop_level %v\n", - fmtKey(body.DropProgress), body.DropLevel) + textui.Fprintf(out, "\t\tdrop_progress key %v drop_level %v\n", + body.DropProgress.Format(treeID), body.DropLevel) textui.Fprintf(out, "\t\tlevel %v generation_v2 %v\n", body.Level, body.GenerationV2) if body.Generation == body.GenerationV2 { @@ -193,8 +193,8 @@ func printTree(ctx context.Context, out io.Writer, fs *btrfs.FS, treeID btrfspri textui.Fprintf(out, "\t\trefs %v gen %v flags %v\n", body.Head.Refs, body.Head.Generation, body.Head.Flags) if body.Head.Flags.Has(btrfsitem.EXTENT_FLAG_TREE_BLOCK) { - textui.Fprintf(out, "\t\ttree block %v level %v\n", - fmtKey(body.Info.Key), body.Info.Level) + textui.Fprintf(out, "\t\ttree block key %v level %v\n", + body.Info.Key.Format(treeID), body.Info.Level) } printExtentInlineRefs(out, body.Refs) case *btrfsitem.Metadata: @@ -319,7 +319,7 @@ func printTree(ctx context.Context, out io.Writer, fs *btrfs.FS, treeID btrfspri // // TODO case *btrfsitem.DevStats: textui.Fprintf(out, "\t\tpersistent item objectid %v offset %v\n", - item.Key.ObjectID.Format(item.Key.ItemType), item.Key.Offset) + item.Key.ObjectID.Format(treeID), item.Key.Offset) switch item.Key.ObjectID { case btrfsprim.DEV_STATS_OBJECTID: textui.Fprintf(out, "\t\tdevice stats\n") @@ -437,27 +437,6 @@ func printExtentInlineRefs(out io.Writer, refs []btrfsitem.ExtentInlineRef) { } } -// mimics print-tree.c:btrfs_print_key() -func fmtKey(key btrfsprim.Key) string { - var out strings.Builder - textui.Fprintf(&out, "key (%v %v", key.ObjectID.Format(key.ItemType), key.ItemType) - switch key.ItemType { - case btrfsitem.QGROUP_RELATION_KEY, btrfsitem.QGROUP_INFO_KEY, btrfsitem.QGROUP_LIMIT_KEY: - textui.Fprintf(&out, " %v)", btrfsprim.ObjID(key.Offset).Format(btrfsprim.QGROUP_RELATION_KEY)) - case btrfsitem.UUID_SUBVOL_KEY, btrfsitem.UUID_RECEIVED_SUBVOL_KEY: - textui.Fprintf(&out, " %#08x)", key.Offset) - case btrfsitem.ROOT_ITEM_KEY: - textui.Fprintf(&out, " %v)", btrfsprim.ObjID(key.Offset)) - default: - if key.Offset == math.MaxUint64 { - textui.Fprintf(&out, " -1)") - } else { - textui.Fprintf(&out, " %v)", key.Offset) - } - } - return out.String() -} - func fmtTime(t btrfsprim.Time) string { return textui.Sprintf("%v.%v (%v)", t.Sec, t.NSec, t.ToStd().Format("2006-01-02 15:04:05")) diff --git a/lib/containers/rbtree.go b/lib/containers/rbtree.go index 4125847..6182150 100644 --- a/lib/containers/rbtree.go +++ b/lib/containers/rbtree.go @@ -12,8 +12,8 @@ import ( type Color bool const ( - Black = Color(false) - Red = Color(true) + Black Color = false + Red Color = true ) type RBNode[T Ordered[T]] struct { diff --git a/lib/fmtutil/bitfield.go b/lib/fmtutil/bitfield.go index d46fee5..7f0b143 100644 --- a/lib/fmtutil/bitfield.go +++ b/lib/fmtutil/bitfield.go @@ -12,7 +12,7 @@ import ( type BitfieldFormat uint8 const ( - HexNone = BitfieldFormat(iota) + HexNone BitfieldFormat = iota HexLower HexUpper ) |