summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--pkg/btrfs/internal/itemtype.go2
-rw-r--r--pkg/btrfs/types_node.go2
-rw-r--r--pkg/btrfsmisc/print_tree.go24
-rwxr-xr-xscripts/diff-dump-tree.sh2
8 files changed, 74 insertions, 5 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() {}
diff --git a/pkg/btrfs/internal/itemtype.go b/pkg/btrfs/internal/itemtype.go
index 842f5b6..e4b1302 100644
--- a/pkg/btrfs/internal/itemtype.go
+++ b/pkg/btrfs/internal/itemtype.go
@@ -13,6 +13,7 @@ const (
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)
@@ -43,6 +44,7 @@ func (t ItemType) String() string {
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",
diff --git a/pkg/btrfs/types_node.go b/pkg/btrfs/types_node.go
index 24a02e5..8aafc49 100644
--- a/pkg/btrfs/types_node.go
+++ b/pkg/btrfs/types_node.go
@@ -266,7 +266,7 @@ func (node *Node) unmarshalLeaf(bodyBuf []byte) (int, error) {
}
tail = dataOff
dataBuf := bodyBuf[dataOff : dataOff+dataSize]
- item.Body = btrfsitem.UnmarshalItem(item.Head.Key, dataBuf)
+ item.Body = btrfsitem.UnmarshalItem(item.Head.Key, node.ChecksumType, dataBuf)
node.BodyLeaf = append(node.BodyLeaf, item)
}
diff --git a/pkg/btrfsmisc/print_tree.go b/pkg/btrfsmisc/print_tree.go
index bc3224b..59ad0f5 100644
--- a/pkg/btrfsmisc/print_tree.go
+++ b/pkg/btrfsmisc/print_tree.go
@@ -7,6 +7,7 @@ import (
"lukeshu.com/btrfs-tools/pkg/btrfs"
"lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem"
+ "lukeshu.com/btrfs-tools/pkg/btrfs/btrfssum"
"lukeshu.com/btrfs-tools/pkg/btrfs/btrfsvol"
"lukeshu.com/btrfs-tools/pkg/util"
)
@@ -117,8 +118,27 @@ func PrintTree(fs *btrfs.FS, root btrfsvol.LogicalAddr) error {
// // TODO
//case btrfsitem.SHARED_DATA_REF_KEY:
// // TODO
- //case btrfsitem.EXTENT_CSUM_KEY:
- // // TODO
+ case btrfsitem.ExtentCSum:
+ sb, _ := fs.Superblock()
+ sectorSize := btrfsvol.AddrDelta(sb.Data.SectorSize)
+
+ start := btrfsvol.LogicalAddr(item.Head.Key.Offset)
+ itemSize := btrfsvol.AddrDelta(len(body.Sums)) * sectorSize
+ fmt.Printf("\t\trange start %d end %d length %d",
+ start, start.Add(itemSize), itemSize)
+ sumsPerLine := util.Max(1, len(btrfssum.CSum{})/body.ChecksumSize/2)
+
+ pos := start
+ for i, sum := range body.Sums {
+ if i%sumsPerLine == 0 {
+ fmt.Printf("\n\t\t")
+ } else {
+ fmt.Printf(" ")
+ }
+ fmt.Printf("[%d] 0x%s", pos, sum.Fmt(sb.Data.ChecksumType))
+ pos = pos.Add(sectorSize)
+ }
+ fmt.Printf("\n")
case btrfsitem.FileExtent:
fmt.Printf("\t\tgeneration %v type %v\n",
body.Generation, body.Type)
diff --git a/scripts/diff-dump-tree.sh b/scripts/diff-dump-tree.sh
index 9e650f3..597adb5 100755
--- a/scripts/diff-dump-tree.sh
+++ b/scripts/diff-dump-tree.sh
@@ -1,5 +1,5 @@
#!/bin/bash
make -C ../btrfs-progs
diff -u \
- <(../btrfs-progs/btrfs inspect dump-tree --noscan ../scratch/new.img | sed -e 's/ UNKNOWN.0 / UNTYPED /g' -e 's/\b18446744073709551615\b/-1/g') \
+ <(../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') \
<(go run ./cmd/btrfs-dump-tree/ ../scratch/new.img)