From 5f45fa7d378edae2fac73517384749fc73d24e89 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 28 Feb 2023 20:33:28 -0700 Subject: tree-wide: Don't pass around a full rebuildmappings.ScanDevicesResult when a simple list of nodes will do --- cmd/btrfs-rec/inspect/rebuildtrees/rebuild.go | 5 ++-- cmd/btrfs-rec/inspect/rebuildtrees/scan.go | 40 +++++++++++-------------- cmd/btrfs-rec/inspect/rebuildtrees/util.go | 10 ------- cmd/btrfs-rec/inspect_lstrees.go | 43 +++++++++++---------------- cmd/btrfs-rec/inspect_rebuildtrees.go | 10 ++----- cmd/btrfs-rec/inspect_scandevices.go | 25 ++++++++++++++++ 6 files changed, 66 insertions(+), 67 deletions(-) diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild.go b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild.go index bbfcdde..708b504 100644 --- a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild.go +++ b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild.go @@ -14,7 +14,6 @@ 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" @@ -74,9 +73,9 @@ type Rebuilder interface { ListRoots(context.Context) map[btrfsprim.ObjID]containers.Set[btrfsvol.LogicalAddr] } -func NewRebuilder(ctx context.Context, fs *btrfs.FS, nodeScanResults rebuildmappings.ScanDevicesResult) (Rebuilder, error) { +func NewRebuilder(ctx context.Context, fs *btrfs.FS, nodeList []btrfsvol.LogicalAddr) (Rebuilder, error) { ctx = dlog.WithField(ctx, "btrfs.inspect.rebuild-trees.step", "read-fs-data") - sb, nodeGraph, keyIO, err := ScanDevices(ctx, fs, nodeScanResults) // ScanDevices does its own logging + sb, nodeGraph, keyIO, err := ScanDevices(ctx, fs, nodeList) // ScanDevices does its own logging if err != nil { return nil, err } diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/scan.go b/cmd/btrfs-rec/inspect/rebuildtrees/scan.go index 2995a2e..ba56c5b 100644 --- a/cmd/btrfs-rec/inspect/rebuildtrees/scan.go +++ b/cmd/btrfs-rec/inspect/rebuildtrees/scan.go @@ -10,17 +10,15 @@ 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/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 rebuildmappings.ScanDevicesResult) (btrfstree.Superblock, btrfsutil.Graph, *btrfsutil.KeyIO, error) { +func ScanDevices(ctx context.Context, fs *btrfs.FS, nodeList []btrfsvol.LogicalAddr) (btrfstree.Superblock, btrfsutil.Graph, *btrfsutil.KeyIO, error) { dlog.Info(ctx, "Reading superblock...") sb, err := fs.Superblock() if err != nil { @@ -30,7 +28,7 @@ func ScanDevices(ctx context.Context, fs *btrfs.FS, scanResults rebuildmappings. dlog.Infof(ctx, "Reading node data from FS...") var stats textui.Portion[int] - stats.D = countNodes(scanResults) + stats.D = len(nodeList) progressWriter := textui.NewProgress[textui.Portion[int]]( dlog.WithField(ctx, "btrfs.inspect.rebuild-trees.read.substep", "read-nodes"), dlog.LogLevelInfo, textui.Tunable(1*time.Second)) @@ -39,27 +37,25 @@ func ScanDevices(ctx context.Context, fs *btrfs.FS, scanResults rebuildmappings. 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{}, 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{}, btrfsutil.Graph{}, nil, err - } + for _, laddr := range nodeList { + if err := ctx.Err(); err != nil { + 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{}, btrfsutil.Graph{}, nil, err + } - nodeGraph.InsertNode(nodeRef) - keyIO.InsertNode(nodeRef) + nodeGraph.InsertNode(nodeRef) + keyIO.InsertNode(nodeRef) - btrfstree.FreeNodeRef(nodeRef) + btrfstree.FreeNodeRef(nodeRef) - stats.N++ - progressWriter.Set(stats) - } + stats.N++ + progressWriter.Set(stats) } if stats.N != stats.D { panic("should not happen") diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/util.go b/cmd/btrfs-rec/inspect/rebuildtrees/util.go index 71caee0..842fb55 100644 --- a/cmd/btrfs-rec/inspect/rebuildtrees/util.go +++ b/cmd/btrfs-rec/inspect/rebuildtrees/util.go @@ -6,18 +6,8 @@ package rebuildtrees import ( "golang.org/x/exp/constraints" - - "git.lukeshu.com/btrfs-progs-ng/cmd/btrfs-rec/inspect/rebuildmappings" ) -func countNodes(nodeScanResults rebuildmappings.ScanDevicesResult) int { - var cnt int - for _, devResults := range nodeScanResults { - cnt += len(devResults.FoundNodes) - } - return cnt -} - func roundDown[T constraints.Integer](n, d T) T { return (n / d) * d } diff --git a/cmd/btrfs-rec/inspect_lstrees.go b/cmd/btrfs-rec/inspect_lstrees.go index df2473c..0c82fe0 100644 --- a/cmd/btrfs-rec/inspect_lstrees.go +++ b/cmd/btrfs-rec/inspect_lstrees.go @@ -12,7 +12,6 @@ import ( "github.com/datawire/ocibuild/pkg/cliutil" "github.com/spf13/cobra" - "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" @@ -36,13 +35,9 @@ func init() { }, RunE: func(fs *btrfs.FS, cmd *cobra.Command, _ []string) error { ctx := cmd.Context() - var scanResults rebuildmappings.ScanDevicesResult - if scandevicesFilename != "" { - var err error - scanResults, err = readJSONFile[rebuildmappings.ScanDevicesResult](ctx, scandevicesFilename) - if err != nil { - return err - } + nodeList, err := readNodeList(ctx, scandevicesFilename) + if err != nil { + return err } var treeErrCnt int @@ -98,23 +93,21 @@ func init() { treeItemCnt = make(map[btrfsitem.Type]int) textui.Fprintf(os.Stdout, "lost+found\n") sb, _ := fs.Superblock() - for _, devResults := range scanResults { - for laddr := range devResults.FoundNodes { - if visitedNodes.Has(laddr) { - continue - } - visitedNodes.Insert(laddr) - node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](fs, *sb, laddr, btrfstree.NodeExpectations{ - LAddr: containers.Optional[btrfsvol.LogicalAddr]{OK: true, Val: laddr}, - }) - if err != nil { - treeErrCnt++ - continue - } - for _, item := range node.Data.BodyLeaf { - typ := item.Key.ItemType - treeItemCnt[typ]++ - } + for _, laddr := range nodeList { + if visitedNodes.Has(laddr) { + continue + } + visitedNodes.Insert(laddr) + node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](fs, *sb, laddr, btrfstree.NodeExpectations{ + LAddr: containers.Optional[btrfsvol.LogicalAddr]{OK: true, Val: laddr}, + }) + if err != nil { + treeErrCnt++ + continue + } + for _, item := range node.Data.BodyLeaf { + typ := item.Key.ItemType + treeItemCnt[typ]++ } } flush() diff --git a/cmd/btrfs-rec/inspect_rebuildtrees.go b/cmd/btrfs-rec/inspect_rebuildtrees.go index 0b41dd9..5d782cf 100644 --- a/cmd/btrfs-rec/inspect_rebuildtrees.go +++ b/cmd/btrfs-rec/inspect_rebuildtrees.go @@ -15,7 +15,6 @@ import ( "github.com/datawire/ocibuild/pkg/cliutil" "github.com/spf13/cobra" - "git.lukeshu.com/btrfs-progs-ng/cmd/btrfs-rec/inspect/rebuildmappings" "git.lukeshu.com/btrfs-progs-ng/cmd/btrfs-rec/inspect/rebuildtrees" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" "git.lukeshu.com/btrfs-progs-ng/lib/textui" @@ -30,17 +29,14 @@ func init() { RunE: func(fs *btrfs.FS, cmd *cobra.Command, args []string) error { ctx := cmd.Context() - // This is wrapped in a func in order to *ensure* that `nodeScanResults` goes out of scope once + // This is wrapped in a func in order to *ensure* that `nodeList` goes out of scope once // `rebuilder` has been created. rebuilder, err := func(ctx context.Context) (rebuildtrees.Rebuilder, error) { - dlog.Infof(ctx, "Reading %q...", args[0]) - nodeScanResults, err := readJSONFile[rebuildmappings.ScanDevicesResult](ctx, args[0]) + nodeList, err := readNodeList(ctx, args[0]) if err != nil { return nil, err } - dlog.Infof(ctx, "... done reading %q", args[0]) - - return rebuildtrees.NewRebuilder(ctx, fs, nodeScanResults) + return rebuildtrees.NewRebuilder(ctx, fs, nodeList) }(ctx) if err != nil { return err diff --git a/cmd/btrfs-rec/inspect_scandevices.go b/cmd/btrfs-rec/inspect_scandevices.go index 0542d6a..f93d99d 100644 --- a/cmd/btrfs-rec/inspect_scandevices.go +++ b/cmd/btrfs-rec/inspect_scandevices.go @@ -5,6 +5,7 @@ package main import ( + "context" "os" "git.lukeshu.com/go/lowmemjson" @@ -14,6 +15,9 @@ import ( "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/btrfsvol" + "git.lukeshu.com/btrfs-progs-ng/lib/containers" + "git.lukeshu.com/btrfs-progs-ng/lib/maps" ) func init() { @@ -44,3 +48,24 @@ func init() { }, }) } + +func readNodeList(ctx context.Context, filename string) ([]btrfsvol.LogicalAddr, error) { + if filename == "" { + return nil, nil + } + results, err := readJSONFile[rebuildmappings.ScanDevicesResult](ctx, filename) + if err != nil { + return nil, err + } + var cnt int + for _, devResults := range results { + cnt += len(devResults.FoundNodes) + } + set := make(containers.Set[btrfsvol.LogicalAddr], cnt) + for _, devResults := range results { + for laddr := range devResults.FoundNodes { + set.Insert(laddr) + } + } + return maps.SortedKeys(set), nil +} -- cgit v1.2.3-2-g168b