summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-08-28 11:50:57 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-08-28 14:40:22 -0600
commit0e699ef345f61ec38b937d6e73c064c6ecf450a7 (patch)
tree8989ec192ff13d49c0f1370bc10e77d5ee250322
parenta40e81b3b629198a4c30ad18f7544c7d513da287 (diff)
btrfs: Allow TreeWalkHandler to indicate a node should be skipped
-rw-r--r--lib/btrfs/io3_btree.go20
1 files changed, 19 insertions, 1 deletions
diff --git a/lib/btrfs/io3_btree.go b/lib/btrfs/io3_btree.go
index 154f800..97670c0 100644
--- a/lib/btrfs/io3_btree.go
+++ b/lib/btrfs/io3_btree.go
@@ -6,6 +6,7 @@ package btrfs
import (
"context"
+ "errors"
"fmt"
"io"
iofs "io/fs"
@@ -322,7 +323,12 @@ func LookupTreeRoot(fs Trees, treeID ObjID) (*TreeRoot, error) {
}
type TreeWalkHandler struct {
- // Callbacks for entire nodes
+ // Callbacks for entire nodes.
+ //
+ // If any of these return an error that is io/fs.SkipDir, the
+ // node immediately stops getting processed; if PreNode, Node,
+ // or BadNode return io/fs.SkipDir then key pointers and items
+ // within the node are not processed.
PreNode func(TreePath) error
Node func(TreePath, *diskio.Ref[btrfsvol.LogicalAddr, Node]) error
BadNode func(TreePath, *diskio.Ref[btrfsvol.LogicalAddr, Node], error) error
@@ -368,6 +374,9 @@ func (fs *FS) treeWalk(ctx context.Context, path TreePath, errHandle func(*TreeE
if cbs.PreNode != nil {
if err := cbs.PreNode(path); err != nil {
+ if errors.Is(err, iofs.SkipDir) {
+ return
+ }
errHandle(&TreeError{Path: path, Err: err})
}
if ctx.Err() != nil {
@@ -381,12 +390,18 @@ func (fs *FS) treeWalk(ctx context.Context, path TreePath, errHandle func(*TreeE
if err != nil && node != nil && cbs.BadNode != nil {
// opportunity to fix the node
err = cbs.BadNode(path, node, err)
+ if errors.Is(err, iofs.SkipDir) {
+ return
+ }
}
if err != nil {
errHandle(&TreeError{Path: path, Err: err})
} else {
if cbs.Node != nil {
if err := cbs.Node(path, node); err != nil {
+ if errors.Is(err, iofs.SkipDir) {
+ return
+ }
errHandle(&TreeError{Path: path, Err: err})
}
}
@@ -452,6 +467,9 @@ func (fs *FS) treeWalk(ctx context.Context, path TreePath, errHandle func(*TreeE
}
if cbs.PostNode != nil {
if err := cbs.PostNode(path, node); err != nil {
+ if errors.Is(err, iofs.SkipDir) {
+ return
+ }
errHandle(&TreeError{Path: path, Err: err})
}
}