From 53a2ce3b4dcbfd17ac15230da17130a2aeae42dc Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 17 Oct 2022 00:15:06 -0600 Subject: Add and improve comments --- lib/btrfs/btrfsitem/item_blockgroup.go | 2 +- lib/btrfs/btrfsitem/item_devextent.go | 6 +++--- lib/btrfs/btrfsitem/item_extent.go | 2 ++ lib/btrfs/btrfsitem/item_extentdataref.go | 10 ++++++---- lib/btrfs/btrfsitem/item_freespacebitmap.go | 2 ++ lib/btrfs/btrfsitem/item_freespaceinfo.go | 22 ++++++++++++++++++++-- lib/btrfs/btrfsitem/item_inode.go | 4 +++- lib/btrfs/btrfsitem/item_root.go | 14 +++++++++----- lib/btrfs/btrfsitem/item_rootref.go | 11 +++++++++-- lib/btrfs/btrfsitem/item_shareddataref.go | 6 +++++- lib/btrfsprogs/btrfsutil/broken_btree.go | 2 +- 11 files changed, 61 insertions(+), 20 deletions(-) (limited to 'lib') diff --git a/lib/btrfs/btrfsitem/item_blockgroup.go b/lib/btrfs/btrfsitem/item_blockgroup.go index 96ce218..6fc09ac 100644 --- a/lib/btrfs/btrfsitem/item_blockgroup.go +++ b/lib/btrfs/btrfsitem/item_blockgroup.go @@ -14,7 +14,7 @@ import ( // key.offset = size of chunk type BlockGroup struct { // BLOCK_GROUP_ITEM=192 Used int64 `bin:"off=0, siz=8"` - ChunkObjectID btrfsprim.ObjID `bin:"off=8, siz=8"` // always BTRFS_FIRST_CHUNK_TREE_OBJECTID + ChunkObjectID btrfsprim.ObjID `bin:"off=8, siz=8"` // always FIRST_CHUNK_TREE_OBJECTID Flags btrfsvol.BlockGroupFlags `bin:"off=16, siz=8"` binstruct.End `bin:"off=24"` } diff --git a/lib/btrfs/btrfsitem/item_devextent.go b/lib/btrfs/btrfsitem/item_devextent.go index 8f5f05c..47bdbcf 100644 --- a/lib/btrfs/btrfsitem/item_devextent.go +++ b/lib/btrfs/btrfsitem/item_devextent.go @@ -13,9 +13,9 @@ import ( // key.objectid = device_id // key.offset = physical_addr type DevExtent struct { // DEV_EXTENT=204 - ChunkTree int64 `bin:"off=0, siz=8"` - ChunkObjectID btrfsprim.ObjID `bin:"off=8, siz=8"` - ChunkOffset btrfsvol.LogicalAddr `bin:"off=16, siz=8"` + ChunkTree btrfsprim.ObjID `bin:"off=0, siz=8"` // always CHUNK_TREE_OBJECTID + ChunkObjectID btrfsprim.ObjID `bin:"off=8, siz=8"` // which chunk within .ChunkTree owns this extent, always FIRST_CHUNK_TREE_OBJECTID + ChunkOffset btrfsvol.LogicalAddr `bin:"off=16, siz=8"` // offset of the CHUNK_ITEM that owns this extent, within the .ChunkObjectID Length btrfsvol.AddrDelta `bin:"off=24, siz=8"` ChunkTreeUUID btrfsprim.UUID `bin:"off=32, siz=16"` binstruct.End `bin:"off=48"` diff --git a/lib/btrfs/btrfsitem/item_extent.go b/lib/btrfs/btrfsitem/item_extent.go index 97dc105..66aae1d 100644 --- a/lib/btrfs/btrfsitem/item_extent.go +++ b/lib/btrfs/btrfsitem/item_extent.go @@ -12,6 +12,8 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/fmtutil" ) +// key.objectid = laddr of the extent +// key.offset = length of the extent type Extent struct { // EXTENT_ITEM=168 Head ExtentHeader Info TreeBlockInfo // only if .Head.Flags.Has(EXTENT_FLAG_TREE_BLOCK) diff --git a/lib/btrfs/btrfsitem/item_extentdataref.go b/lib/btrfs/btrfsitem/item_extentdataref.go index 74ce799..8c856e2 100644 --- a/lib/btrfs/btrfsitem/item_extentdataref.go +++ b/lib/btrfs/btrfsitem/item_extentdataref.go @@ -9,10 +9,12 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsprim" ) +// key.objectid = laddr of the extent being referenced +// key.offset = crc32c([root,objectid,offset]) type ExtentDataRef struct { // EXTENT_DATA_REF=178 - Root btrfsprim.ObjID `bin:"off=0, siz=8"` - ObjectID btrfsprim.ObjID `bin:"off=8, siz=8"` - Offset int64 `bin:"off=16, siz=8"` - Count int32 `bin:"off=24, siz=4"` + Root btrfsprim.ObjID `bin:"off=0, siz=8"` // subvolume tree ID that references this extent + ObjectID btrfsprim.ObjID `bin:"off=8, siz=8"` // inode number that references this extent within the .Root subvolume + Offset int64 `bin:"off=16, siz=8"` // byte offset for the extent within the file + Count int32 `bin:"off=24, siz=4"` // reference count binstruct.End `bin:"off=28"` } diff --git a/lib/btrfs/btrfsitem/item_freespacebitmap.go b/lib/btrfs/btrfsitem/item_freespacebitmap.go index 7842785..ad46204 100644 --- a/lib/btrfs/btrfsitem/item_freespacebitmap.go +++ b/lib/btrfs/btrfsitem/item_freespacebitmap.go @@ -4,6 +4,8 @@ package btrfsitem +// key.objectid = object ID of the FreeSpaceInfo (logical_addr) +// key.offset = offset of the FreeSpaceInfo (size) type FreeSpaceBitmap []byte // FREE_SPACE_BITMAP=200 func (o *FreeSpaceBitmap) UnmarshalBinary(dat []byte) (int, error) { diff --git a/lib/btrfs/btrfsitem/item_freespaceinfo.go b/lib/btrfs/btrfsitem/item_freespaceinfo.go index 844f664..b38da20 100644 --- a/lib/btrfs/btrfsitem/item_freespaceinfo.go +++ b/lib/btrfs/btrfsitem/item_freespaceinfo.go @@ -6,10 +6,28 @@ package btrfsitem import ( "git.lukeshu.com/btrfs-progs-ng/lib/binstruct" + "git.lukeshu.com/btrfs-progs-ng/lib/fmtutil" ) +// key.objectid = object ID of the BlockGroup (logical_addr) +// key.offset = offset of the BlockGroup (size) type FreeSpaceInfo struct { // FREE_SPACE_INFO=198 - ExtentCount int32 `bin:"off=0, siz=4"` - Flags uint32 `bin:"off=4, siz=4"` + ExtentCount int32 `bin:"off=0, siz=4"` + Flags FreeSpaceFlags `bin:"off=4, siz=4"` binstruct.End `bin:"off=8"` } + +type FreeSpaceFlags uint32 + +const ( + FREE_SPACE_USING_BITMAPS = FreeSpaceFlags(1 << iota) +) + +var freeSpaceFlagNames = []string{ + "USING_BITMAPS", +} + +func (f FreeSpaceFlags) Has(req FreeSpaceFlags) bool { return f&req == req } +func (f FreeSpaceFlags) String() string { + return fmtutil.BitfieldString(f, freeSpaceFlagNames, fmtutil.HexNone) +} diff --git a/lib/btrfs/btrfsitem/item_inode.go b/lib/btrfs/btrfsitem/item_inode.go index 8023156..704b56a 100644 --- a/lib/btrfs/btrfsitem/item_inode.go +++ b/lib/btrfs/btrfsitem/item_inode.go @@ -10,12 +10,14 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/fmtutil" ) +// key.objectid = inode number +// key.offset = 0 type Inode struct { // INODE_ITEM=1 Generation btrfsprim.Generation `bin:"off=0x00, siz=0x08"` TransID int64 `bin:"off=0x08, siz=0x08"` Size int64 `bin:"off=0x10, siz=0x08"` // stat NumBytes int64 `bin:"off=0x18, siz=0x08"` // allocated bytes, may be larger than size (or smaller if there are holes?) - BlockGroup int64 `bin:"off=0x20, siz=0x08"` + BlockGroup btrfsprim.ObjID `bin:"off=0x20, siz=0x08"` // only used for freespace inodes NLink int32 `bin:"off=0x28, siz=0x04"` // stat UID int32 `bin:"off=0x2C, siz=0x04"` // stat GID int32 `bin:"off=0x30, siz=0x04"` // stat diff --git a/lib/btrfs/btrfsitem/item_root.go b/lib/btrfs/btrfsitem/item_root.go index 2e0b327..ffbbf4d 100644 --- a/lib/btrfs/btrfsitem/item_root.go +++ b/lib/btrfs/btrfsitem/item_root.go @@ -11,12 +11,16 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/fmtutil" ) +// key.objectid = tree ID +// key.offset = either +// - 0 if objectid is one of the BTRFS_*_TREE_OBJECTID defines or a non-snapshot volume; or +// - transaction_id of when this snapshot was created type Root struct { // ROOT_ITEM=132 - Inode Inode `bin:"off=0x000, siz=0xa0"` + Inode Inode `bin:"off=0x000, siz=0xa0"` // ??? Generation btrfsprim.Generation `bin:"off=0x0a0, siz=0x08"` - RootDirID btrfsprim.ObjID `bin:"off=0x0a8, siz=0x08"` - ByteNr btrfsvol.LogicalAddr `bin:"off=0x0b0, siz=0x08"` - ByteLimit int64 `bin:"off=0x0b8, siz=0x08"` + RootDirID btrfsprim.ObjID `bin:"off=0x0a8, siz=0x08"` // inode number of the root inode + ByteNr btrfsvol.LogicalAddr `bin:"off=0x0b0, siz=0x08"` // root node + ByteLimit int64 `bin:"off=0x0b8, siz=0x08"` // always 0 (unused) BytesUsed int64 `bin:"off=0x0c0, siz=0x08"` LastSnapshot int64 `bin:"off=0x0c8, siz=0x08"` Flags RootFlags `bin:"off=0x0d0, siz=0x08"` @@ -36,7 +40,7 @@ type Root struct { // ROOT_ITEM=132 OTime btrfsprim.Time `bin:"off=0x153, siz=0x0c"` STime btrfsprim.Time `bin:"off=0x15f, siz=0x0c"` RTime btrfsprim.Time `bin:"off=0x16b, siz=0x0c"` - GlobalTreeID btrfsprim.ObjID `bin:"off=0x177, siz=0x08"` + GlobalTreeID btrfsprim.ObjID `bin:"off=0x177, siz=0x08"` // ??? Reserved [7]int64 `bin:"off=0x17f, siz=0x38"` binstruct.End `bin:"off=0x1b7"` } diff --git a/lib/btrfs/btrfsitem/item_rootref.go b/lib/btrfs/btrfsitem/item_rootref.go index d1dfd3b..b33883d 100644 --- a/lib/btrfs/btrfsitem/item_rootref.go +++ b/lib/btrfs/btrfsitem/item_rootref.go @@ -12,9 +12,16 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsprim" ) +// RootRefs link subvolumes parent→child for normal subvolumes and +// base→snapshot for snapshot subvolumes. BACKREF items go the other +// direction; child→parent and snapshot→base. +// +// ROOT_REF | ROOT_BACKREF +// key.objectid = ID of the parent subvolume | ID of the child subvolume +// key.offset = ID of the child subvolume | ID of the parent subvolume type RootRef struct { // ROOT_REF=156 ROOT_BACKREF=144 - DirID btrfsprim.ObjID `bin:"off=0x00, siz=0x8"` - Sequence int64 `bin:"off=0x08, siz=0x8"` + DirID btrfsprim.ObjID `bin:"off=0x00, siz=0x8"` // inode of the parent directory of the dir entry + Sequence int64 `bin:"off=0x08, siz=0x8"` // index of that dir entry within the parent NameLen uint16 `bin:"off=0x10, siz=0x2"` // [ignored-when-writing] binstruct.End `bin:"off=0x12"` Name []byte `bin:"-"` diff --git a/lib/btrfs/btrfsitem/item_shareddataref.go b/lib/btrfs/btrfsitem/item_shareddataref.go index 5ce4198..d7765af 100644 --- a/lib/btrfs/btrfsitem/item_shareddataref.go +++ b/lib/btrfs/btrfsitem/item_shareddataref.go @@ -8,7 +8,11 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/binstruct" ) +// key.objectid = laddr of the extent being referenced +// +// key.offset = laddr of the leaf node containing the FileExtent +// (EXTENT_DATA_KEY) for this reference. type SharedDataRef struct { // SHARED_DATA_REF=184 - Count int32 `bin:"off=0, siz=4"` + Count int32 `bin:"off=0, siz=4"` // reference count binstruct.End `bin:"off=4"` } diff --git a/lib/btrfsprogs/btrfsutil/broken_btree.go b/lib/btrfsprogs/btrfsutil/broken_btree.go index 1fa84e7..0660a46 100644 --- a/lib/btrfsprogs/btrfsutil/broken_btree.go +++ b/lib/btrfsprogs/btrfsutil/broken_btree.go @@ -75,7 +75,7 @@ var _ btrfstree.TreeOperator = (*brokenTrees)(nil) // NewBrokenTrees wraps a *btrfs.FS to support looking up information // from broken trees. // -// Of the btrfs.FS.Tree{Verb}Trees methods: +// Of the btrfs.FS.Tree{Verb} methods: // // - TreeWalk works on broken trees // - TreeLookup relies on the tree being properly ordered (which a -- cgit v1.2.3-2-g168b