diff options
Diffstat (limited to 'pkg/btrfs/btrfsitem')
-rw-r--r-- | pkg/btrfs/btrfsitem/item_empty.go | 2 | ||||
-rw-r--r-- | pkg/btrfs/btrfsitem/item_untyped.go | 14 | ||||
-rw-r--r-- | pkg/btrfs/btrfsitem/items.go | 32 | ||||
-rw-r--r-- | pkg/btrfs/btrfsitem/items.txt | 2 | ||||
-rw-r--r-- | pkg/btrfs/btrfsitem/items_gen.go | 5 |
5 files changed, 43 insertions, 12 deletions
diff --git a/pkg/btrfs/btrfsitem/item_empty.go b/pkg/btrfs/btrfsitem/item_empty.go index 74645cc..93e2f9e 100644 --- a/pkg/btrfs/btrfsitem/item_empty.go +++ b/pkg/btrfs/btrfsitem/item_empty.go @@ -4,6 +4,6 @@ import ( "lukeshu.com/btrfs-tools/pkg/binstruct" ) -type Empty struct { // UNTYPED=0 ORPHAN_ITEM=48 TREE_BLOCK_REF=176 SHARED_BLOCK_REF=182 FREE_SPACE_EXTENT=199 QGROUP_RELATION=246 +type Empty struct { // ORPHAN_ITEM=48 TREE_BLOCK_REF=176 SHARED_BLOCK_REF=182 FREE_SPACE_EXTENT=199 QGROUP_RELATION=246 binstruct.End `bin:"off=0"` } diff --git a/pkg/btrfs/btrfsitem/item_untyped.go b/pkg/btrfs/btrfsitem/item_untyped.go new file mode 100644 index 0000000..51d0676 --- /dev/null +++ b/pkg/btrfs/btrfsitem/item_untyped.go @@ -0,0 +1,14 @@ +package btrfsitem + +import ( + "lukeshu.com/btrfs-tools/pkg/binstruct" + "lukeshu.com/btrfs-tools/pkg/btrfs/internal" +) + +type FreeSpaceHeader struct { // UNTYPED=0:FREE_SPACE_OBJECTID + Location internal.Key `bin:"off=0x00, siz=0x11"` + Generation int64 `bin:"off=0x11, siz=0x8"` + NumEntries int64 `bin:"off=0x19, siz=0x8"` + NumBitmaps int64 `bin:"off=0x21, siz=0x8"` + binstruct.End `bin:"off=0x29"` +} diff --git a/pkg/btrfs/btrfsitem/items.go b/pkg/btrfs/btrfsitem/items.go index 3c4392e..c4ad7e9 100644 --- a/pkg/btrfs/btrfsitem/items.go +++ b/pkg/btrfs/btrfsitem/items.go @@ -31,12 +31,26 @@ func (o *Error) UnmarshalBinary(dat []byte) (int, error) { } // Rather than returning a separate error value, return an Error item. -func UnmarshalItem(keytyp Type, dat []byte) Item { - gotyp, ok := keytype2gotype[keytyp] - if !ok { - return Error{ - Dat: dat, - Err: fmt.Errorf("btrfsitem.UnmarshalItem(typ=%v, dat): unknown item type", keytyp), +func UnmarshalItem(key internal.Key, dat []byte) Item { + var gotyp reflect.Type + if key.ItemType == UNTYPED_KEY { + var ok bool + gotyp, ok = untypedObjID2gotype[key.ObjectID] + if !ok { + return Error{ + Dat: dat, + Err: fmt.Errorf("btrfsitem.UnmarshalItem({ItemType:%v, ObjectID:%v}, dat): unknown object ID for untyped item", + key.ItemType, key.ObjectID), + } + } + } else { + var ok bool + gotyp, ok = keytype2gotype[key.ItemType] + if !ok { + return Error{ + Dat: dat, + Err: fmt.Errorf("btrfsitem.UnmarshalItem({ItemType:%v}, dat): unknown item type", key.ItemType), + } } } retPtr := reflect.New(gotyp) @@ -44,15 +58,15 @@ func UnmarshalItem(keytyp Type, dat []byte) Item { if err != nil { return Error{ Dat: dat, - Err: fmt.Errorf("btrfsitem.UnmarshalItem(typ=%v, dat): %w", keytyp, err), + Err: fmt.Errorf("btrfsitem.UnmarshalItem({ItemType:%v}, dat): %w", key.ItemType, err), } } if n < len(dat) { return Error{ Dat: dat, - Err: fmt.Errorf("btrfsitem.UnmarshalItem(typ=%v, dat): left over data: got %d bytes but only consumed %d", - keytyp, len(dat), n), + Err: fmt.Errorf("btrfsitem.UnmarshalItem({ItemType:%v}, dat): left over data: got %d bytes but only consumed %d", + key.ItemType, len(dat), n), } } return retPtr.Elem().Interface().(Item) diff --git a/pkg/btrfs/btrfsitem/items.txt b/pkg/btrfs/btrfsitem/items.txt index 8320650..59e3e76 100644 --- a/pkg/btrfs/btrfsitem/items.txt +++ b/pkg/btrfs/btrfsitem/items.txt @@ -20,7 +20,7 @@ ROOT_ITEM=132 Root SHARED_BLOCK_REF=182 Empty SHARED_DATA_REF=184 SharedDataRef TREE_BLOCK_REF=176 Empty -UNTYPED=0 Empty +UNTYPED=0:FREE_SPACE_OBJECTID FreeSpaceHeader UUID_RECEIVED_SUBVOL=252 UUIDMap UUID_SUBVOL=251 UUIDMap XATTR_ITEM=24 DirList diff --git a/pkg/btrfs/btrfsitem/items_gen.go b/pkg/btrfs/btrfsitem/items_gen.go index 02e2915..e60c50e 100644 --- a/pkg/btrfs/btrfsitem/items_gen.go +++ b/pkg/btrfs/btrfsitem/items_gen.go @@ -60,11 +60,13 @@ var keytype2gotype = map[Type]reflect.Type{ SHARED_BLOCK_REF_KEY: reflect.TypeOf(Empty{}), SHARED_DATA_REF_KEY: reflect.TypeOf(SharedDataRef{}), TREE_BLOCK_REF_KEY: reflect.TypeOf(Empty{}), - UNTYPED_KEY: reflect.TypeOf(Empty{}), UUID_RECEIVED_SUBVOL_KEY: reflect.TypeOf(UUIDMap{}), UUID_SUBVOL_KEY: reflect.TypeOf(UUIDMap{}), XATTR_ITEM_KEY: reflect.TypeOf(DirList{}), } +var untypedObjID2gotype = map[internal.ObjID]reflect.Type{ + internal.FREE_SPACE_OBJECTID: reflect.TypeOf(FreeSpaceHeader{}), +} func (BlockGroup) isItem() {} func (Chunk) isItem() {} @@ -77,6 +79,7 @@ func (Extent) isItem() {} func (ExtentDataRef) isItem() {} func (FileExtent) isItem() {} func (FreeSpaceBitmap) isItem() {} +func (FreeSpaceHeader) isItem() {} func (FreeSpaceInfo) isItem() {} func (Inode) isItem() {} func (InodeRefList) isItem() {} |