diff options
Diffstat (limited to 'pkg/btrfs/btrfsitem')
-rw-r--r-- | pkg/btrfs/btrfsitem/item_extentcsum.go | 39 | ||||
-rw-r--r-- | pkg/btrfs/btrfsitem/items.go | 6 | ||||
-rw-r--r-- | pkg/btrfs/btrfsitem/items.txt | 1 | ||||
-rw-r--r-- | pkg/btrfs/btrfsitem/items_gen.go | 3 |
4 files changed, 48 insertions, 1 deletions
diff --git a/pkg/btrfs/btrfsitem/item_extentcsum.go b/pkg/btrfs/btrfsitem/item_extentcsum.go new file mode 100644 index 0000000..27c7c9b --- /dev/null +++ b/pkg/btrfs/btrfsitem/item_extentcsum.go @@ -0,0 +1,39 @@ +package btrfsitem + +import ( + "fmt" + + "lukeshu.com/btrfs-tools/pkg/btrfs/btrfssum" +) + +// key.objectid = BTRFS_EXTENT_CSUM_OBJECTID +// key.offset = laddr of checksummed region +type ExtentCSum struct { // EXTENT_CSUM=128 + ChecksumSize int + // Checksum of each sector starting at key.offset + Sums []btrfssum.CSum +} + +func (o *ExtentCSum) UnmarshalBinary(dat []byte) (int, error) { + if o.ChecksumSize == 0 { + return 0, fmt.Errorf("btrfs.ExtentCSum.UnmarshalBinary: .ChecksumSize must be set") + } + for len(dat) >= o.ChecksumSize { + var csum btrfssum.CSum + copy(csum[:], dat[:o.ChecksumSize]) + dat = dat[o.ChecksumSize:] + o.Sums = append(o.Sums, csum) + } + return len(o.Sums) * o.ChecksumSize, nil +} + +func (o ExtentCSum) MarshalBinary() ([]byte, error) { + if o.ChecksumSize == 0 { + return nil, fmt.Errorf("btrfs.ExtentCSum.MarshalBinary: .ChecksumSize must be set") + } + var dat []byte + for _, csum := range o.Sums { + dat = append(dat, csum[:o.ChecksumSize]...) + } + return dat, nil +} diff --git a/pkg/btrfs/btrfsitem/items.go b/pkg/btrfs/btrfsitem/items.go index 1a3b883..5ad3471 100644 --- a/pkg/btrfs/btrfsitem/items.go +++ b/pkg/btrfs/btrfsitem/items.go @@ -5,6 +5,7 @@ import ( "reflect" "lukeshu.com/btrfs-tools/pkg/binstruct" + "lukeshu.com/btrfs-tools/pkg/btrfs/btrfssum" "lukeshu.com/btrfs-tools/pkg/btrfs/internal" ) @@ -31,7 +32,7 @@ func (o *Error) UnmarshalBinary(dat []byte) (int, error) { } // Rather than returning a separate error value, return an Error item. -func UnmarshalItem(key internal.Key, dat []byte) Item { +func UnmarshalItem(key internal.Key, csumType btrfssum.CSumType, dat []byte) Item { var gotyp reflect.Type if key.ItemType == UNTYPED_KEY { var ok bool @@ -54,6 +55,9 @@ func UnmarshalItem(key internal.Key, dat []byte) Item { } } retPtr := reflect.New(gotyp) + if csums, ok := retPtr.Interface().(*ExtentCSum); ok { + csums.ChecksumSize = csumType.Size() + } n, err := binstruct.Unmarshal(dat, retPtr.Interface()) if err != nil { return Error{ diff --git a/pkg/btrfs/btrfsitem/items.txt b/pkg/btrfs/btrfsitem/items.txt index 59e3e76..dbcd260 100644 --- a/pkg/btrfs/btrfsitem/items.txt +++ b/pkg/btrfs/btrfsitem/items.txt @@ -4,6 +4,7 @@ DEV_EXTENT=204 DevExtent DEV_ITEM=216 Dev DIR_INDEX=96 DirList DIR_ITEM=84 DirList +EXTENT_CSUM=128 ExtentCSum EXTENT_DATA=108 FileExtent EXTENT_DATA_REF=178 ExtentDataRef EXTENT_ITEM=168 Extent diff --git a/pkg/btrfs/btrfsitem/items_gen.go b/pkg/btrfs/btrfsitem/items_gen.go index e60c50e..f0a4274 100644 --- a/pkg/btrfs/btrfsitem/items_gen.go +++ b/pkg/btrfs/btrfsitem/items_gen.go @@ -15,6 +15,7 @@ const ( DEV_ITEM_KEY = internal.DEV_ITEM_KEY DIR_INDEX_KEY = internal.DIR_INDEX_KEY DIR_ITEM_KEY = internal.DIR_ITEM_KEY + EXTENT_CSUM_KEY = internal.EXTENT_CSUM_KEY EXTENT_DATA_KEY = internal.EXTENT_DATA_KEY EXTENT_DATA_REF_KEY = internal.EXTENT_DATA_REF_KEY EXTENT_ITEM_KEY = internal.EXTENT_ITEM_KEY @@ -44,6 +45,7 @@ var keytype2gotype = map[Type]reflect.Type{ DEV_ITEM_KEY: reflect.TypeOf(Dev{}), DIR_INDEX_KEY: reflect.TypeOf(DirList{}), DIR_ITEM_KEY: reflect.TypeOf(DirList{}), + EXTENT_CSUM_KEY: reflect.TypeOf(ExtentCSum{}), EXTENT_DATA_KEY: reflect.TypeOf(FileExtent{}), EXTENT_DATA_REF_KEY: reflect.TypeOf(ExtentDataRef{}), EXTENT_ITEM_KEY: reflect.TypeOf(Extent{}), @@ -76,6 +78,7 @@ func (DevStats) isItem() {} func (DirList) isItem() {} func (Empty) isItem() {} func (Extent) isItem() {} +func (ExtentCSum) isItem() {} func (ExtentDataRef) isItem() {} func (FileExtent) isItem() {} func (FreeSpaceBitmap) isItem() {} |