From 7b8cdb995ecce81e4603a31e3304f6a2b9401c4c Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 5 Jun 2022 21:30:25 -0600 Subject: more fsck --- pkg/btrfs/btrfsitem/item_chunk.go | 6 +++--- pkg/btrfs/io2_fs.go | 2 +- pkg/btrfs/types_btree.go | 42 +++++++++++++++++++++++++++++++++++++++ pkg/btrfsmisc/fsck.go | 2 +- 4 files changed, 47 insertions(+), 5 deletions(-) (limited to 'pkg') diff --git a/pkg/btrfs/btrfsitem/item_chunk.go b/pkg/btrfs/btrfsitem/item_chunk.go index eae8339..4389a46 100644 --- a/pkg/btrfs/btrfsitem/item_chunk.go +++ b/pkg/btrfs/btrfsitem/item_chunk.go @@ -23,9 +23,9 @@ type Chunk struct { // CHUNK_ITEM=228 } type ChunkStripe struct { - DeviceID internal.ObjID `bin:"off=0x0, siz=0x8"` - Offset uint64 `bin:"off=0x8, siz=0x8"` - DeviceUUID internal.UUID `bin:"off=0x10, siz=0x10"` + DeviceID internal.ObjID `bin:"off=0x0, siz=0x8"` + Offset internal.PhysicalAddr `bin:"off=0x8, siz=0x8"` + DeviceUUID internal.UUID `bin:"off=0x10, siz=0x10"` binstruct.End `bin:"off=0x20"` } diff --git a/pkg/btrfs/io2_fs.go b/pkg/btrfs/io2_fs.go index ff5415a..ca67a9c 100644 --- a/pkg/btrfs/io2_fs.go +++ b/pkg/btrfs/io2_fs.go @@ -181,7 +181,7 @@ func (fs *FS) Resolve(laddr LogicalAddr) (paddrs map[QualifiedPhysicalAddr]struc for _, stripe := range chunk.Chunk.Stripes { paddrs[QualifiedPhysicalAddr{ Dev: stripe.DeviceUUID, - Addr: PhysicalAddr(stripe.Offset + offsetWithinChunk), + Addr: stripe.Offset + PhysicalAddr(offsetWithinChunk), }] = struct{}{} } } diff --git a/pkg/btrfs/types_btree.go b/pkg/btrfs/types_btree.go index 5adc7ec..89901c3 100644 --- a/pkg/btrfs/types_btree.go +++ b/pkg/btrfs/types_btree.go @@ -2,7 +2,9 @@ package btrfs import ( "encoding/binary" + "errors" "fmt" + iofs "io/fs" "lukeshu.com/btrfs-tools/pkg/binstruct" "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem" @@ -297,6 +299,10 @@ func (fs *FS) ReadNode(addr LogicalAddr) (*util.Ref[LogicalAddr, Node], error) { } type WalkTreeHandler struct { + // Callbacks for entire nodes + PreNode func(LogicalAddr) error + MidNode func(*util.Ref[LogicalAddr, Node]) error + PostNode func(*util.Ref[LogicalAddr, Node]) error // Callbacks for items on internal nodes PreKeyPointer func(KeyPointer) error PostKeyPointer func(KeyPointer) error @@ -310,18 +316,40 @@ func (fs *FS) WalkTree(nodeAddr LogicalAddr, cbs WalkTreeHandler) error { if nodeAddr == 0 { return nil } + if cbs.PreNode != nil { + if err := cbs.PreNode(nodeAddr); err != nil { + if errors.Is(err, iofs.SkipDir) { + return nil + } + return err + } + } node, err := fs.ReadNode(nodeAddr) if err != nil { if cbs.NodeError != nil { err = cbs.NodeError(err) } if err != nil { + if errors.Is(err, iofs.SkipDir) { + return nil + } return fmt.Errorf("btrfs.FS.WalkTree: %w", err) } } + if cbs.MidNode != nil { + if err := cbs.MidNode(node); err != nil { + if errors.Is(err, iofs.SkipDir) { + return nil + } + return err + } + } for _, item := range node.Data.BodyInternal { if cbs.PreKeyPointer != nil { if err := cbs.PreKeyPointer(item); err != nil { + if errors.Is(err, iofs.SkipDir) { + continue + } return err } } @@ -330,6 +358,9 @@ func (fs *FS) WalkTree(nodeAddr LogicalAddr, cbs WalkTreeHandler) error { } if cbs.PostKeyPointer != nil { if err := cbs.PostKeyPointer(item); err != nil { + if errors.Is(err, iofs.SkipDir) { + continue + } return err } } @@ -337,9 +368,20 @@ func (fs *FS) WalkTree(nodeAddr LogicalAddr, cbs WalkTreeHandler) error { for _, item := range node.Data.BodyLeaf { if cbs.Item != nil { if err := cbs.Item(item.Head.Key, item.Body); err != nil { + if errors.Is(err, iofs.SkipDir) { + continue + } return fmt.Errorf("btrfs.FS.WalkTree: callback: %w", err) } } } + if cbs.PostNode != nil { + if err := cbs.PostNode(node); err != nil { + if errors.Is(err, iofs.SkipDir) { + return nil + } + return err + } + } return nil } diff --git a/pkg/btrfsmisc/fsck.go b/pkg/btrfsmisc/fsck.go index a9e7d1d..8d20e6e 100644 --- a/pkg/btrfsmisc/fsck.go +++ b/pkg/btrfsmisc/fsck.go @@ -23,7 +23,7 @@ func ScanForNodes(dev *btrfs.Device, sb btrfs.Superblock, fn func(*util.Ref[btrf } nodeBuf := make([]byte, sb.NodeSize) - for pos := btrfs.PhysicalAddr(0); pos+btrfs.PhysicalAddr(sb.SectorSize) < devSize; pos += btrfs.PhysicalAddr(sb.SectorSize) { + for pos := btrfs.PhysicalAddr(0); pos+btrfs.PhysicalAddr(sb.NodeSize) < devSize; pos += btrfs.PhysicalAddr(sb.SectorSize) { if util.InSlice(pos, btrfs.SuperblockAddrs) { //fmt.Printf("sector@%d is a superblock\n", pos) continue -- cgit v1.2.3-2-g168b