From 05e621c0c47e65665042f1977ec69927c1bbde12 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 1 Jan 2023 12:36:22 -0700 Subject: rebuildnodes: Check for INODE_NODATASUM before looking for csums --- .../btrfsinspect/rebuildnodes/rebuild.go | 41 +++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) (limited to 'lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go') diff --git a/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go b/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go index a3fd0e7..08ab81a 100644 --- a/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go +++ b/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go @@ -18,6 +18,7 @@ import ( "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/btrfssum" "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" @@ -814,11 +815,43 @@ func (o *rebuilder) _wantRange( // func implements rebuildCallbacks. // // interval is [beg, end) -func (o *rebuilder) wantCSum(ctx context.Context, reason string, beg, end btrfsvol.LogicalAddr) { +func (o *rebuilder) wantCSum(ctx context.Context, reason string, inodeTree, inode btrfsprim.ObjID, beg, end btrfsvol.LogicalAddr) { ctx = dlog.WithField(ctx, "btrfsinspect.rebuild-nodes.rebuild.want.reason", reason) - const treeID = btrfsprim.CSUM_TREE_OBJECTID - o._wantRange(ctx, treeID, btrfsprim.EXTENT_CSUM_OBJECTID, btrfsprim.EXTENT_CSUM_KEY, - uint64(beg), uint64(end)) + + inodeKey := keyAndTree{ + TreeID: inodeTree, + Key: btrfsprim.Key{ + ObjectID: inode, + ItemType: btrfsitem.INODE_ITEM_KEY, + Offset: 0, + }, + } + inodeCtx := dlog.WithField(ctx, "btrfsinspect.rebuild-nodes.rebuild.want.key", inodeKey.String()) + if !o._wantOff(inodeCtx, inodeKey.TreeID, inodeKey.String(), inodeKey.Key) { + o.itemQueue.Insert(o.curKey) + return + } + inodeBody, ok := o.rebuilt.Tree(inodeCtx, inodeKey.TreeID).ReadItem(inodeCtx, inodeKey.Key) + if !ok { + o.ioErr(inodeCtx, fmt.Errorf("could not read previously read item: %v", inodeKey)) + } + switch inodeBody := inodeBody.(type) { + case btrfsitem.Inode: + if inodeBody.Flags.Has(btrfsitem.INODE_NODATASUM) { + return + } + beg = roundDown(beg, btrfssum.BlockSize) + end = roundUp(end, btrfssum.BlockSize) + const treeID = btrfsprim.CSUM_TREE_OBJECTID + o._wantRange(ctx, treeID, btrfsprim.EXTENT_CSUM_OBJECTID, btrfsprim.EXTENT_CSUM_KEY, + uint64(beg), uint64(end)) + case btrfsitem.Error: + o.fsErr(inodeCtx, fmt.Errorf("error decoding item: %v: %w", inodeKey, inodeBody.Err)) + default: + // This is a panic because the item decoder should not emit INODE_ITEM items as anything but + // btrfsitem.Inode or btrfsitem.Error without this code also being updated. + panic(fmt.Errorf("should not happen: INODE_ITEM item has unexpected type: %T", inodeBody)) + } } // wantFileExt implements rebuildCallbacks. -- cgit v1.2.3-2-g168b