From 6b521d08bbb75430432834e5fcd2cb1da3de1e2e Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 17 Apr 2023 18:21:04 -0600 Subject: btrfsutil: RebuiltForrest: Have LookupRoot return an error --- cmd/btrfs-rec/inspect/rebuildtrees/rebuild_treecb.go | 8 ++++---- lib/btrfsutil/rebuilt_callbacks.go | 12 ++++++------ lib/btrfsutil/rebuilt_forrest.go | 6 +++--- lib/btrfsutil/rebuilt_forrest_test.go | 20 ++++++++++---------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_treecb.go b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_treecb.go index cfef623..b8205ae 100644 --- a/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_treecb.go +++ b/cmd/btrfs-rec/inspect/rebuildtrees/rebuild_treecb.go @@ -37,7 +37,7 @@ func (o forrestCallbacks) AddedRoot(_ context.Context, tree btrfsprim.ObjID, _ b } // LookupRoot implements btrfsutil.RebuiltForrestCallbacks. -func (o forrestCallbacks) LookupRoot(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, _item btrfsitem.Root, ok bool) { +func (o forrestCallbacks) LookupRoot(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, _item btrfsitem.Root, err error) { wantKey := wantWithTree{ TreeID: btrfsprim.ROOT_TREE_OBJECTID, Key: want{ @@ -50,16 +50,16 @@ func (o forrestCallbacks) LookupRoot(ctx context.Context, tree btrfsprim.ObjID) foundKey, ok := o._want(ctx, wantKey) if !ok { o.enqueueRetry(btrfsprim.ROOT_TREE_OBJECTID) - return 0, btrfsitem.Root{}, false + return 0, btrfsitem.Root{}, btrfstree.ErrNoItem } item, _ := discardErr(o.rebuilt.RebuiltTree(ctx, wantKey.TreeID)).TreeLookup(ctx, foundKey) defer item.Body.Free() switch itemBody := item.Body.(type) { case *btrfsitem.Root: - return btrfsprim.Generation(foundKey.Offset), *itemBody, true + return btrfsprim.Generation(foundKey.Offset), *itemBody, nil case *btrfsitem.Error: graphCallbacks(o).FSErr(ctx, fmt.Errorf("error decoding item: %v: %w", foundKey, itemBody.Err)) - return 0, btrfsitem.Root{}, false + return 0, btrfsitem.Root{}, itemBody.Err default: // This is a panic because the item decoder should not emit ROOT_ITEM items as anything but // btrfsitem.Root or btrfsitem.Error without this code also being updated. diff --git a/lib/btrfsutil/rebuilt_callbacks.go b/lib/btrfsutil/rebuilt_callbacks.go index 9ed3177..b5fbc91 100644 --- a/lib/btrfsutil/rebuilt_callbacks.go +++ b/lib/btrfsutil/rebuilt_callbacks.go @@ -16,7 +16,7 @@ import ( type RebuiltForrestCallbacks interface { AddedRoot(ctx context.Context, tree btrfsprim.ObjID, root btrfsvol.LogicalAddr) - LookupRoot(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, item btrfsitem.Root, ok bool) + LookupRoot(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, item btrfsitem.Root, err error) LookupUUID(ctx context.Context, uuid btrfsprim.UUID) (id btrfsprim.ObjID, err error) } @@ -32,21 +32,21 @@ type noopRebuiltForrestCallbacks struct { func (noopRebuiltForrestCallbacks) AddedRoot(context.Context, btrfsprim.ObjID, btrfsvol.LogicalAddr) { } -func (cb noopRebuiltForrestCallbacks) LookupRoot(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, _item btrfsitem.Root, ok bool) { +func (cb noopRebuiltForrestCallbacks) LookupRoot(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, _item btrfsitem.Root, err error) { rootTree, err := cb.forrest.ForrestLookup(ctx, btrfsprim.ROOT_TREE_OBJECTID) if err != nil { - return 0, btrfsitem.Root{}, false + return 0, btrfsitem.Root{}, err } item, err := rootTree.TreeSearch(ctx, btrfstree.SearchRootItem(tree)) if err != nil { - return 0, btrfsitem.Root{}, false + return 0, btrfsitem.Root{}, err } defer item.Body.Free() switch itemBody := item.Body.(type) { case *btrfsitem.Root: - return btrfsprim.Generation(item.Key.Offset), *itemBody, true + return btrfsprim.Generation(item.Key.Offset), *itemBody, nil case *btrfsitem.Error: - return 0, btrfsitem.Root{}, false + return 0, btrfsitem.Root{}, itemBody.Err default: // This is a panic because the item decoder should not emit ROOT_ITEM items as anything but // btrfsitem.Root or btrfsitem.Error without this code also being updated. diff --git a/lib/btrfsutil/rebuilt_forrest.go b/lib/btrfsutil/rebuilt_forrest.go index 3c53af7..3e40103 100644 --- a/lib/btrfsutil/rebuilt_forrest.go +++ b/lib/btrfsutil/rebuilt_forrest.go @@ -212,9 +212,9 @@ func (ts *RebuiltForrest) rebuildTree(ctx context.Context, treeID btrfsprim.ObjI sb, _ := ts.Superblock() ts.trees[treeID].Root = sb.BlockGroupRoot default: - rootOff, rootItem, ok := ts.cb.LookupRoot(ctx, treeID) - if !ok { - ts.trees[treeID].rootErr = btrfstree.ErrNoTree + rootOff, rootItem, err := ts.cb.LookupRoot(ctx, treeID) + if err != nil { + ts.trees[treeID].rootErr = fmt.Errorf("%w: %s", btrfstree.ErrNoTree, err) return } ts.trees[treeID].Root = rootItem.ByteNr diff --git a/lib/btrfsutil/rebuilt_forrest_test.go b/lib/btrfsutil/rebuilt_forrest_test.go index ef0ed72..86ae9a7 100644 --- a/lib/btrfsutil/rebuilt_forrest_test.go +++ b/lib/btrfsutil/rebuilt_forrest_test.go @@ -20,7 +20,7 @@ import ( type rebuiltForrestCallbacks struct { addedItem func(ctx context.Context, tree btrfsprim.ObjID, key btrfsprim.Key) addedRoot func(ctx context.Context, tree btrfsprim.ObjID, root btrfsvol.LogicalAddr) - lookupRoot func(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, item btrfsitem.Root, ok bool) + lookupRoot func(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, item btrfsitem.Root, err error) lookupUUID func(ctx context.Context, uuid btrfsprim.UUID) (id btrfsprim.ObjID, err error) } @@ -32,7 +32,7 @@ func (cbs rebuiltForrestCallbacks) AddedRoot(ctx context.Context, tree btrfsprim cbs.addedRoot(ctx, tree, root) } -func (cbs rebuiltForrestCallbacks) LookupRoot(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, item btrfsitem.Root, ok bool) { +func (cbs rebuiltForrestCallbacks) LookupRoot(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, item btrfsitem.Root, err error) { return cbs.lookupRoot(ctx, tree) } @@ -85,17 +85,17 @@ func TestRebuiltTreeCycles(t *testing.T) { addedRoot: func(ctx context.Context, tree btrfsprim.ObjID, root btrfsvol.LogicalAddr) { // do nothing }, - lookupRoot: func(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, item btrfsitem.Root, ok bool) { + lookupRoot: func(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, item btrfsitem.Root, err error) { for _, root := range roots { if root.ID == tree { return root.ParentGen, btrfsitem.Root{ Generation: 2000, UUID: root.UUID, ParentUUID: root.ParentUUID, - }, true + }, nil } } - return 0, btrfsitem.Root{}, false + return 0, btrfsitem.Root{}, btrfstree.ErrNoItem }, lookupUUID: func(ctx context.Context, uuid btrfsprim.UUID) (id btrfsprim.ObjID, err error) { for _, root := range roots { @@ -194,10 +194,10 @@ func TestRebuiltTreeParentErr(t *testing.T) { addedRoot: func(ctx context.Context, tree btrfsprim.ObjID, root btrfsvol.LogicalAddr) { // do nothing }, - lookupRoot: func(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, item btrfsitem.Root, ok bool) { + lookupRoot: func(ctx context.Context, tree btrfsprim.ObjID) (offset btrfsprim.Generation, item btrfsitem.Root, err error) { if tree == 304 { // Force a fault. - return 0, btrfsitem.Root{}, false + return 0, btrfsitem.Root{}, btrfstree.ErrNoItem } for _, root := range roots { if root.ID == tree { @@ -205,10 +205,10 @@ func TestRebuiltTreeParentErr(t *testing.T) { Generation: 2000, UUID: root.UUID, ParentUUID: root.ParentUUID, - }, true + }, nil } } - return 0, btrfsitem.Root{}, false + return 0, btrfsitem.Root{}, btrfstree.ErrNoItem }, lookupUUID: func(ctx context.Context, uuid btrfsprim.UUID) (id btrfsprim.ObjID, err error) { for _, root := range roots { @@ -225,7 +225,7 @@ func TestRebuiltTreeParentErr(t *testing.T) { rfs := NewRebuiltForrest(nil, Graph{}, cbs, false) tree, err := rfs.RebuiltTree(ctx, 305) - assert.EqualError(t, err, `failed to rebuild parent tree: 304: tree does not exist`) + assert.EqualError(t, err, `failed to rebuild parent tree: 304: tree does not exist: item does not exist`) assert.Nil(t, tree) }) -- cgit v1.1-4-g5e80