From 8e215721b38972c522b692032bf1c516eb62359f Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 5 Apr 2023 10:10:34 -0600 Subject: btrfstree: Do a better job of checking node ownership This now considers the interior nodes *between* the root and the leaf, instead of just considering the root and the leaf. --- lib/btrfsutil/old_rebuilt_forrest.go | 79 +++++++++++------------------------- 1 file changed, 24 insertions(+), 55 deletions(-) (limited to 'lib/btrfsutil/old_rebuilt_forrest.go') diff --git a/lib/btrfsutil/old_rebuilt_forrest.go b/lib/btrfsutil/old_rebuilt_forrest.go index 0a3106d..b03ddc2 100644 --- a/lib/btrfsutil/old_rebuilt_forrest.go +++ b/lib/btrfsutil/old_rebuilt_forrest.go @@ -367,7 +367,7 @@ func (tree oldRebuiltTree) TreeWalk(ctx context.Context, cbs btrfstree.TreeWalkH if cbs.Node != nil && !visitedNodes.Has(indexItem.Value.Node.LAddr) { nodePath := btrfstree.Path{ btrfstree.PathRoot{ - Tree: tree, + Forrest: tree.forrest, TreeID: tree.ID, ToAddr: indexItem.Value.Node.LAddr, ToGeneration: indexItem.Value.Node.Generation, @@ -386,7 +386,7 @@ func (tree oldRebuiltTree) TreeWalk(ctx context.Context, cbs btrfstree.TreeWalkH item := node.BodyLeaf[indexItem.Value.Slot] itemPath := btrfstree.Path{ btrfstree.PathRoot{ - Tree: tree, + Forrest: tree.forrest, TreeID: tree.ID, ToAddr: indexItem.Value.Node.LAddr, ToGeneration: indexItem.Value.Node.Generation, @@ -418,59 +418,28 @@ func (tree oldRebuiltTree) TreeWalk(ctx context.Context, cbs btrfstree.TreeWalkH tree.forrest.ReleaseNode(node) } -// TreeCheckOwner implements btrfstree.Tree. -func (tree oldRebuiltTree) TreeCheckOwner(ctx context.Context, failOpen bool, owner btrfsprim.ObjID, gen btrfsprim.Generation) error { - var uuidTree oldRebuiltTree - for { - // Main. - if owner == tree.ID { - return nil - } - if tree.ParentUUID == (btrfsprim.UUID{}) { - return fmt.Errorf("owner=%v is not acceptable in this tree", - owner) - } - if gen > tree.ParentGen { - return fmt.Errorf("claimed owner=%v might be acceptable in this tree (if generation<=%v) but not with claimed generation=%v", - owner, tree.ParentGen, gen) - } - - // Loop update. - if uuidTree.forrest == nil { - uuidTree = tree.forrest.RebuiltTree(ctx, btrfsprim.UUID_TREE_OBJECTID) - if uuidTree.RootErr != nil { - return nil //nolint:nilerr // fail open - } - } - parentIDItem, err := uuidTree.TreeLookup(ctx, btrfsitem.UUIDToKey(tree.ParentUUID)) - if err != nil { - if failOpen { - return nil - } - return fmt.Errorf("unable to determine whether owner=%v generation=%v is acceptable: %w", - owner, gen, err) - } - switch parentIDBody := parentIDItem.Body.(type) { - case *btrfsitem.UUIDMap: - tree = tree.forrest.RebuiltTree(ctx, parentIDBody.ObjID) - if tree.RootErr != nil { - if failOpen { - return nil - } - return fmt.Errorf("unable to determine whether owner=%v generation=%v is acceptable: %w", - owner, gen, tree.RootErr) - } - case *btrfsitem.Error: - if failOpen { - return nil - } - return fmt.Errorf("unable to determine whether owner=%v generation=%v is acceptable: %w", - owner, gen, parentIDBody.Err) - default: - // This is a panic because the item decoder should not emit UUID_SUBVOL items as anything but - // btrfsitem.UUIDMap or btrfsitem.Error without this code also being updated. - panic(fmt.Errorf("should not happen: UUID_SUBVOL item has unexpected type: %T", parentIDBody)) - } +// TreeParentID implements btrfstree.Tree. +func (tree oldRebuiltTree) TreeParentID(ctx context.Context) (btrfsprim.ObjID, btrfsprim.Generation, error) { + if tree.ParentUUID == (btrfsprim.UUID{}) { + return 0, 0, nil + } + uuidTree := tree.forrest.RebuiltTree(ctx, btrfsprim.UUID_TREE_OBJECTID) + if uuidTree.RootErr != nil { + return 0, 0, uuidTree.RootErr + } + parentIDItem, err := uuidTree.TreeLookup(ctx, btrfsitem.UUIDToKey(tree.ParentUUID)) + if err != nil { + return 0, 0, err + } + switch parentIDBody := parentIDItem.Body.(type) { + case *btrfsitem.UUIDMap: + return parentIDBody.ObjID, tree.ParentGen, nil + case *btrfsitem.Error: + return 0, 0, parentIDBody.Err + default: + // This is a panic because the item decoder should not emit UUID_SUBVOL items as anything but + // btrfsitem.UUIDMap or btrfsitem.Error without this code also being updated. + panic(fmt.Errorf("should not happen: UUID_SUBVOL item has unexpected type: %T", parentIDBody)) } } -- cgit v1.2.3-2-g168b