summaryrefslogtreecommitdiff
path: root/pkg/btrfs/btrfsitem
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/btrfs/btrfsitem')
-rw-r--r--pkg/btrfs/btrfsitem/item_extentcsum.go39
-rw-r--r--pkg/btrfs/btrfsitem/items.go6
-rw-r--r--pkg/btrfs/btrfsitem/items.txt1
-rw-r--r--pkg/btrfs/btrfsitem/items_gen.go3
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() {}