From 1bc243ca607c22e232017b0f1b4badcde288a9b3 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Thu, 16 Mar 2023 09:17:35 -0600 Subject: btrfstree: Have ReadNode return a *Node rather than a *diskio.Ref[Addr, Node] ... and take a ReaderAt instead of a diskio.File. --- cmd/btrfs-rec/inspect/rebuildtrees/scan.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'cmd/btrfs-rec/inspect/rebuildtrees/scan.go') diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/scan.go b/cmd/btrfs-rec/inspect/rebuildtrees/scan.go index ba56c5b..4bc09ad 100644 --- a/cmd/btrfs-rec/inspect/rebuildtrees/scan.go +++ b/cmd/btrfs-rec/inspect/rebuildtrees/scan.go @@ -41,18 +41,18 @@ func ScanDevices(ctx context.Context, fs *btrfs.FS, nodeList []btrfsvol.LogicalA if err := ctx.Err(); err != nil { return btrfstree.Superblock{}, btrfsutil.Graph{}, nil, err } - nodeRef, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](fs, *sb, laddr, btrfstree.NodeExpectations{ + node, 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) + node.Free() return btrfstree.Superblock{}, btrfsutil.Graph{}, nil, err } - nodeGraph.InsertNode(nodeRef) - keyIO.InsertNode(nodeRef) + nodeGraph.InsertNode(node) + keyIO.InsertNode(node) - btrfstree.FreeNodeRef(nodeRef) + node.Free() stats.N++ progressWriter.Set(stats) -- cgit v1.2.3-2-g168b From d7a616119a4f5fbfa8d0f028e337037a48272048 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 28 Feb 2023 23:50:32 -0700 Subject: rebuildtrees: Move item-data from btrfsutil.KeyIO to scan --- cmd/btrfs-rec/inspect/rebuildtrees/scan.go | 97 ++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 12 deletions(-) (limited to 'cmd/btrfs-rec/inspect/rebuildtrees/scan.go') diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/scan.go b/cmd/btrfs-rec/inspect/rebuildtrees/scan.go index 4bc09ad..961ff8d 100644 --- a/cmd/btrfs-rec/inspect/rebuildtrees/scan.go +++ b/cmd/btrfs-rec/inspect/rebuildtrees/scan.go @@ -6,11 +6,14 @@ package rebuildtrees import ( "context" + "fmt" "time" "github.com/datawire/dlib/dlog" "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/btrfsutil" @@ -18,11 +21,31 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/textui" ) -func ScanDevices(ctx context.Context, fs *btrfs.FS, nodeList []btrfsvol.LogicalAddr) (btrfstree.Superblock, btrfsutil.Graph, *btrfsutil.KeyIO, error) { +type SizeAndErr struct { + Size uint64 + Err error +} + +type FlagsAndErr struct { + NoDataSum bool + Err error +} + +type ScanDevicesResult struct { + Superblock btrfstree.Superblock + + Graph btrfsutil.Graph + + Flags map[btrfsutil.ItemPtr]FlagsAndErr // INODE_ITEM + Names map[btrfsutil.ItemPtr][]byte // DIR_INDEX + Sizes map[btrfsutil.ItemPtr]SizeAndErr // EXTENT_CSUM and EXTENT_DATA +} + +func ScanDevices(ctx context.Context, fs *btrfs.FS, nodeList []btrfsvol.LogicalAddr) (ScanDevicesResult, error) { dlog.Info(ctx, "Reading superblock...") sb, err := fs.Superblock() if err != nil { - return btrfstree.Superblock{}, btrfsutil.Graph{}, nil, err + return ScanDevicesResult{}, err } dlog.Infof(ctx, "Reading node data from FS...") @@ -33,24 +56,30 @@ func ScanDevices(ctx context.Context, fs *btrfs.FS, nodeList []btrfsvol.LogicalA dlog.WithField(ctx, "btrfs.inspect.rebuild-trees.read.substep", "read-nodes"), dlog.LogLevelInfo, textui.Tunable(1*time.Second)) - nodeGraph := btrfsutil.NewGraph(*sb) - keyIO := btrfsutil.NewKeyIO(fs, *sb) + ret := ScanDevicesResult{ + Superblock: *sb, + + Graph: btrfsutil.NewGraph(*sb), + + Flags: make(map[btrfsutil.ItemPtr]FlagsAndErr), + Names: make(map[btrfsutil.ItemPtr][]byte), + Sizes: make(map[btrfsutil.ItemPtr]SizeAndErr), + } progressWriter.Set(stats) for _, laddr := range nodeList { if err := ctx.Err(); err != nil { - return btrfstree.Superblock{}, btrfsutil.Graph{}, nil, err + return ScanDevicesResult{}, err } node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](fs, *sb, laddr, btrfstree.NodeExpectations{ LAddr: containers.Optional[btrfsvol.LogicalAddr]{OK: true, Val: laddr}, }) if err != nil { node.Free() - return btrfstree.Superblock{}, btrfsutil.Graph{}, nil, err + return ScanDevicesResult{}, err } - nodeGraph.InsertNode(node) - keyIO.InsertNode(node) + ret.insertNode(node) node.Free() @@ -64,10 +93,54 @@ func ScanDevices(ctx context.Context, fs *btrfs.FS, nodeList []btrfsvol.LogicalA dlog.Info(ctx, "... done reading node data") ctx = dlog.WithField(ctx, "btrfs.inspect.rebuild-trees.read.substep", "check") - if err := nodeGraph.FinalCheck(ctx, fs, *sb); err != nil { - return btrfstree.Superblock{}, btrfsutil.Graph{}, nil, err + if err := ret.Graph.FinalCheck(ctx, fs, *sb); err != nil { + return ScanDevicesResult{}, err } - keyIO.SetGraph(*nodeGraph) - return *sb, *nodeGraph, keyIO, nil + return ret, nil +} + +func (o *ScanDevicesResult) insertNode(node *btrfstree.Node) { + o.Graph.InsertNode(node) + for i, item := range node.BodyLeaf { + ptr := btrfsutil.ItemPtr{ + Node: node.Head.Addr, + Slot: i, + } + switch itemBody := item.Body.(type) { + case *btrfsitem.Inode: + o.Flags[ptr] = FlagsAndErr{ + NoDataSum: itemBody.Flags.Has(btrfsitem.INODE_NODATASUM), + Err: nil, + } + case *btrfsitem.DirEntry: + if item.Key.ItemType == btrfsprim.DIR_INDEX_KEY { + o.Names[ptr] = append([]byte(nil), itemBody.Name...) + } + case *btrfsitem.ExtentCSum: + o.Sizes[ptr] = SizeAndErr{ + Size: uint64(itemBody.Size()), + Err: nil, + } + case *btrfsitem.FileExtent: + size, err := itemBody.Size() + o.Sizes[ptr] = SizeAndErr{ + Size: uint64(size), + Err: err, + } + case *btrfsitem.Error: + switch item.Key.ItemType { + case btrfsprim.INODE_ITEM_KEY: + o.Flags[ptr] = FlagsAndErr{ + Err: fmt.Errorf("error decoding item: ptr=%v (tree=%v key=%v): %w", + ptr, node.Head.Owner, item.Key, itemBody.Err), + } + case btrfsprim.EXTENT_CSUM_KEY, btrfsprim.EXTENT_DATA_KEY: + o.Sizes[ptr] = SizeAndErr{ + Err: fmt.Errorf("error decoding item: ptr=%v (tree=%v key=%v): %w", + ptr, node.Head.Owner, item.Key, itemBody.Err), + } + } + } + } } -- cgit v1.2.3-2-g168b From 33de7f09d31063ef2a4380bb2f2692653a6de06c Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Thu, 9 Mar 2023 16:43:39 -0700 Subject: containers: Add OptionalValue and OptionalNil --- cmd/btrfs-rec/inspect/rebuildtrees/scan.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmd/btrfs-rec/inspect/rebuildtrees/scan.go') diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/scan.go b/cmd/btrfs-rec/inspect/rebuildtrees/scan.go index 961ff8d..ada9f6f 100644 --- a/cmd/btrfs-rec/inspect/rebuildtrees/scan.go +++ b/cmd/btrfs-rec/inspect/rebuildtrees/scan.go @@ -72,7 +72,7 @@ func ScanDevices(ctx context.Context, fs *btrfs.FS, nodeList []btrfsvol.LogicalA return ScanDevicesResult{}, err } node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](fs, *sb, laddr, btrfstree.NodeExpectations{ - LAddr: containers.Optional[btrfsvol.LogicalAddr]{OK: true, Val: laddr}, + LAddr: containers.OptionalValue(laddr), }) if err != nil { node.Free() -- cgit v1.2.3-2-g168b