summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-12 16:17:34 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-12 16:17:34 -0700
commitc55326b0cb6994bb802cf6aac4a296acfb0e41ff (patch)
tree020cb033adb3809bcc8ffed5f56ba8d167b32dd1
parentcfcc753dc8906817e15b1b7c36b4dc12462d12e4 (diff)
parentacbbfafa07922b458506b91a58f3a082da453fd1 (diff)
Merge branch 'lukeshu/enums'
-rw-r--r--lib/btrfs/Makefile11
-rw-r--r--lib/btrfs/btrfsitem/item_dir.go47
-rw-r--r--lib/btrfs/btrfsitem/item_extent.go2
-rw-r--r--lib/btrfs/btrfsitem/item_fileextent.go40
-rw-r--r--lib/btrfs/btrfsitem/item_freespaceinfo.go2
-rw-r--r--lib/btrfs/btrfsitem/item_inode.go2
-rw-r--r--lib/btrfs/btrfsitem/item_root.go2
-rw-r--r--lib/btrfs/btrfsprim/itemtype.go168
-rw-r--r--lib/btrfs/btrfsprim/misc.go29
-rw-r--r--lib/btrfs/btrfsprim/objid.go177
-rw-r--r--lib/btrfs/btrfssum/csum.go37
-rw-r--r--lib/btrfs/btrfstree/path.go3
-rw-r--r--lib/btrfs/btrfstree/types_node.go6
-rw-r--r--lib/btrfs/btrfstree/types_superblock.go2
-rw-r--r--lib/btrfs/btrfsvol/blockgroupflags.go2
-rw-r--r--lib/btrfsprogs/btrfsinspect/print_tree.go53
-rw-r--r--lib/containers/rbtree.go4
-rw-r--r--lib/fmtutil/bitfield.go2
-rwxr-xr-xscripts/diff-dump-tree.sh2
19 files changed, 305 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
)
diff --git a/scripts/diff-dump-tree.sh b/scripts/diff-dump-tree.sh
index 60ab4d3..3d560d9 100755
--- a/scripts/diff-dump-tree.sh
+++ b/scripts/diff-dump-tree.sh
@@ -16,6 +16,8 @@ diff -u \
<(../btrfs-progs/btrfs inspect dump-tree --noscan --csum-items ../scratch/new.img |
sed -e 's/ UNKNOWN.0 / UNTYPED /g' \
-e 's/\b18446744073709551615\b/-1/g' \
+ -e 's/INODE_REF 6)/INODE_REF ROOT_TREE_DIR)/g' \
+ -e 's/ROOT_BACKREF 5)/ROOT_BACKREF FS_TREE)/g' \
) \
<(go run ./cmd/btrfs-rec/ inspect dump-trees --pv=../scratch/new.img |
sed -E \