summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-07-01 00:31:57 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-07-01 00:31:57 -0600
commitb589943af25661c140bacdc0afc2550e1e2db852 (patch)
tree99fb838ed9a00d335a1543431145b1f6680753e4
parent7d2d4ae383e02a03dec6aa60207e3a1dfa8e79a9 (diff)
add more callbacks to WalkFS
-rw-r--r--cmd/btrfs-fsck/pass1.go27
-rw-r--r--cmd/btrfs-fsck/pass2.go15
-rw-r--r--pkg/btrfsmisc/walk.go33
3 files changed, 50 insertions, 25 deletions
diff --git a/cmd/btrfs-fsck/pass1.go b/cmd/btrfs-fsck/pass1.go
index 6812c73..5188d65 100644
--- a/cmd/btrfs-fsck/pass1.go
+++ b/cmd/btrfs-fsck/pass1.go
@@ -22,19 +22,22 @@ func pass1(fs *btrfs.FS, superblock *util.Ref[btrfs.PhysicalAddr, btrfs.Superblo
fmt.Printf("Pass 1: ... walking fs\n")
visitedNodes := make(map[btrfs.LogicalAddr]struct{})
- btrfsmisc.WalkFS(fs, btrfs.WalkTreeHandler{
- Node: func(path btrfs.WalkTreePath, node *util.Ref[btrfs.LogicalAddr, btrfs.Node], err error) error {
- if err != nil {
- err = fmt.Errorf("%v: %w", path, err)
- fmt.Printf("Pass 1: ... walk fs: error: %v\n", err)
- }
- if node != nil {
- visitedNodes[node.Addr] = struct{}{}
- }
- return err
+ btrfsmisc.WalkFS(fs, btrfsmisc.WalkFSHandler{
+ WalkTreeHandler: btrfs.WalkTreeHandler{
+ Node: func(path btrfs.WalkTreePath, node *util.Ref[btrfs.LogicalAddr, btrfs.Node], err error) error {
+ if err != nil {
+ err = fmt.Errorf("%v: %w", path, err)
+ fmt.Printf("Pass 1: ... walk fs: error: %v\n", err)
+ }
+ if node != nil {
+ visitedNodes[node.Addr] = struct{}{}
+ }
+ return err
+ },
+ },
+ Err: func(err error) {
+ fmt.Printf("Pass 1: ... walk fs: error: %v\n", err)
},
- }, func(err error) {
- fmt.Printf("Pass 1: ... walk fs: error: %v\n", err)
})
fsFoundNodes := make(map[btrfs.LogicalAddr]struct{})
diff --git a/cmd/btrfs-fsck/pass2.go b/cmd/btrfs-fsck/pass2.go
index acea740..7970cca 100644
--- a/cmd/btrfs-fsck/pass2.go
+++ b/cmd/btrfs-fsck/pass2.go
@@ -13,13 +13,16 @@ func pass2(fs *btrfs.FS, foundNodes map[btrfs.LogicalAddr]struct{}) {
fmt.Printf("\nPass 2: orphaned nodes\n")
visitedNodes := make(map[btrfs.LogicalAddr]struct{})
- btrfsmisc.WalkFS(fs, btrfs.WalkTreeHandler{
- Node: func(path btrfs.WalkTreePath, node *util.Ref[btrfs.LogicalAddr, btrfs.Node], err error) error {
- visitedNodes[node.Addr] = struct{}{}
- return nil
+ btrfsmisc.WalkFS(fs, btrfsmisc.WalkFSHandler{
+ WalkTreeHandler: btrfs.WalkTreeHandler{
+ Node: func(path btrfs.WalkTreePath, node *util.Ref[btrfs.LogicalAddr, btrfs.Node], err error) error {
+ visitedNodes[node.Addr] = struct{}{}
+ return nil
+ },
+ },
+ Err: func(err error) {
+ fmt.Printf("Pass 2: walk FS: error: %v\n", err)
},
- }, func(err error) {
- fmt.Printf("Pass 2: walk FS: error: %v\n", err)
})
orphanedNodes := make(map[btrfs.LogicalAddr]int)
diff --git a/pkg/btrfsmisc/walk.go b/pkg/btrfsmisc/walk.go
index fc0edbc..a82bd5f 100644
--- a/pkg/btrfsmisc/walk.go
+++ b/pkg/btrfsmisc/walk.go
@@ -23,13 +23,22 @@ func (e WalkErr) Error() string {
return fmt.Sprintf("%v: %v: %v", e.TreeName, e.Path, e.Err)
}
+type WalkFSHandler struct {
+ Err func(error)
+ // Callbacks for entire trees
+ PreTree func(name string, laddr btrfs.LogicalAddr)
+ PostTree func(name string, laddr btrfs.LogicalAddr)
+ // Callbacks for nodes or smaller
+ btrfs.WalkTreeHandler
+}
+
// WalkFS walks all trees in a *btrfs.FS. Rather than returning an
// error, it calls errCb each time an error is encountered. The error
// will always be of type WalkErr.
-func WalkFS(fs *btrfs.FS, cbs btrfs.WalkTreeHandler, errCb func(error)) {
+func WalkFS(fs *btrfs.FS, cbs WalkFSHandler) {
var treeName string
handleErr := func(path btrfs.WalkTreePath, err error) {
- errCb(WalkErr{
+ cbs.Err(WalkErr{
TreeName: treeName,
Path: path,
Err: err,
@@ -82,29 +91,39 @@ func WalkFS(fs *btrfs.FS, cbs btrfs.WalkTreeHandler, errCb func(error)) {
}
treeName = "root tree"
- if err := fs.WalkTree(superblock.Data.RootTree, cbs); err != nil {
+ cbs.PreTree(treeName, superblock.Data.RootTree)
+ if err := fs.WalkTree(superblock.Data.RootTree, cbs.WalkTreeHandler); err != nil {
handleErr(nil, err)
}
+ cbs.PostTree(treeName, superblock.Data.RootTree)
treeName = "chunk tree"
- if err := fs.WalkTree(superblock.Data.ChunkTree, cbs); err != nil {
+ cbs.PreTree(treeName, superblock.Data.ChunkTree)
+ if err := fs.WalkTree(superblock.Data.ChunkTree, cbs.WalkTreeHandler); err != nil {
handleErr(nil, err)
}
+ cbs.PostTree(treeName, superblock.Data.ChunkTree)
treeName = "log tree"
- if err := fs.WalkTree(superblock.Data.LogTree, cbs); err != nil {
+ cbs.PreTree(treeName, superblock.Data.LogTree)
+ if err := fs.WalkTree(superblock.Data.LogTree, cbs.WalkTreeHandler); err != nil {
handleErr(nil, err)
}
+ cbs.PostTree(treeName, superblock.Data.LogTree)
treeName = "block group tree"
- if err := fs.WalkTree(superblock.Data.BlockGroupRoot, cbs); err != nil {
+ cbs.PreTree(treeName, superblock.Data.BlockGroupRoot)
+ if err := fs.WalkTree(superblock.Data.BlockGroupRoot, cbs.WalkTreeHandler); err != nil {
handleErr(nil, err)
}
+ cbs.PostTree(treeName, superblock.Data.BlockGroupRoot)
for _, tree := range foundTrees {
treeName = tree.Name
- if err := fs.WalkTree(tree.Root, cbs); err != nil {
+ cbs.PreTree(treeName, tree.Root)
+ if err := fs.WalkTree(tree.Root, cbs.WalkTreeHandler); err != nil {
handleErr(nil, err)
}
+ cbs.PostTree(treeName, tree.Root)
}
}