summaryrefslogtreecommitdiff
path: root/pkg/btrfsmisc/fsck.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/btrfsmisc/fsck.go')
-rw-r--r--pkg/btrfsmisc/fsck.go34
1 files changed, 20 insertions, 14 deletions
diff --git a/pkg/btrfsmisc/fsck.go b/pkg/btrfsmisc/fsck.go
index 8d20e6e..a771cf4 100644
--- a/pkg/btrfsmisc/fsck.go
+++ b/pkg/btrfsmisc/fsck.go
@@ -36,26 +36,37 @@ func ScanForNodes(dev *btrfs.Device, sb btrfs.Superblock, fn func(*util.Ref[btrf
continue
}
- // does it look like a node?
+ // parse (early)
+ nodeRef := &util.Ref[btrfs.PhysicalAddr, btrfs.Node]{
+ File: dev,
+ Addr: pos,
+ Data: btrfs.Node{
+ Size: sb.NodeSize,
+ },
+ }
var nodeHeader btrfs.NodeHeader
if _, err := binstruct.Unmarshal(nodeBuf, &nodeHeader); err != nil {
fn(nil, fmt.Errorf("sector@%d: %w", pos, err))
}
+
+ // sanity checking
+
if nodeHeader.MetadataUUID != sb.EffectiveMetadataUUID() {
//fmt.Printf("sector@%d does not look like a node\n", pos)
continue
}
- // ok, it looks like a node; go ahead and read it as a node
-
- nodeRef := &util.Ref[btrfs.PhysicalAddr, btrfs.Node]{
- File: dev,
- Addr: pos,
- Data: btrfs.Node{
- Size: sb.NodeSize,
- },
+ stored := nodeRef.Data.Head.Checksum
+ calced := btrfs.CRC32c(nodeBuf[binstruct.StaticSize(btrfs.CSum{}):])
+ if stored != calced {
+ fn(nodeRef, fmt.Errorf("sector@%d: looks like a node but is corrupt: checksum doesn't match: stored=%s calculated=%s",
+ pos, stored, calced))
+ continue
}
+
+ // parse (main)
+
if _, err := nodeRef.Data.UnmarshalBinary(nodeBuf); err != nil {
fn(nil, fmt.Errorf("sector@%d: %w", pos, err))
continue
@@ -63,11 +74,6 @@ func ScanForNodes(dev *btrfs.Device, sb btrfs.Superblock, fn func(*util.Ref[btrf
// finally, process the node
- if nodeRef.Data.Head.Checksum != btrfs.CRC32c(nodeBuf[0x20:]) {
- fn(nodeRef, fmt.Errorf("sector@%d looks like a node but is corrupt (checksum doesn't match)", pos))
- continue
- }
-
fn(nodeRef, nil)
pos += btrfs.PhysicalAddr(sb.NodeSize) - btrfs.PhysicalAddr(sb.SectorSize)