diff options
Diffstat (limited to 'pkg/btrfsmisc/fsck.go')
-rw-r--r-- | pkg/btrfsmisc/fsck.go | 34 |
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) |