From 7c9de305d3dd364d6d76c8869d55a09bf80b28a8 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Thu, 2 Mar 2023 16:02:42 -0700 Subject: btrfs: Migrate to the new btrfstree.Forrest API --- cmd/btrfs-rec/inspect/lsfiles/lsfiles.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'cmd/btrfs-rec') diff --git a/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go b/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go index af8f690..dec472d 100644 --- a/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go +++ b/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go @@ -21,8 +21,6 @@ import ( "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/diskio" "git.lukeshu.com/btrfs-progs-ng/lib/maps" "git.lukeshu.com/btrfs-progs-ng/lib/textui" ) @@ -32,8 +30,7 @@ func LsFiles( out io.Writer, fs interface { btrfstree.TreeOperator - Superblock() (*btrfstree.Superblock, error) - diskio.ReaderAt[btrfsvol.LogicalAddr] + btrfs.ReadableFS }, ) (err error) { defer func() { -- cgit v1.2.3-54-g00ecf From f9fd200f70d5746e6e5b64e1c6e7ed2474081964 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Thu, 2 Mar 2023 16:02:42 -0700 Subject: btrfsutil, cmd: Migrate to the new btrfstree.Forrest API --- cmd/btrfs-rec/inspect/dumptrees/print_tree.go | 96 +++++++++++++-------------- cmd/btrfs-rec/inspect/lsfiles/lsfiles.go | 6 +- cmd/btrfs-rec/inspect_lstrees.go | 4 +- cmd/btrfs-rec/inspect_spewitems.go | 7 +- lib/btrfsutil/walk.go | 53 ++++++--------- 5 files changed, 76 insertions(+), 90 deletions(-) (limited to 'cmd/btrfs-rec') diff --git a/cmd/btrfs-rec/inspect/dumptrees/print_tree.go b/cmd/btrfs-rec/inspect/dumptrees/print_tree.go index 75797a8..735a50b 100644 --- a/cmd/btrfs-rec/inspect/dumptrees/print_tree.go +++ b/cmd/btrfs-rec/inspect/dumptrees/print_tree.go @@ -23,7 +23,7 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/textui" ) -func DumpTrees(ctx context.Context, out io.Writer, fs *btrfs.FS) { +func DumpTrees(ctx context.Context, out io.Writer, fs btrfs.ReadableFS) { superblock, err := fs.Superblock() if err != nil { dlog.Error(ctx, err) @@ -46,45 +46,44 @@ func DumpTrees(ctx context.Context, out io.Writer, fs *btrfs.FS) { textui.Fprintf(out, "block group tree\n") printTree(ctx, out, fs, btrfsprim.BLOCK_GROUP_TREE_OBJECTID) } - fs.TreeWalk( - ctx, - btrfsprim.ROOT_TREE_OBJECTID, - func(err *btrfstree.TreeError) { - dlog.Error(ctx, err) - }, - btrfstree.TreeWalkHandler{ - Item: func(_ btrfstree.Path, item btrfstree.Item) { - if item.Key.ItemType != btrfsitem.ROOT_ITEM_KEY { - return - } - treeName, ok := map[btrfsprim.ObjID]string{ - btrfsprim.ROOT_TREE_OBJECTID: "root", - btrfsprim.EXTENT_TREE_OBJECTID: "extent", - btrfsprim.CHUNK_TREE_OBJECTID: "chunk", - btrfsprim.DEV_TREE_OBJECTID: "device", - btrfsprim.FS_TREE_OBJECTID: "fs", - btrfsprim.ROOT_TREE_DIR_OBJECTID: "directory", - btrfsprim.CSUM_TREE_OBJECTID: "checksum", - btrfsprim.ORPHAN_OBJECTID: "orphan", - btrfsprim.TREE_LOG_OBJECTID: "log", - btrfsprim.TREE_LOG_FIXUP_OBJECTID: "log fixup", - btrfsprim.TREE_RELOC_OBJECTID: "reloc", - btrfsprim.DATA_RELOC_TREE_OBJECTID: "data reloc", - btrfsprim.EXTENT_CSUM_OBJECTID: "extent checksum", - btrfsprim.QUOTA_TREE_OBJECTID: "quota", - btrfsprim.UUID_TREE_OBJECTID: "uuid", - btrfsprim.FREE_SPACE_TREE_OBJECTID: "free space", - btrfsprim.MULTIPLE_OBJECTIDS: "multiple", - btrfsprim.BLOCK_GROUP_TREE_OBJECTID: "block group", - }[item.Key.ObjectID] - if !ok { - treeName = "file" - } - textui.Fprintf(out, "%v tree key %v \n", treeName, item.Key.Format(btrfsprim.ROOT_TREE_OBJECTID)) - printTree(ctx, out, fs, item.Key.ObjectID) - }, - }, - ) + rootTree, err := fs.ForrestLookup(ctx, btrfsprim.ROOT_TREE_OBJECTID) + if err != nil { + dlog.Errorf(ctx, "root tree: %v", err) + } else { + if err := rootTree.TreeRange(ctx, func(item btrfstree.Item) bool { + if item.Key.ItemType != btrfsitem.ROOT_ITEM_KEY { + return true + } + treeName, ok := map[btrfsprim.ObjID]string{ + btrfsprim.ROOT_TREE_OBJECTID: "root", + btrfsprim.EXTENT_TREE_OBJECTID: "extent", + btrfsprim.CHUNK_TREE_OBJECTID: "chunk", + btrfsprim.DEV_TREE_OBJECTID: "device", + btrfsprim.FS_TREE_OBJECTID: "fs", + btrfsprim.ROOT_TREE_DIR_OBJECTID: "directory", + btrfsprim.CSUM_TREE_OBJECTID: "checksum", + btrfsprim.ORPHAN_OBJECTID: "orphan", + btrfsprim.TREE_LOG_OBJECTID: "log", + btrfsprim.TREE_LOG_FIXUP_OBJECTID: "log fixup", + btrfsprim.TREE_RELOC_OBJECTID: "reloc", + btrfsprim.DATA_RELOC_TREE_OBJECTID: "data reloc", + btrfsprim.EXTENT_CSUM_OBJECTID: "extent checksum", + btrfsprim.QUOTA_TREE_OBJECTID: "quota", + btrfsprim.UUID_TREE_OBJECTID: "uuid", + btrfsprim.FREE_SPACE_TREE_OBJECTID: "free space", + btrfsprim.MULTIPLE_OBJECTIDS: "multiple", + btrfsprim.BLOCK_GROUP_TREE_OBJECTID: "block group", + }[item.Key.ObjectID] + if !ok { + treeName = "file" + } + textui.Fprintf(out, "%v tree key %v \n", treeName, item.Key.Format(btrfsprim.ROOT_TREE_OBJECTID)) + printTree(ctx, out, fs, item.Key.ObjectID) + return true + }); err != nil { + dlog.Errorf(ctx, "iterating over root tree: %v", err) + } + } textui.Fprintf(out, "total bytes %v\n", superblock.TotalBytes) textui.Fprintf(out, "bytes used %v\n", superblock.BytesUsed) textui.Fprintf(out, "uuid %v\n", superblock.FSUUID) @@ -95,7 +94,7 @@ var nodeHeaderSize = binstruct.StaticSize(btrfstree.NodeHeader{}) // printTree mimics btrfs-progs // kernel-shared/print-tree.c:btrfs_print_tree() and // kernel-shared/print-tree.c:btrfs_print_leaf() -func printTree(ctx context.Context, out io.Writer, fs *btrfs.FS, treeID btrfsprim.ObjID) { +func printTree(ctx context.Context, out io.Writer, fs btrfs.ReadableFS, treeID btrfsprim.ObjID) { var itemOffset uint32 handlers := btrfstree.TreeWalkHandler{ Node: func(path btrfstree.Path, node *btrfstree.Node) { @@ -357,14 +356,13 @@ func printTree(ctx context.Context, out io.Writer, fs *btrfs.FS, treeID btrfspri }, } handlers.BadItem = handlers.Item - fs.TreeWalk( - ctx, - treeID, - func(err *btrfstree.TreeError) { - dlog.Error(ctx, err) - }, - handlers, - ) + + tree, err := fs.ForrestLookup(ctx, treeID) + if err != nil { + dlog.Errorf(ctx, "tree %v: %v", treeID, err) + return + } + tree.TreeWalk(ctx, handlers) } // printHeaderInfo mimics btrfs-progs kernel-shared/print-tree.c:print_header_info() diff --git a/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go b/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go index dec472d..d172e2e 100644 --- a/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go +++ b/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go @@ -20,7 +20,6 @@ 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/btrfstree" "git.lukeshu.com/btrfs-progs-ng/lib/maps" "git.lukeshu.com/btrfs-progs-ng/lib/textui" ) @@ -28,10 +27,7 @@ import ( func LsFiles( ctx context.Context, out io.Writer, - fs interface { - btrfstree.TreeOperator - btrfs.ReadableFS - }, + fs btrfs.ReadableFS, ) (err error) { defer func() { if _err := derror.PanicToError(recover()); _err != nil { diff --git a/cmd/btrfs-rec/inspect_lstrees.go b/cmd/btrfs-rec/inspect_lstrees.go index 5887983..0eb45ba 100644 --- a/cmd/btrfs-rec/inspect_lstrees.go +++ b/cmd/btrfs-rec/inspect_lstrees.go @@ -71,10 +71,10 @@ func init() { treeItemCnt = make(map[btrfsitem.Type]int) textui.Fprintf(os.Stdout, "tree id=%v name=%q\n", treeID, name) }, - Err: func(_ *btrfsutil.WalkError) { + BadTree: func(_ string, _ btrfsprim.ObjID, _ error) { treeErrCnt++ }, - TreeWalkHandler: btrfstree.TreeWalkHandler{ + Tree: btrfstree.TreeWalkHandler{ Node: func(path btrfstree.Path, node *btrfstree.Node) { visitedNodes.Insert(node.Head.Addr) }, diff --git a/cmd/btrfs-rec/inspect_spewitems.go b/cmd/btrfs-rec/inspect_spewitems.go index c3a1e6b..94d34d9 100644 --- a/cmd/btrfs-rec/inspect_spewitems.go +++ b/cmd/btrfs-rec/inspect_spewitems.go @@ -13,6 +13,7 @@ import ( "github.com/spf13/cobra" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" + "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/btrfsutil" "git.lukeshu.com/btrfs-progs-ng/lib/textui" @@ -30,10 +31,10 @@ func init() { spew.DisablePointerAddresses = true btrfsutil.WalkAllTrees(ctx, fs, btrfsutil.WalkAllTreesHandler{ - Err: func(err *btrfsutil.WalkError) { - dlog.Error(ctx, err) + BadTree: func(name string, id btrfsprim.ObjID, err error) { + dlog.Errorf(ctx, "%v: %v", name, err) }, - TreeWalkHandler: btrfstree.TreeWalkHandler{ + Tree: btrfstree.TreeWalkHandler{ Item: func(path btrfstree.Path, item btrfstree.Item) { textui.Fprintf(os.Stdout, "%s = ", path) spew.Dump(item) diff --git a/lib/btrfsutil/walk.go b/lib/btrfsutil/walk.go index b05218c..caa1e4c 100644 --- a/lib/btrfsutil/walk.go +++ b/lib/btrfsutil/walk.go @@ -8,35 +8,23 @@ import ( "context" "fmt" + "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" ) -type WalkError struct { - TreeName string - Err *btrfstree.TreeError -} - -func (e *WalkError) Unwrap() error { return e.Err } - -func (e *WalkError) Error() string { - return fmt.Sprintf("%v: %v", e.TreeName, e.Err) -} - type WalkAllTreesHandler struct { - Err func(*WalkError) - // Callbacks for entire trees PreTree func(name string, id btrfsprim.ObjID) + BadTree func(name string, id btrfsprim.ObjID, err error) + Tree btrfstree.TreeWalkHandler PostTree func(name string, id btrfsprim.ObjID) - // Callbacks for nodes or smaller - btrfstree.TreeWalkHandler } -// WalkAllTrees walks all trees in a *btrfs.FS. Rather than returning -// an error, it calls errCb each time an error is encountered. The -// error will always be of type WalkError. -func WalkAllTrees(ctx context.Context, fs btrfstree.TreeOperator, cbs WalkAllTreesHandler) { +// WalkAllTrees walks all trees in a btrfs.ReadableFS. Rather than +// returning an error, it calls the appropriate "BadXXX" callback +// (BadTree, BadNode, BadItem) each time an error is encountered. +func WalkAllTrees(ctx context.Context, fs btrfs.ReadableFS, cbs WalkAllTreesHandler) { var treeName string trees := []struct { @@ -60,8 +48,8 @@ func WalkAllTrees(ctx context.Context, fs btrfstree.TreeOperator, cbs WalkAllTre ID: btrfsprim.BLOCK_GROUP_TREE_OBJECTID, }, } - origItem := cbs.Item - cbs.Item = func(path btrfstree.Path, item btrfstree.Item) { + origItem := cbs.Tree.Item + cbs.Tree.Item = func(path btrfstree.Path, item btrfstree.Item) { if item.Key.ItemType == btrfsitem.ROOT_ITEM_KEY { trees = append(trees, struct { Name string @@ -78,19 +66,22 @@ func WalkAllTrees(ctx context.Context, fs btrfstree.TreeOperator, cbs WalkAllTre } for i := 0; i < len(trees); i++ { - tree := trees[i] - treeName = tree.Name + treeInfo := trees[i] + treeName = treeInfo.Name if cbs.PreTree != nil { - cbs.PreTree(treeName, tree.ID) + cbs.PreTree(treeName, treeInfo.ID) + } + tree, err := fs.ForrestLookup(ctx, treeInfo.ID) + switch { + case err != nil: + if cbs.BadTree != nil { + cbs.BadTree(treeName, treeInfo.ID, err) + } + default: + tree.TreeWalk(ctx, cbs.Tree) } - fs.TreeWalk( - ctx, - tree.ID, - func(err *btrfstree.TreeError) { cbs.Err(&WalkError{TreeName: treeName, Err: err}) }, - cbs.TreeWalkHandler, - ) if cbs.PostTree != nil { - cbs.PostTree(treeName, tree.ID) + cbs.PostTree(treeName, treeInfo.ID) } } } -- cgit v1.2.3-54-g00ecf From c7b6460ee9b3c07c13c973cbc8c8f690560fefc6 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Thu, 2 Mar 2023 16:02:42 -0700 Subject: tree-wide: Drop the old btrfstree.TreeOperator API --- cmd/btrfs-rec/inspect/mount/mount.go | 2 +- cmd/btrfs-rec/inspect_lsfiles.go | 2 +- lib/btrfs/btrfstree/btree.go | 53 --------------------- lib/btrfs/btrfstree/btree_forrest.go | 81 ++------------------------------ lib/btrfs/io3_btree.go | 24 ---------- lib/btrfsutil/old_rebuilt_forrest.go | 89 ++++++++---------------------------- 6 files changed, 27 insertions(+), 224 deletions(-) (limited to 'cmd/btrfs-rec') diff --git a/cmd/btrfs-rec/inspect/mount/mount.go b/cmd/btrfs-rec/inspect/mount/mount.go index 143131a..28363ed 100644 --- a/cmd/btrfs-rec/inspect/mount/mount.go +++ b/cmd/btrfs-rec/inspect/mount/mount.go @@ -54,7 +54,7 @@ func MountRO(ctx context.Context, fs *btrfs.FS, mountpoint string, noChecksums b rootSubvol := &subvolume{ Subvolume: btrfs.NewSubvolume( ctx, - btrfsutil.NewOldRebuiltForrest(ctx, fs), + btrfsutil.NewOldRebuiltForrest(fs), btrfsprim.FS_TREE_OBJECTID, noChecksums, ), diff --git a/cmd/btrfs-rec/inspect_lsfiles.go b/cmd/btrfs-rec/inspect_lsfiles.go index 00a4873..abc73bc 100644 --- a/cmd/btrfs-rec/inspect_lsfiles.go +++ b/cmd/btrfs-rec/inspect_lsfiles.go @@ -32,7 +32,7 @@ func init() { return lsfiles.LsFiles( cmd.Context(), out, - btrfsutil.NewOldRebuiltForrest(cmd.Context(), fs)) + btrfsutil.NewOldRebuiltForrest(fs)) }), }) } diff --git a/lib/btrfs/btrfstree/btree.go b/lib/btrfs/btrfstree/btree.go index cbaa6d0..25259c0 100644 --- a/lib/btrfs/btrfstree/btree.go +++ b/lib/btrfs/btrfstree/btree.go @@ -137,59 +137,6 @@ type TreeWalkHandler struct { BadItem func(Path, Item) } -// Compat ////////////////////////////////////////////////////////////////////// - -// TreeOperator is an interface for performing basic btree operations. -type TreeOperator interface { - // TreeWalk walks a tree, triggering callbacks for every node, - // key-pointer, and item; as well as for any errors encountered. - // - // If the tree is valid, then everything is walked in key-order; but - // if the tree is broken, then ordering is not guaranteed. - // - // Canceling the Context causes TreeWalk to return early; no values - // from the Context are used. - // - // The lifecycle of callbacks is: - // - // 000 (read superblock) (maybe cbs.BadSuperblock()) - // - // 001 (read node) - // 002 cbs.Node() or cbs.BadNode() - // if interior: - // for kp in node.items: - // 003a if cbs.PreKeyPointer == nil || cbs.PreKeyPointer() { - // 004b (recurse) - // else: - // for item in node.items: - // 003b cbs.Item() or cbs.BadItem() - TreeWalk(ctx context.Context, treeID btrfsprim.ObjID, errHandle func(*TreeError), cbs TreeWalkHandler) - - TreeLookup(treeID btrfsprim.ObjID, key btrfsprim.Key) (Item, error) - TreeSearch(treeID btrfsprim.ObjID, search TreeSearcher) (Item, error) - - // If some items are able to be read, but there is an error reading the - // full set, then it might return *both* a list of items and an error. - // - // If the tree is not found, an error that is ErrNoTree is - // returned. - // - // If no such item is found, an error that is ErrNoItem is - // returned. - TreeSearchAll(treeID btrfsprim.ObjID, search TreeSearcher) ([]Item, error) -} - -type TreeError struct { - Path Path - Err error -} - -func (e *TreeError) Unwrap() error { return e.Err } - -func (e *TreeError) Error() string { - return fmt.Sprintf("%v: %v", e.Path, e.Err) -} - type NodeSource interface { Superblock() (*Superblock, error) AcquireNode(ctx context.Context, addr btrfsvol.LogicalAddr, exp NodeExpectations) (*Node, error) diff --git a/lib/btrfs/btrfstree/btree_forrest.go b/lib/btrfs/btrfstree/btree_forrest.go index 4a4a4c0..1a80504 100644 --- a/lib/btrfs/btrfstree/btree_forrest.go +++ b/lib/btrfs/btrfstree/btree_forrest.go @@ -40,27 +40,6 @@ type TreeRoot struct { // LookupTreeRoot, as LookupTreeRoot will not call ForrestLookup for // ROOT_TREE_OBJECTID; so it will not be an infinite recursion. func LookupTreeRoot(ctx context.Context, forrest Forrest, sb Superblock, treeID btrfsprim.ObjID) (*TreeRoot, error) { - return OldLookupTreeRoot( - ctx, - func(rootTreeID btrfsprim.ObjID, searcher TreeSearcher) (Item, error) { - rootTree, err := forrest.ForrestLookup(ctx, rootTreeID) - if err != nil { - return Item{}, err - } - rootItem, err := rootTree.TreeSearch(ctx, searcher) - if err != nil { - return Item{}, err - } - return rootItem, nil - }, - sb, - treeID, - ) -} - -// OldLookupTreeRoot is a utility function to help with implementing -// the old 'TreeOperator' interface. -func OldLookupTreeRoot(_ context.Context, treeSearch func(treeID btrfsprim.ObjID, _ TreeSearcher) (Item, error), sb Superblock, treeID btrfsprim.ObjID) (*TreeRoot, error) { switch treeID { case btrfsprim.ROOT_TREE_OBJECTID: return &TreeRoot{ @@ -91,7 +70,11 @@ func OldLookupTreeRoot(_ context.Context, treeSearch func(treeID btrfsprim.ObjID Generation: sb.BlockGroupRootGeneration, }, nil default: - rootItem, err := treeSearch(btrfsprim.ROOT_TREE_OBJECTID, SearchRootItem(treeID)) + rootTree, err := forrest.ForrestLookup(ctx, btrfsprim.ROOT_TREE_OBJECTID) + if err != nil { + return nil, fmt.Errorf("tree %s: %w", treeID.Format(btrfsprim.ROOT_TREE_OBJECTID), err) + } + rootItem, err := rootTree.TreeSearch(ctx, SearchRootItem(treeID)) if err != nil { if errors.Is(err, ErrNoItem) { err = fmt.Errorf("%w: %s", ErrNoTree, err) @@ -152,57 +135,3 @@ func (forrest RawForrest) ForrestLookup(ctx context.Context, treeID btrfsprim.Ob } return tree, nil } - -// Compat ////////////////////////////////////////////////////////////////////// - -var _ TreeOperator = RawForrest{} - -type TreeOperatorImpl = RawForrest - -// TreeWalk implements the 'TreeOperator' interface. -func (forrest RawForrest) TreeWalk(ctx context.Context, treeID btrfsprim.ObjID, errHandle func(*TreeError), cbs TreeWalkHandler) { - tree, err := forrest.RawTree(ctx, treeID) - if err != nil { - errHandle(&TreeError{Path: Path{PathRoot{TreeID: treeID}}, Err: err}) - return - } - tree.TreeWalk(ctx, cbs) -} - -// TreeLookup implements the 'TreeOperator' interface. -func (forrest RawForrest) TreeLookup(treeID btrfsprim.ObjID, key btrfsprim.Key) (Item, error) { - ctx := context.TODO() - tree, err := forrest.RawTree(ctx, treeID) - if err != nil { - return Item{}, err - } - return tree.TreeLookup(ctx, key) -} - -// TreeSearch implements the 'TreeOperator' interface. -func (forrest RawForrest) TreeSearch(treeID btrfsprim.ObjID, searcher TreeSearcher) (Item, error) { - ctx := context.TODO() - tree, err := forrest.RawTree(ctx, treeID) - if err != nil { - return Item{}, err - } - return tree.TreeSearch(ctx, searcher) -} - -// TreeSearchAll implements the 'TreeOperator' interface. -func (forrest RawForrest) TreeSearchAll(treeID btrfsprim.ObjID, searcher TreeSearcher) ([]Item, error) { - ctx := context.TODO() - tree, err := forrest.RawTree(ctx, treeID) - if err != nil { - return nil, err - } - - var ret []Item - err = tree.TreeSubrange(ctx, 1, searcher, func(item Item) bool { - item.Body = item.Body.CloneItem() - ret = append(ret, item) - return true - }) - - return ret, err -} diff --git a/lib/btrfs/io3_btree.go b/lib/btrfs/io3_btree.go index 59e4c1d..01797df 100644 --- a/lib/btrfs/io3_btree.go +++ b/lib/btrfs/io3_btree.go @@ -89,30 +89,6 @@ func (fs *FS) ForrestLookup(ctx context.Context, treeID btrfsprim.ObjID) (btrfst var _ btrfstree.Forrest = (*FS)(nil) -// btrfstree.TreeOperator ////////////////////////////////////////////////////// - -// TreeWalk implements btrfstree.TreeOperator. -func (fs *FS) TreeWalk(ctx context.Context, treeID btrfsprim.ObjID, errHandle func(*btrfstree.TreeError), cbs btrfstree.TreeWalkHandler) { - btrfstree.TreeOperatorImpl{NodeSource: fs}.TreeWalk(ctx, treeID, errHandle, cbs) -} - -// TreeLookup implements btrfstree.TreeOperator. -func (fs *FS) TreeLookup(treeID btrfsprim.ObjID, key btrfsprim.Key) (btrfstree.Item, error) { - return btrfstree.TreeOperatorImpl{NodeSource: fs}.TreeLookup(treeID, key) -} - -// TreeSearch implements btrfstree.TreeOperator. -func (fs *FS) TreeSearch(treeID btrfsprim.ObjID, searcher btrfstree.TreeSearcher) (btrfstree.Item, error) { - return btrfstree.TreeOperatorImpl{NodeSource: fs}.TreeSearch(treeID, searcher) -} - -// TreeSearchAll implements btrfstree.TreeOperator. -func (fs *FS) TreeSearchAll(treeID btrfsprim.ObjID, searcher btrfstree.TreeSearcher) ([]btrfstree.Item, error) { - return btrfstree.TreeOperatorImpl{NodeSource: fs}.TreeSearchAll(treeID, searcher) -} - -var _ btrfstree.TreeOperator = (*FS)(nil) - // ReadableFS ////////////////////////////////////////////////////////////////// type ReadableFS interface { diff --git a/lib/btrfsutil/old_rebuilt_forrest.go b/lib/btrfsutil/old_rebuilt_forrest.go index ae63001..58333df 100644 --- a/lib/btrfsutil/old_rebuilt_forrest.go +++ b/lib/btrfsutil/old_rebuilt_forrest.go @@ -85,7 +85,6 @@ func newOldRebuiltTree() oldRebuiltTree { } type OldRebuiltForrest struct { - ctx context.Context //nolint:containedctx // don't have an option while keeping the same API inner *btrfs.FS // btrfsprim.ROOT_TREE_OBJECTID @@ -96,32 +95,27 @@ type OldRebuiltForrest struct { trees map[btrfsprim.ObjID]oldRebuiltTree } -var ( - _ btrfstree.TreeOperator = (*OldRebuiltForrest)(nil) - _ btrfs.ReadableFS = (*OldRebuiltForrest)(nil) -) +var _ btrfs.ReadableFS = (*OldRebuiltForrest)(nil) // NewOldRebuiltForrest wraps a *btrfs.FS to support looking up // information from broken trees. // -// Of the btrfstree.TreeOperator methods: +// Of the btrfstree.Tree methods: // -// - TreeWalk works on broken trees -// - TreeLookup relies on the tree being properly ordered (which a +// - TreeRange works on broken trees +// - TreeSubrange relies on the tree being properly ordered (which a // broken tree might not be). // - TreeSearch relies on the tree being properly ordered (which a // broken tree might not be). -// - TreeSearchAll relies on the tree being properly ordered (which a -// broken tree might not be), and a bad node may cause it to not -// return a truncated list of results. +// - TreeLookup relies on the tree being properly ordered (which a +// broken tree might not be). // -// NewOldRebuiltForrest attempts to remedy these deficiencies by using -// .TreeWalk to build an out-of-FS index of all of the items in the -// tree, and re-implements TreeLookup, TreeSearch, and TreeSearchAll +// NewOldRebuiltForrest attempts to remedy these deficiencies by +// building an out-of-FS index of all of the items in the tree, and +// re-implements TreeLookup, TreeSearch, TreeSubrange, and TreeRange // using that index. -func NewOldRebuiltForrest(ctx context.Context, inner *btrfs.FS) *OldRebuiltForrest { +func NewOldRebuiltForrest(inner *btrfs.FS) *OldRebuiltForrest { return &OldRebuiltForrest{ - ctx: ctx, inner: inner, } } @@ -251,8 +245,8 @@ func (tree oldRebuiltTree) addErrs(fn func(btrfsprim.Key, uint32) int, err error return errs } -func (bt *OldRebuiltForrest) readNode(nodeInfo nodeInfo) *btrfstree.Node { - node, err := bt.inner.AcquireNode(bt.ctx, nodeInfo.LAddr, btrfstree.NodeExpectations{ +func (bt *OldRebuiltForrest) readNode(ctx context.Context, nodeInfo nodeInfo) *btrfstree.Node { + node, err := bt.inner.AcquireNode(ctx, nodeInfo.LAddr, btrfstree.NodeExpectations{ LAddr: containers.OptionalValue(nodeInfo.LAddr), Level: containers.OptionalValue(nodeInfo.Level), Generation: containers.OptionalValue(nodeInfo.Generation), @@ -274,23 +268,13 @@ func (bt *OldRebuiltForrest) readNode(nodeInfo nodeInfo) *btrfstree.Node { return node } -// TreeLookup implements btrfstree.TreeOperator. -func (bt *OldRebuiltForrest) TreeLookup(treeID btrfsprim.ObjID, key btrfsprim.Key) (btrfstree.Item, error) { - return bt.RebuiltTree(bt.ctx, treeID).TreeLookup(bt.ctx, key) -} - // TreeLookup implements btrfstree.Tree. func (tree oldRebuiltTree) TreeLookup(ctx context.Context, key btrfsprim.Key) (btrfstree.Item, error) { return tree.TreeSearch(ctx, btrfstree.SearchExactKey(key)) } -// TreeSearch implements btrfstree.TreeOperator. -func (bt *OldRebuiltForrest) TreeSearch(treeID btrfsprim.ObjID, searcher btrfstree.TreeSearcher) (btrfstree.Item, error) { - return bt.RebuiltTree(bt.ctx, treeID).TreeSearch(bt.ctx, searcher) -} - // TreeSearch implements btrfstree.Tree. -func (tree oldRebuiltTree) TreeSearch(_ context.Context, searcher btrfstree.TreeSearcher) (btrfstree.Item, error) { +func (tree oldRebuiltTree) TreeSearch(ctx context.Context, searcher btrfstree.TreeSearcher) (btrfstree.Item, error) { if tree.RootErr != nil { return btrfstree.Item{}, tree.RootErr } @@ -302,7 +286,7 @@ func (tree oldRebuiltTree) TreeSearch(_ context.Context, searcher btrfstree.Tree return btrfstree.Item{}, fmt.Errorf("item with %s: %w", searcher, tree.addErrs(searcher.Search, btrfstree.ErrNoItem)) } - node := tree.forrest.readNode(indexItem.Value.Node) + node := tree.forrest.readNode(ctx, indexItem.Value.Node) defer tree.forrest.inner.ReleaseNode(node) item := node.BodyLeaf[indexItem.Value.Slot] @@ -314,7 +298,7 @@ func (tree oldRebuiltTree) TreeSearch(_ context.Context, searcher btrfstree.Tree } // TreeRange implements btrfstree.Tree. -func (tree oldRebuiltTree) TreeRange(_ context.Context, handleFn func(btrfstree.Item) bool) error { +func (tree oldRebuiltTree) TreeRange(ctx context.Context, handleFn func(btrfstree.Item) bool) error { if tree.RootErr != nil { return tree.RootErr } @@ -324,7 +308,7 @@ func (tree oldRebuiltTree) TreeRange(_ context.Context, handleFn func(btrfstree. func(rbnode *containers.RBNode[oldRebuiltTreeValue]) bool { if node == nil || node.Head.Addr != rbnode.Value.Node.LAddr { tree.forrest.inner.ReleaseNode(node) - node = tree.forrest.readNode(rbnode.Value.Node) + node = tree.forrest.readNode(ctx, rbnode.Value.Node) } return handleFn(node.BodyLeaf[rbnode.Value.Slot]) }) @@ -333,25 +317,8 @@ func (tree oldRebuiltTree) TreeRange(_ context.Context, handleFn func(btrfstree. return tree.addErrs(func(btrfsprim.Key, uint32) int { return 0 }, nil) } -// TreeSearchAll implements btrfstree.TreeOperator. -func (bt *OldRebuiltForrest) TreeSearchAll(treeID btrfsprim.ObjID, searcher btrfstree.TreeSearcher) ([]btrfstree.Item, error) { - tree := bt.RebuiltTree(bt.ctx, treeID) - if tree.RootErr != nil { - return nil, tree.RootErr - } - - var ret []btrfstree.Item - err := tree.TreeSubrange(bt.ctx, 1, searcher, func(item btrfstree.Item) bool { - item.Body = item.Body.CloneItem() - ret = append(ret, item) - return true - }) - - return ret, err -} - // TreeSubrange implements btrfstree.Tree. -func (tree oldRebuiltTree) TreeSubrange(_ context.Context, min int, searcher btrfstree.TreeSearcher, handleFn func(btrfstree.Item) bool) error { +func (tree oldRebuiltTree) TreeSubrange(ctx context.Context, min int, searcher btrfstree.TreeSearcher, handleFn func(btrfstree.Item) bool) error { var node *btrfstree.Node var cnt int tree.Items.Subrange( @@ -362,7 +329,7 @@ func (tree oldRebuiltTree) TreeSubrange(_ context.Context, min int, searcher btr cnt++ if node == nil || node.Head.Addr != rbNode.Value.Node.LAddr { tree.forrest.inner.ReleaseNode(node) - node = tree.forrest.readNode(rbNode.Value.Node) + node = tree.forrest.readNode(ctx, rbNode.Value.Node) } return handleFn(node.BodyLeaf[rbNode.Value.Slot]) }) @@ -379,20 +346,6 @@ func (tree oldRebuiltTree) TreeSubrange(_ context.Context, min int, searcher btr return err } -// TreeWalk implements btrfstree.TreeOperator. It doesn't actually -// visit nodes or keypointers (just items). -func (bt *OldRebuiltForrest) TreeWalk(ctx context.Context, treeID btrfsprim.ObjID, errHandle func(*btrfstree.TreeError), cbs btrfstree.TreeWalkHandler) { - tree := bt.RebuiltTree(ctx, treeID) - if tree.RootErr != nil { - errHandle(&btrfstree.TreeError{ - Path: btrfstree.Path{btrfstree.PathRoot{TreeID: treeID}}, - Err: tree.RootErr, - }) - return - } - tree.TreeWalk(ctx, cbs) -} - // TreeWalk implements btrfstree.Tree. It doesn't actually visit // nodes or keypointers (just items). func (tree oldRebuiltTree) TreeWalk(ctx context.Context, cbs btrfstree.TreeWalkHandler) { @@ -404,12 +357,10 @@ func (tree oldRebuiltTree) TreeWalk(ctx context.Context, cbs btrfstree.TreeWalkH if ctx.Err() != nil { return false } - if tree.forrest.ctx.Err() != nil { - return false - } + if node == nil || node.Head.Addr != indexItem.Value.Node.LAddr { tree.forrest.inner.ReleaseNode(node) - node = tree.forrest.readNode(indexItem.Value.Node) + node = tree.forrest.readNode(ctx, indexItem.Value.Node) } item := node.BodyLeaf[indexItem.Value.Slot] -- cgit v1.2.3-54-g00ecf