summaryrefslogtreecommitdiff
path: root/cmd/btrfs-rec/inspect/rebuildtrees
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/btrfs-rec/inspect/rebuildtrees')
-rw-r--r--cmd/btrfs-rec/inspect/rebuildtrees/rebuild.go23
-rw-r--r--cmd/btrfs-rec/inspect/rebuildtrees/rebuild_treecb.go6
-rw-r--r--cmd/btrfs-rec/inspect/rebuildtrees/rebuild_wantcb.go50
-rw-r--r--cmd/btrfs-rec/inspect/rebuildtrees/rebuild_wanttyp.go2
-rw-r--r--cmd/btrfs-rec/inspect/rebuildtrees/scan.go21
-rw-r--r--cmd/btrfs-rec/inspect/rebuildtrees/util.go8
6 files changed, 54 insertions, 56 deletions
diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild.go b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild.go
index cf334a0..6492d9c 100644
--- a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild.go
+++ b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild.go
@@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: GPL-2.0-or-later
-package rebuildnodes
+package rebuildtrees
import (
"context"
@@ -14,15 +14,14 @@ import (
"github.com/datawire/dlib/dgroup"
"github.com/datawire/dlib/dlog"
+ "git.lukeshu.com/btrfs-progs-ng/cmd/btrfs-rec/inspect/rebuildmappings"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsprim"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfstree"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect/rebuildnodes/btrees"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect/rebuildnodes/graph"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect/rebuildnodes/keyio"
+ "git.lukeshu.com/btrfs-progs-ng/lib/btrfscheck"
+ "git.lukeshu.com/btrfs-progs-ng/lib/btrfsutil"
"git.lukeshu.com/btrfs-progs-ng/lib/containers"
"git.lukeshu.com/btrfs-progs-ng/lib/maps"
"git.lukeshu.com/btrfs-progs-ng/lib/textui"
@@ -46,10 +45,10 @@ func (o keyAndTree) String() string {
type rebuilder struct {
sb btrfstree.Superblock
- graph graph.Graph
- keyIO *keyio.Handle
+ graph btrfsutil.Graph
+ keyIO *btrfsutil.KeyIO
- rebuilt *btrees.RebuiltForrest
+ rebuilt *btrfsutil.RebuiltForrest
curKey struct {
TreeID btrfsprim.ObjID
@@ -75,7 +74,7 @@ type Rebuilder interface {
ListRoots(context.Context) map[btrfsprim.ObjID]containers.Set[btrfsvol.LogicalAddr]
}
-func NewRebuilder(ctx context.Context, fs *btrfs.FS, nodeScanResults btrfsinspect.ScanDevicesResult) (Rebuilder, error) {
+func NewRebuilder(ctx context.Context, fs *btrfs.FS, nodeScanResults rebuildmappings.ScanDevicesResult) (Rebuilder, error) {
ctx = dlog.WithField(ctx, "btrfsinspect.rebuild-nodes.step", "read-fs-data")
sb, nodeGraph, keyIO, err := ScanDevices(ctx, fs, nodeScanResults) // ScanDevices does its own logging
if err != nil {
@@ -87,7 +86,7 @@ func NewRebuilder(ctx context.Context, fs *btrfs.FS, nodeScanResults btrfsinspec
graph: nodeGraph,
keyIO: keyIO,
}
- o.rebuilt = btrees.NewRebuiltForrest(sb, nodeGraph, keyIO, o)
+ o.rebuilt = btrfsutil.NewRebuiltForrest(sb, nodeGraph, keyIO, o)
return o, nil
}
@@ -214,7 +213,7 @@ func (o *rebuilder) processAddedItemQueue(ctx context.Context) error {
progress.NumAugments = o.numAugments
progress.NumAugmentTrees = len(o.augmentQueue)
progressWriter.Set(progress)
- } else if !handleWouldBeNoOp(key.ItemType) {
+ } else if !btrfscheck.HandleWouldBeNoOp(key.ItemType) {
o.settledItemQueue.Insert(key)
}
}
@@ -284,7 +283,7 @@ func (o *rebuilder) processSettledItemQueue(ctx context.Context) error {
ctx := dlog.WithField(ctx, "btrfsinspect.rebuild-nodes.rebuild.process.item", item.keyAndTree)
o.curKey.TreeID = item.TreeID
o.curKey.Key.Val = item.Key
- handleItem(o, ctx, item.TreeID, btrfstree.Item{
+ btrfscheck.HandleItem(o, ctx, item.TreeID, btrfstree.Item{
Key: item.Key,
Body: item.Body,
})
diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_treecb.go b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_treecb.go
index 492436b..d58689c 100644
--- a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_treecb.go
+++ b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_treecb.go
@@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: GPL-2.0-or-later
-package rebuildnodes
+package rebuildtrees
import (
"context"
@@ -50,7 +50,7 @@ func (o *rebuilder) LookupRoot(ctx context.Context, tree btrfsprim.ObjID) (offse
case *btrfsitem.Root:
return btrfsprim.Generation(foundKey.Offset), *itemBody, true
case *btrfsitem.Error:
- o.fsErr(ctx, fmt.Errorf("error decoding item: %v: %w", foundKey, itemBody.Err))
+ o.FSErr(ctx, fmt.Errorf("error decoding item: %v: %w", foundKey, itemBody.Err))
return 0, btrfsitem.Root{}, false
default:
// This is a panic because the item decoder should not emit ROOT_ITEM items as anything but
@@ -76,7 +76,7 @@ func (o *rebuilder) LookupUUID(ctx context.Context, uuid btrfsprim.UUID) (id btr
case *btrfsitem.UUIDMap:
return itemBody.ObjID, true
case *btrfsitem.Error:
- o.fsErr(ctx, fmt.Errorf("error decoding item: %v: %w", wantKey, itemBody.Err))
+ o.FSErr(ctx, fmt.Errorf("error decoding item: %v: %w", wantKey, itemBody.Err))
return 0, false
default:
// This is a panic because the item decoder should not emit UUID_SUBVOL items as anything but
diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_wantcb.go b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_wantcb.go
index adf3cff..06be630 100644
--- a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_wantcb.go
+++ b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_wantcb.go
@@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: GPL-2.0-or-later
-package rebuildnodes
+package rebuildtrees
import (
"bytes"
@@ -15,17 +15,17 @@ import (
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsprim"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfssum"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect/rebuildnodes/keyio"
+ "git.lukeshu.com/btrfs-progs-ng/lib/btrfsutil"
"git.lukeshu.com/btrfs-progs-ng/lib/containers"
)
// fsErr implements rebuildCallbacks.
-func (o *rebuilder) fsErr(ctx context.Context, e error) {
+func (o *rebuilder) FSErr(ctx context.Context, e error) {
dlog.Errorf(ctx, "filesystem error: %v", e)
}
// want implements rebuildCallbacks.
-func (o *rebuilder) want(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, typ btrfsprim.ItemType) {
+func (o *rebuilder) Want(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, typ btrfsprim.ItemType) {
wantKey := WantWithTree{
TreeID: treeID,
Key: Want{
@@ -47,7 +47,7 @@ func (o *rebuilder) _want(ctx context.Context, wantKey WantWithTree) (key btrfsp
// check if we already have it
tgt := wantKey.Key.Key()
- if key, _, ok := o.rebuilt.Tree(ctx, wantKey.TreeID).Items(ctx).Search(func(key btrfsprim.Key, _ keyio.ItemPtr) int {
+ if key, _, ok := o.rebuilt.Tree(ctx, wantKey.TreeID).Items(ctx).Search(func(key btrfsprim.Key, _ btrfsutil.ItemPtr) int {
key.Offset = 0
return tgt.Compare(key)
}); ok {
@@ -61,11 +61,11 @@ func (o *rebuilder) _want(ctx context.Context, wantKey WantWithTree) (key btrfsp
}
wants := make(containers.Set[btrfsvol.LogicalAddr])
o.rebuilt.Tree(ctx, wantKey.TreeID).PotentialItems(ctx).Subrange(
- func(k btrfsprim.Key, _ keyio.ItemPtr) int {
+ func(k btrfsprim.Key, _ btrfsutil.ItemPtr) int {
k.Offset = 0
return tgt.Compare(k)
},
- func(_ btrfsprim.Key, v keyio.ItemPtr) bool {
+ func(_ btrfsprim.Key, v btrfsutil.ItemPtr) bool {
wants.InsertFrom(o.rebuilt.Tree(ctx, wantKey.TreeID).LeafToRoots(ctx, v.Node))
return true
})
@@ -74,7 +74,7 @@ func (o *rebuilder) _want(ctx context.Context, wantKey WantWithTree) (key btrfsp
}
// wantOff implements rebuildCallbacks.
-func (o *rebuilder) wantOff(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, typ btrfsprim.ItemType, off uint64) {
+func (o *rebuilder) WantOff(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, typ btrfsprim.ItemType, off uint64) {
wantKey := WantWithTree{
TreeID: treeID,
Key: Want{
@@ -108,8 +108,8 @@ func (o *rebuilder) _wantOff(ctx context.Context, wantKey WantWithTree) (ok bool
}
wants := make(containers.Set[btrfsvol.LogicalAddr])
o.rebuilt.Tree(ctx, wantKey.TreeID).PotentialItems(ctx).Subrange(
- func(k btrfsprim.Key, _ keyio.ItemPtr) int { return tgt.Compare(k) },
- func(_ btrfsprim.Key, v keyio.ItemPtr) bool {
+ func(k btrfsprim.Key, _ btrfsutil.ItemPtr) int { return tgt.Compare(k) },
+ func(_ btrfsprim.Key, v btrfsutil.ItemPtr) bool {
wants.InsertFrom(o.rebuilt.Tree(ctx, wantKey.TreeID).LeafToRoots(ctx, v.Node))
return true
})
@@ -118,7 +118,7 @@ func (o *rebuilder) _wantOff(ctx context.Context, wantKey WantWithTree) (ok bool
}
// wantDirIndex implements rebuildCallbacks.
-func (o *rebuilder) wantDirIndex(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, name []byte) {
+func (o *rebuilder) WantDirIndex(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, name []byte) {
wantKey := WantWithTree{
TreeID: treeID,
Key: Want{
@@ -140,11 +140,11 @@ func (o *rebuilder) wantDirIndex(ctx context.Context, reason string, treeID btrf
tgt := wantKey.Key.Key()
found := false
o.rebuilt.Tree(ctx, treeID).Items(ctx).Subrange(
- func(key btrfsprim.Key, _ keyio.ItemPtr) int {
+ func(key btrfsprim.Key, _ btrfsutil.ItemPtr) int {
key.Offset = 0
return tgt.Compare(key)
},
- func(_ btrfsprim.Key, ptr keyio.ItemPtr) bool {
+ func(_ btrfsprim.Key, ptr btrfsutil.ItemPtr) bool {
if itemName, ok := o.keyIO.Names[ptr]; ok && bytes.Equal(itemName, name) {
found = true
}
@@ -161,11 +161,11 @@ func (o *rebuilder) wantDirIndex(ctx context.Context, reason string, treeID btrf
}
wants := make(containers.Set[btrfsvol.LogicalAddr])
o.rebuilt.Tree(ctx, treeID).PotentialItems(ctx).Subrange(
- func(key btrfsprim.Key, _ keyio.ItemPtr) int {
+ func(key btrfsprim.Key, _ btrfsutil.ItemPtr) int {
key.Offset = 0
return tgt.Compare(key)
},
- func(_ btrfsprim.Key, ptr keyio.ItemPtr) bool {
+ func(_ btrfsprim.Key, ptr btrfsutil.ItemPtr) bool {
if itemName, ok := o.keyIO.Names[ptr]; ok && bytes.Equal(itemName, name) {
wants.InsertFrom(o.rebuilt.Tree(ctx, treeID).LeafToRoots(ctx, ptr.Node))
}
@@ -176,10 +176,10 @@ func (o *rebuilder) wantDirIndex(ctx context.Context, reason string, treeID btrf
func (o *rebuilder) _walkRange(
ctx context.Context,
- items *containers.SortedMap[btrfsprim.Key, keyio.ItemPtr],
+ items *containers.SortedMap[btrfsprim.Key, btrfsutil.ItemPtr],
treeID, objID btrfsprim.ObjID, typ btrfsprim.ItemType,
beg, end uint64,
- fn func(key btrfsprim.Key, ptr keyio.ItemPtr, beg, end uint64),
+ fn func(key btrfsprim.Key, ptr btrfsutil.ItemPtr, beg, end uint64),
) {
min := btrfsprim.Key{
ObjectID: objID,
@@ -192,7 +192,7 @@ func (o *rebuilder) _walkRange(
Offset: end - 1,
}
items.Subrange(
- func(runKey btrfsprim.Key, _ keyio.ItemPtr) int {
+ func(runKey btrfsprim.Key, _ btrfsutil.ItemPtr) int {
switch {
case min.Compare(runKey) < 0:
return 1
@@ -202,14 +202,14 @@ func (o *rebuilder) _walkRange(
return 0
}
},
- func(runKey btrfsprim.Key, runPtr keyio.ItemPtr) bool {
+ func(runKey btrfsprim.Key, runPtr btrfsutil.ItemPtr) bool {
runSizeAndErr, ok := o.keyIO.Sizes[runPtr]
if !ok {
panic(fmt.Errorf("should not happen: %v (%v) did not have a size recorded",
runPtr, keyAndTree{TreeID: treeID, Key: runKey}))
}
if runSizeAndErr.Err != nil {
- o.fsErr(ctx, fmt.Errorf("get size: %v (%v): %w",
+ o.FSErr(ctx, fmt.Errorf("get size: %v (%v): %w",
runPtr, keyAndTree{TreeID: treeID, Key: runKey},
runSizeAndErr.Err))
return true
@@ -273,7 +273,7 @@ func (o *rebuilder) _wantRange(
ctx,
o.rebuilt.Tree(ctx, treeID).Items(ctx),
treeID, objID, typ, beg, end,
- func(runKey btrfsprim.Key, _ keyio.ItemPtr, runBeg, runEnd uint64) {
+ func(runKey btrfsprim.Key, _ btrfsutil.ItemPtr, runBeg, runEnd uint64) {
var overlappingGaps []*containers.RBNode[gap]
gaps.Subrange(
func(gap gap) int {
@@ -324,7 +324,7 @@ func (o *rebuilder) _wantRange(
ctx,
potentialItems,
treeID, objID, typ, gap.Beg, gap.End,
- func(k btrfsprim.Key, v keyio.ItemPtr, runBeg, runEnd uint64) {
+ func(k btrfsprim.Key, v btrfsutil.ItemPtr, runBeg, runEnd uint64) {
// TODO: This is dumb and greedy.
if last < runBeg {
// log an error
@@ -353,7 +353,7 @@ func (o *rebuilder) _wantRange(
// func implements rebuildCallbacks.
//
// interval is [beg, end)
-func (o *rebuilder) wantCSum(ctx context.Context, reason string, inodeTree, inode btrfsprim.ObjID, beg, end btrfsvol.LogicalAddr) {
+func (o *rebuilder) WantCSum(ctx context.Context, reason string, inodeTree, inode btrfsprim.ObjID, beg, end btrfsvol.LogicalAddr) {
inodeWant := WantWithTree{
TreeID: inodeTree,
Key: Want{
@@ -377,7 +377,7 @@ func (o *rebuilder) wantCSum(ctx context.Context, reason string, inodeTree, inod
panic(fmt.Errorf("should not happen: INODE_ITEM did not have flags recorded"))
}
if inodeFlags.Err != nil {
- o.fsErr(inodeCtx, inodeFlags.Err)
+ o.FSErr(inodeCtx, inodeFlags.Err)
return
}
@@ -392,7 +392,7 @@ func (o *rebuilder) wantCSum(ctx context.Context, reason string, inodeTree, inod
}
// wantFileExt implements rebuildCallbacks.
-func (o *rebuilder) wantFileExt(ctx context.Context, reason string, treeID btrfsprim.ObjID, ino btrfsprim.ObjID, size int64) {
+func (o *rebuilder) WantFileExt(ctx context.Context, reason string, treeID btrfsprim.ObjID, ino btrfsprim.ObjID, size int64) {
o._wantRange(
ctx, reason,
treeID, ino, btrfsprim.EXTENT_DATA_KEY,
diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_wanttyp.go b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_wanttyp.go
index 2b471fe..fa1ba98 100644
--- a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_wanttyp.go
+++ b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_wanttyp.go
@@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: GPL-2.0-or-later
-package rebuildnodes
+package rebuildtrees
import (
"context"
diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/scan.go b/cmd/btrfs-rec/inspect/rebuildtrees/scan.go
index 17949ab..03261e0 100644
--- a/cmd/btrfs-rec/inspect/rebuildtrees/scan.go
+++ b/cmd/btrfs-rec/inspect/rebuildtrees/scan.go
@@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: GPL-2.0-or-later
-package rebuildnodes
+package rebuildtrees
import (
"context"
@@ -10,22 +10,21 @@ import (
"github.com/datawire/dlib/dlog"
+ "git.lukeshu.com/btrfs-progs-ng/cmd/btrfs-rec/inspect/rebuildmappings"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfstree"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect/rebuildnodes/graph"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect/rebuildnodes/keyio"
+ "git.lukeshu.com/btrfs-progs-ng/lib/btrfsutil"
"git.lukeshu.com/btrfs-progs-ng/lib/containers"
"git.lukeshu.com/btrfs-progs-ng/lib/maps"
"git.lukeshu.com/btrfs-progs-ng/lib/textui"
)
-func ScanDevices(ctx context.Context, fs *btrfs.FS, scanResults btrfsinspect.ScanDevicesResult) (btrfstree.Superblock, graph.Graph, *keyio.Handle, error) {
+func ScanDevices(ctx context.Context, fs *btrfs.FS, scanResults rebuildmappings.ScanDevicesResult) (btrfstree.Superblock, btrfsutil.Graph, *btrfsutil.KeyIO, error) {
dlog.Info(ctx, "Reading superblock...")
sb, err := fs.Superblock()
if err != nil {
- return btrfstree.Superblock{}, graph.Graph{}, nil, err
+ return btrfstree.Superblock{}, btrfsutil.Graph{}, nil, err
}
dlog.Infof(ctx, "Reading node data from FS...")
@@ -36,21 +35,21 @@ func ScanDevices(ctx context.Context, fs *btrfs.FS, scanResults btrfsinspect.Sca
dlog.WithField(ctx, "btrfsinspect.rebuild-nodes.read.substep", "read-nodes"),
dlog.LogLevelInfo, textui.Tunable(1*time.Second))
- nodeGraph := graph.New(*sb)
- keyIO := keyio.NewHandle(fs, *sb)
+ nodeGraph := btrfsutil.NewGraph(*sb)
+ keyIO := btrfsutil.NewKeyIO(fs, *sb)
progressWriter.Set(stats)
for _, devResults := range scanResults {
for _, laddr := range maps.SortedKeys(devResults.FoundNodes) {
if err := ctx.Err(); err != nil {
- return btrfstree.Superblock{}, graph.Graph{}, nil, err
+ return btrfstree.Superblock{}, btrfsutil.Graph{}, nil, err
}
nodeRef, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](fs, *sb, laddr, btrfstree.NodeExpectations{
LAddr: containers.Optional[btrfsvol.LogicalAddr]{OK: true, Val: laddr},
})
if err != nil {
btrfstree.FreeNodeRef(nodeRef)
- return btrfstree.Superblock{}, graph.Graph{}, nil, err
+ return btrfstree.Superblock{}, btrfsutil.Graph{}, nil, err
}
nodeGraph.InsertNode(nodeRef)
@@ -69,7 +68,7 @@ func ScanDevices(ctx context.Context, fs *btrfs.FS, scanResults btrfsinspect.Sca
dlog.Info(ctx, "... done reading node data")
if err := nodeGraph.FinalCheck(ctx, fs, *sb); err != nil {
- return btrfstree.Superblock{}, graph.Graph{}, nil, err
+ return btrfstree.Superblock{}, btrfsutil.Graph{}, nil, err
}
keyIO.SetGraph(*nodeGraph)
diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/util.go b/cmd/btrfs-rec/inspect/rebuildtrees/util.go
index 9d91f23..71caee0 100644
--- a/cmd/btrfs-rec/inspect/rebuildtrees/util.go
+++ b/cmd/btrfs-rec/inspect/rebuildtrees/util.go
@@ -1,16 +1,16 @@
-// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com>
+// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com>
//
// SPDX-License-Identifier: GPL-2.0-or-later
-package rebuildnodes
+package rebuildtrees
import (
"golang.org/x/exp/constraints"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect"
+ "git.lukeshu.com/btrfs-progs-ng/cmd/btrfs-rec/inspect/rebuildmappings"
)
-func countNodes(nodeScanResults btrfsinspect.ScanDevicesResult) int {
+func countNodes(nodeScanResults rebuildmappings.ScanDevicesResult) int {
var cnt int
for _, devResults := range nodeScanResults {
cnt += len(devResults.FoundNodes)