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. --- lib/btrfsutil/old_rebuilt_forrest.go | 37 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 19 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 d49f34e..2ec1d83 100644 --- a/lib/btrfsutil/old_rebuilt_forrest.go +++ b/lib/btrfsutil/old_rebuilt_forrest.go @@ -17,7 +17,6 @@ import ( "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/containers" - "git.lukeshu.com/btrfs-progs-ng/lib/diskio" ) type oldRebuiltTree struct { @@ -226,12 +225,12 @@ func (bt *OldRebuiltForrest) TreeSearch(treeID btrfsprim.ObjID, searcher btrfstr itemPath := bt.arena.Inflate(indexItem.Value.Path) node, err := bt.inner.ReadNode(itemPath.Parent()) - defer btrfstree.FreeNodeRef(node) + defer node.Free() if err != nil { return btrfstree.Item{}, fmt.Errorf("item with %s: %w", searcher, bt.addErrs(tree, searcher.Search, err)) } - item := node.Data.BodyLeaf[itemPath.Node(-1).FromItemSlot] + item := node.BodyLeaf[itemPath.Node(-1).FromItemSlot] item.Body = item.Body.CloneItem() // Since we were only asked to return 1 item, it isn't @@ -259,22 +258,22 @@ func (bt *OldRebuiltForrest) TreeSearchAll(treeID btrfsprim.ObjID, searcher btrf } ret := make([]btrfstree.Item, len(indexItems)) - var node *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.Node] + var node *btrfstree.Node for i := range indexItems { itemPath := bt.arena.Inflate(indexItems[i].Path) - if node == nil || node.Addr != itemPath.Node(-2).ToNodeAddr { + if node == nil || node.Head.Addr != itemPath.Node(-2).ToNodeAddr { var err error - btrfstree.FreeNodeRef(node) + node.Free() node, err = bt.inner.ReadNode(itemPath.Parent()) if err != nil { - btrfstree.FreeNodeRef(node) + node.Free() return nil, fmt.Errorf("items with %s: %w", searcher, bt.addErrs(tree, searcher.Search, err)) } } - ret[i] = node.Data.BodyLeaf[itemPath.Node(-1).FromItemSlot] + ret[i] = node.BodyLeaf[itemPath.Node(-1).FromItemSlot] ret[i].Body = ret[i].Body.CloneItem() } - btrfstree.FreeNodeRef(node) + node.Free() err := bt.addErrs(tree, searcher.Search, nil) if err != nil { @@ -298,7 +297,7 @@ func (bt *OldRebuiltForrest) TreeWalk(ctx context.Context, treeID btrfsprim.ObjI if cbs.Item == nil { return } - var node *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.Node] + var node *btrfstree.Node tree.Items.Range(func(indexItem *containers.RBNode[oldRebuiltTreeValue]) bool { if ctx.Err() != nil { return false @@ -307,23 +306,23 @@ func (bt *OldRebuiltForrest) TreeWalk(ctx context.Context, treeID btrfsprim.ObjI return false } itemPath := bt.arena.Inflate(indexItem.Value.Path) - if node == nil || node.Addr != itemPath.Node(-2).ToNodeAddr { + if node == nil || node.Head.Addr != itemPath.Node(-2).ToNodeAddr { var err error - btrfstree.FreeNodeRef(node) + node.Free() node, err = bt.inner.ReadNode(itemPath.Parent()) if err != nil { - btrfstree.FreeNodeRef(node) + node.Free() errHandle(&btrfstree.TreeError{Path: itemPath, Err: err}) return true } } - item := node.Data.BodyLeaf[itemPath.Node(-1).FromItemSlot] + item := node.BodyLeaf[itemPath.Node(-1).FromItemSlot] if err := cbs.Item(itemPath, item); err != nil { errHandle(&btrfstree.TreeError{Path: itemPath, Err: err}) } return true }) - btrfstree.FreeNodeRef(node) + node.Free() } func (bt *OldRebuiltForrest) Superblock() (*btrfstree.Superblock, error) { @@ -343,8 +342,8 @@ func (bt *OldRebuiltForrest) Augment(treeID btrfsprim.ObjID, nodeAddr btrfsvol.L if tree.RootErr != nil { return nil, tree.RootErr } - nodeRef, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](bt.inner, *sb, nodeAddr, btrfstree.NodeExpectations{}) - defer btrfstree.FreeNodeRef(nodeRef) + node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](bt.inner, *sb, nodeAddr, btrfstree.NodeExpectations{}) + defer node.Free() if err != nil { return nil, err } @@ -352,8 +351,8 @@ func (bt *OldRebuiltForrest) Augment(treeID btrfsprim.ObjID, nodeAddr btrfsvol.L bt.rawTreeWalk(btrfstree.TreeRoot{ TreeID: treeID, RootNode: nodeAddr, - Level: nodeRef.Data.Head.Level, - Generation: nodeRef.Data.Head.Generation, + Level: node.Head.Level, + Generation: node.Head.Generation, }, tree, &ret) return ret, nil } -- cgit v1.2.3-2-g168b From 8b5aa5b60839b39f75257ee1c2bafa59459a80e6 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 17 Mar 2023 22:20:10 -0400 Subject: btrfsutil: OldRebuiltForrest: Don't use Paths when tracking errors --- lib/btrfsutil/old_rebuilt_forrest.go | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 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 2ec1d83..a6c2661 100644 --- a/lib/btrfsutil/old_rebuilt_forrest.go +++ b/lib/btrfsutil/old_rebuilt_forrest.go @@ -26,8 +26,17 @@ type oldRebuiltTree struct { } type oldRebuiltTreeError struct { - Path SkinnyPath - Err error + Min btrfsprim.Key + Max btrfsprim.Key + Err error +} + +func (e oldRebuiltTreeError) Error() string { + return fmt.Sprintf("keys %v-%v: %v", e.Min, e.Max, e.Err) +} + +func (e oldRebuiltTreeError) Unwrap() error { + return e.Err } type oldRebuiltTreeValue struct { @@ -41,15 +50,15 @@ func (a oldRebuiltTreeValue) Compare(b oldRebuiltTreeValue) int { return a.Key.Compare(b.Key) } -func newOldRebuiltTree(arena *SkinnyPathArena) oldRebuiltTree { +func newOldRebuiltTree() oldRebuiltTree { return oldRebuiltTree{ Items: new(containers.RBTree[oldRebuiltTreeValue]), Errors: &containers.IntervalTree[btrfsprim.Key, oldRebuiltTreeError]{ MinFn: func(err oldRebuiltTreeError) btrfsprim.Key { - return arena.Inflate(err.Path).Node(-1).ToKey + return err.Min }, MaxFn: func(err oldRebuiltTreeError) btrfsprim.Key { - return arena.Inflate(err.Path).Node(-1).ToMaxKey + return err.Max }, }, } @@ -134,7 +143,7 @@ func (bt *OldRebuiltForrest) RebuiltTree(treeID btrfsprim.ObjID) oldRebuiltTree SB: _sb, } } - cacheEntry := newOldRebuiltTree(bt.arena) + cacheEntry := newOldRebuiltTree() if err != nil { cacheEntry.RootErr = err } else { @@ -158,8 +167,9 @@ func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry old panic(fmt.Errorf("TODO: error parsing item: %w", err)) } cacheEntry.Errors.Insert(oldRebuiltTreeError{ - Path: bt.arena.Deflate(err.Path), - Err: err.Err, + Min: err.Path.Node(-1).ToKey, + Max: err.Path.Node(-1).ToMaxKey, + Err: err.Err, }) } @@ -190,15 +200,12 @@ func (bt *OldRebuiltForrest) TreeLookup(treeID btrfsprim.ObjID, key btrfsprim.Ke return bt.TreeSearch(treeID, btrfstree.SearchExactKey(key)) } -func (bt *OldRebuiltForrest) addErrs(tree oldRebuiltTree, fn func(btrfsprim.Key, uint32) int, err error) error { +func (*OldRebuiltForrest) addErrs(tree oldRebuiltTree, fn func(btrfsprim.Key, uint32) int, err error) error { var errs derror.MultiError tree.Errors.Subrange( func(k btrfsprim.Key) int { return fn(k, 0) }, func(v oldRebuiltTreeError) bool { - path := bt.arena.Inflate(v.Path) - minKey := path.Node(-1).ToKey - maxKey := path.Node(-1).ToMaxKey - errs = append(errs, fmt.Errorf("keys %v-%v: %w", minKey, maxKey, v.Err)) + errs = append(errs, v) return true }) if len(errs) == 0 { -- cgit v1.2.3-2-g168b From 95e542df75675389a3598150be9c85c4834bbb98 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 17 Mar 2023 22:26:42 -0400 Subject: btrfsutil: OldRebuiltForrest: Move .addErrs() from the forrest to the tree --- lib/btrfsutil/old_rebuilt_forrest.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 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 a6c2661..6705535 100644 --- a/lib/btrfsutil/old_rebuilt_forrest.go +++ b/lib/btrfsutil/old_rebuilt_forrest.go @@ -200,7 +200,7 @@ func (bt *OldRebuiltForrest) TreeLookup(treeID btrfsprim.ObjID, key btrfsprim.Ke return bt.TreeSearch(treeID, btrfstree.SearchExactKey(key)) } -func (*OldRebuiltForrest) addErrs(tree oldRebuiltTree, fn func(btrfsprim.Key, uint32) int, err error) error { +func (tree oldRebuiltTree) addErrs(fn func(btrfsprim.Key, uint32) int, err error) error { var errs derror.MultiError tree.Errors.Subrange( func(k btrfsprim.Key) int { return fn(k, 0) }, @@ -227,21 +227,21 @@ func (bt *OldRebuiltForrest) TreeSearch(treeID btrfsprim.ObjID, searcher btrfstr return searcher.Search(indexItem.Key, indexItem.ItemSize) }) if indexItem == nil { - return btrfstree.Item{}, fmt.Errorf("item with %s: %w", searcher, bt.addErrs(tree, searcher.Search, btrfstree.ErrNoItem)) + return btrfstree.Item{}, fmt.Errorf("item with %s: %w", searcher, tree.addErrs(searcher.Search, btrfstree.ErrNoItem)) } itemPath := bt.arena.Inflate(indexItem.Value.Path) node, err := bt.inner.ReadNode(itemPath.Parent()) defer node.Free() if err != nil { - return btrfstree.Item{}, fmt.Errorf("item with %s: %w", searcher, bt.addErrs(tree, searcher.Search, err)) + return btrfstree.Item{}, fmt.Errorf("item with %s: %w", searcher, tree.addErrs(searcher.Search, err)) } item := node.BodyLeaf[itemPath.Node(-1).FromItemSlot] item.Body = item.Body.CloneItem() // Since we were only asked to return 1 item, it isn't - // necessary to augment this `nil` with bt.addErrs(). + // necessary to augment this `nil` with tree.addErrs(). return item, nil } @@ -261,7 +261,7 @@ func (bt *OldRebuiltForrest) TreeSearchAll(treeID btrfsprim.ObjID, searcher btrf return true }) if len(indexItems) == 0 { - return nil, fmt.Errorf("items with %s: %w", searcher, bt.addErrs(tree, searcher.Search, btrfstree.ErrNoItem)) + return nil, fmt.Errorf("items with %s: %w", searcher, tree.addErrs(searcher.Search, btrfstree.ErrNoItem)) } ret := make([]btrfstree.Item, len(indexItems)) @@ -274,7 +274,7 @@ func (bt *OldRebuiltForrest) TreeSearchAll(treeID btrfsprim.ObjID, searcher btrf node, err = bt.inner.ReadNode(itemPath.Parent()) if err != nil { node.Free() - return nil, fmt.Errorf("items with %s: %w", searcher, bt.addErrs(tree, searcher.Search, err)) + return nil, fmt.Errorf("items with %s: %w", searcher, tree.addErrs(searcher.Search, err)) } } ret[i] = node.BodyLeaf[itemPath.Node(-1).FromItemSlot] @@ -282,7 +282,7 @@ func (bt *OldRebuiltForrest) TreeSearchAll(treeID btrfsprim.ObjID, searcher btrf } node.Free() - err := bt.addErrs(tree, searcher.Search, nil) + err := tree.addErrs(searcher.Search, nil) if err != nil { err = fmt.Errorf("items with %s: %w", searcher, err) } -- cgit v1.2.3-2-g168b From b97b6962d5027ae3db2bb03db1e5303702c3e9b2 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Thu, 2 Mar 2023 16:02:42 -0700 Subject: btrfsutil: OldRebuiltForrest: Drop skinny paths This changes errors to not have a Path attached to them, only tracking their spans; and it changes the Paths from TreeWalk to only have the leaf node. --- lib/btrfsutil/old_rebuilt_forrest.go | 137 +++++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 40 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 6705535..8bc02df 100644 --- a/lib/btrfsutil/old_rebuilt_forrest.go +++ b/lib/btrfsutil/old_rebuilt_forrest.go @@ -40,9 +40,20 @@ func (e oldRebuiltTreeError) Unwrap() error { } type oldRebuiltTreeValue struct { - Path SkinnyPath Key btrfsprim.Key ItemSize uint32 + + Node nodeInfo + Slot int +} + +type nodeInfo struct { + LAddr btrfsvol.LogicalAddr + Level uint8 + Generation btrfsprim.Generation + Owner btrfsprim.ObjID + MinItem btrfsprim.Key + MaxItem btrfsprim.Key } // Compare implements containers.Ordered. @@ -68,8 +79,6 @@ type OldRebuiltForrest struct { ctx context.Context //nolint:containedctx // don't have an option while keeping the same API inner *btrfs.FS - arena *SkinnyPathArena - // btrfsprim.ROOT_TREE_OBJECTID rootTreeMu sync.Mutex rootTree *oldRebuiltTree @@ -133,16 +142,7 @@ func (bt *OldRebuiltForrest) RebuiltTree(treeID btrfsprim.ObjID) oldRebuiltTree treeRoot, err = btrfstree.LookupTreeRoot(bt, *sb, treeID) } } - if bt.arena == nil { - var _sb btrfstree.Superblock - if sb != nil { - _sb = *sb - } - bt.arena = &SkinnyPathArena{ - FS: bt.inner, - SB: _sb, - } - } + cacheEntry := newOldRebuiltTree() if err != nil { cacheEntry.RootErr = err @@ -151,6 +151,7 @@ func (bt *OldRebuiltForrest) RebuiltTree(treeID btrfsprim.ObjID) oldRebuiltTree bt.rawTreeWalk(*treeRoot, cacheEntry, nil) dlog.Infof(bt.ctx, "... done indexing tree %v", treeID) } + if treeID == btrfsprim.ROOT_TREE_OBJECTID { bt.rootTree = &cacheEntry } else { @@ -159,6 +160,8 @@ func (bt *OldRebuiltForrest) RebuiltTree(treeID btrfsprim.ObjID) oldRebuiltTree return cacheEntry } +func discardOK[T any](x T, _ bool) T { return x } + func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry oldRebuiltTree, walked *[]btrfsprim.Key) { errHandle := func(err *btrfstree.TreeError) { if len(err.Path) > 0 && err.Path.Node(-1).ToNodeAddr == 0 { @@ -173,7 +176,32 @@ func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry old }) } + var curNode nodeInfo cbs := btrfstree.TreeWalkHandler{ + BadNode: func(path btrfstree.TreePath, node *btrfstree.Node, err error) error { + if node != nil { + curNode = nodeInfo{ + LAddr: path.Node(-1).ToNodeAddr, + Level: node.Head.Level, + Generation: node.Head.Generation, + Owner: node.Head.Owner, + MinItem: discardOK(node.MinItem()), + MaxItem: discardOK(node.MaxItem()), + } + } + return err + }, + Node: func(path btrfstree.TreePath, node *btrfstree.Node) error { + curNode = nodeInfo{ + LAddr: path.Node(-1).ToNodeAddr, + Level: node.Head.Level, + Generation: node.Head.Generation, + Owner: node.Head.Owner, + MinItem: discardOK(node.MinItem()), + MaxItem: discardOK(node.MaxItem()), + } + return nil + }, Item: func(path btrfstree.TreePath, item btrfstree.Item) error { if cacheEntry.Items.Search(func(v oldRebuiltTreeValue) int { return item.Key.Compare(v.Key) }) != nil { // This is a panic because I'm not really sure what the best way to @@ -182,9 +210,11 @@ func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry old panic(fmt.Errorf("dup key=%v in tree=%v", item.Key, root.TreeID)) } cacheEntry.Items.Insert(oldRebuiltTreeValue{ - Path: bt.arena.Deflate(path), Key: item.Key, ItemSize: item.BodySize, + + Node: curNode, + Slot: path.Node(-1).FromItemSlot, }) if walked != nil { *walked = append(*walked, item.Key) @@ -217,6 +247,33 @@ func (tree oldRebuiltTree) addErrs(fn func(btrfsprim.Key, uint32) int, err error return errs } +func (bt *OldRebuiltForrest) readNode(nodeInfo nodeInfo) *btrfstree.Node { + sb, err := bt.inner.Superblock() + if err != nil { + panic(fmt.Errorf("should not happen: i/o error: %w", err)) + } + + node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](bt.inner, *sb, nodeInfo.LAddr, btrfstree.NodeExpectations{ + LAddr: containers.Optional[btrfsvol.LogicalAddr]{OK: true, Val: nodeInfo.LAddr}, + Level: containers.Optional[uint8]{OK: true, Val: nodeInfo.Level}, + Generation: containers.Optional[btrfsprim.Generation]{OK: true, Val: nodeInfo.Generation}, + Owner: func(treeID btrfsprim.ObjID) error { + if treeID != nodeInfo.Owner { + return fmt.Errorf("expected owner=%v but claims to have owner=%v", + nodeInfo.Owner, treeID) + } + return nil + }, + MinItem: containers.Optional[btrfsprim.Key]{OK: true, Val: nodeInfo.MinItem}, + MaxItem: containers.Optional[btrfsprim.Key]{OK: true, Val: nodeInfo.MaxItem}, + }) + if err != nil { + panic(fmt.Errorf("should not happen: i/o error: %w", err)) + } + + return node +} + func (bt *OldRebuiltForrest) TreeSearch(treeID btrfsprim.ObjID, searcher btrfstree.TreeSearcher) (btrfstree.Item, error) { tree := bt.RebuiltTree(treeID) if tree.RootErr != nil { @@ -230,14 +287,10 @@ func (bt *OldRebuiltForrest) TreeSearch(treeID btrfsprim.ObjID, searcher btrfstr return btrfstree.Item{}, fmt.Errorf("item with %s: %w", searcher, tree.addErrs(searcher.Search, btrfstree.ErrNoItem)) } - itemPath := bt.arena.Inflate(indexItem.Value.Path) - node, err := bt.inner.ReadNode(itemPath.Parent()) + node := bt.readNode(indexItem.Value.Node) defer node.Free() - if err != nil { - return btrfstree.Item{}, fmt.Errorf("item with %s: %w", searcher, tree.addErrs(searcher.Search, err)) - } - item := node.BodyLeaf[itemPath.Node(-1).FromItemSlot] + item := node.BodyLeaf[indexItem.Value.Slot] item.Body = item.Body.CloneItem() // Since we were only asked to return 1 item, it isn't @@ -266,18 +319,12 @@ func (bt *OldRebuiltForrest) TreeSearchAll(treeID btrfsprim.ObjID, searcher btrf ret := make([]btrfstree.Item, len(indexItems)) var node *btrfstree.Node - for i := range indexItems { - itemPath := bt.arena.Inflate(indexItems[i].Path) - if node == nil || node.Head.Addr != itemPath.Node(-2).ToNodeAddr { - var err error + for i, indexItem := range indexItems { + if node == nil || node.Head.Addr != indexItem.Node.LAddr { node.Free() - node, err = bt.inner.ReadNode(itemPath.Parent()) - if err != nil { - node.Free() - return nil, fmt.Errorf("items with %s: %w", searcher, tree.addErrs(searcher.Search, err)) - } + node = bt.readNode(indexItem.Node) } - ret[i] = node.BodyLeaf[itemPath.Node(-1).FromItemSlot] + ret[i] = node.BodyLeaf[indexItem.Slot] ret[i].Body = ret[i].Body.CloneItem() } node.Free() @@ -312,18 +359,28 @@ func (bt *OldRebuiltForrest) TreeWalk(ctx context.Context, treeID btrfsprim.ObjI if bt.ctx.Err() != nil { return false } - itemPath := bt.arena.Inflate(indexItem.Value.Path) - if node == nil || node.Head.Addr != itemPath.Node(-2).ToNodeAddr { - var err error + if node == nil || node.Head.Addr != indexItem.Value.Node.LAddr { node.Free() - node, err = bt.inner.ReadNode(itemPath.Parent()) - if err != nil { - node.Free() - errHandle(&btrfstree.TreeError{Path: itemPath, Err: err}) - return true - } + node = bt.readNode(indexItem.Value.Node) + } + item := node.BodyLeaf[indexItem.Value.Slot] + + itemPath := btrfstree.TreePath{ + { + FromTree: treeID, + ToNodeAddr: indexItem.Value.Node.LAddr, + ToNodeGeneration: indexItem.Value.Node.Generation, + ToNodeLevel: indexItem.Value.Node.Level, + ToKey: indexItem.Value.Node.MinItem, + ToMaxKey: indexItem.Value.Node.MaxItem, + }, + { + FromTree: indexItem.Value.Node.Owner, + FromItemSlot: indexItem.Value.Slot, + ToKey: indexItem.Value.Key, + ToMaxKey: indexItem.Value.Key, + }, } - item := node.BodyLeaf[itemPath.Node(-1).FromItemSlot] if err := cbs.Item(itemPath, item); err != nil { errHandle(&btrfstree.TreeError{Path: itemPath, Err: err}) } -- cgit v1.2.3-2-g168b From 17e5d1366a77bbe0e8d32b7bf16829a4f855e854 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 10 Mar 2023 15:22:07 -0700 Subject: tree-wide: s/TreePath/Path/g btrfstree.TreePath stutters. --- lib/btrfsutil/old_rebuilt_forrest.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 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 8bc02df..5f6c718 100644 --- a/lib/btrfsutil/old_rebuilt_forrest.go +++ b/lib/btrfsutil/old_rebuilt_forrest.go @@ -178,7 +178,7 @@ func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry old var curNode nodeInfo cbs := btrfstree.TreeWalkHandler{ - BadNode: func(path btrfstree.TreePath, node *btrfstree.Node, err error) error { + BadNode: func(path btrfstree.Path, node *btrfstree.Node, err error) error { if node != nil { curNode = nodeInfo{ LAddr: path.Node(-1).ToNodeAddr, @@ -191,7 +191,7 @@ func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry old } return err }, - Node: func(path btrfstree.TreePath, node *btrfstree.Node) error { + Node: func(path btrfstree.Path, node *btrfstree.Node) error { curNode = nodeInfo{ LAddr: path.Node(-1).ToNodeAddr, Level: node.Head.Level, @@ -202,7 +202,7 @@ func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry old } return nil }, - Item: func(path btrfstree.TreePath, item btrfstree.Item) error { + Item: func(path btrfstree.Path, item btrfstree.Item) error { if cacheEntry.Items.Search(func(v oldRebuiltTreeValue) int { return item.Key.Compare(v.Key) }) != nil { // This is a panic because I'm not really sure what the best way to // handle this is, and so if this happens I want the program to crash @@ -340,7 +340,7 @@ func (bt *OldRebuiltForrest) TreeWalk(ctx context.Context, treeID btrfsprim.ObjI tree := bt.RebuiltTree(treeID) if tree.RootErr != nil { errHandle(&btrfstree.TreeError{ - Path: btrfstree.TreePath{{ + Path: btrfstree.Path{{ FromTree: treeID, ToMaxKey: btrfsprim.MaxKey, }}, @@ -365,7 +365,7 @@ func (bt *OldRebuiltForrest) TreeWalk(ctx context.Context, treeID btrfsprim.ObjI } item := node.BodyLeaf[indexItem.Value.Slot] - itemPath := btrfstree.TreePath{ + itemPath := btrfstree.Path{ { FromTree: treeID, ToNodeAddr: indexItem.Value.Node.LAddr, -- cgit v1.2.3-2-g168b From ceb9041cc7c838b3833ebc20cd97b02fbd3c92b3 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Thu, 2 Mar 2023 20:43:48 -0700 Subject: btrfsutil: OldRebuildForrest: Drop the Augment method --- lib/btrfsutil/old_rebuilt_forrest.go | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 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 5f6c718..f59a1f9 100644 --- a/lib/btrfsutil/old_rebuilt_forrest.go +++ b/lib/btrfsutil/old_rebuilt_forrest.go @@ -148,7 +148,7 @@ func (bt *OldRebuiltForrest) RebuiltTree(treeID btrfsprim.ObjID) oldRebuiltTree cacheEntry.RootErr = err } else { dlog.Infof(bt.ctx, "indexing tree %v...", treeID) - bt.rawTreeWalk(*treeRoot, cacheEntry, nil) + bt.rawTreeWalk(*treeRoot, cacheEntry) dlog.Infof(bt.ctx, "... done indexing tree %v", treeID) } @@ -162,7 +162,7 @@ func (bt *OldRebuiltForrest) RebuiltTree(treeID btrfsprim.ObjID) oldRebuiltTree func discardOK[T any](x T, _ bool) T { return x } -func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry oldRebuiltTree, walked *[]btrfsprim.Key) { +func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry oldRebuiltTree) { errHandle := func(err *btrfstree.TreeError) { if len(err.Path) > 0 && err.Path.Node(-1).ToNodeAddr == 0 { // This is a panic because on the filesystems I'm working with it more likely @@ -216,9 +216,6 @@ func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry old Node: curNode, Slot: path.Node(-1).FromItemSlot, }) - if walked != nil { - *walked = append(*walked, item.Key) - } return nil }, } @@ -396,27 +393,3 @@ func (bt *OldRebuiltForrest) Superblock() (*btrfstree.Superblock, error) { func (bt *OldRebuiltForrest) ReadAt(p []byte, off btrfsvol.LogicalAddr) (int, error) { return bt.inner.ReadAt(p, off) } - -func (bt *OldRebuiltForrest) Augment(treeID btrfsprim.ObjID, nodeAddr btrfsvol.LogicalAddr) ([]btrfsprim.Key, error) { - sb, err := bt.Superblock() - if err != nil { - return nil, err - } - tree := bt.RebuiltTree(treeID) - if tree.RootErr != nil { - return nil, tree.RootErr - } - node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](bt.inner, *sb, nodeAddr, btrfstree.NodeExpectations{}) - defer node.Free() - if err != nil { - return nil, err - } - var ret []btrfsprim.Key - bt.rawTreeWalk(btrfstree.TreeRoot{ - TreeID: treeID, - RootNode: nodeAddr, - Level: node.Head.Level, - Generation: node.Head.Generation, - }, tree, &ret) - return ret, nil -} -- cgit v1.2.3-2-g168b From 26e58f1cd1d47b63b1b05b26c73c4f69f7e245cb Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 13 Mar 2023 18:52:51 -0600 Subject: btrfsutil: OldRebuiltForrest: Hoist logic from .RebuiltTree to .rawTreeWalk It's OK that for ROOT_TREE_OBJECTID it now calls btrfstree.LookupTreeRoot on `bt` instead of `bt.inner`, because LookupTreeRoot doesn't actually use that argument for ROOT_TREE_OBJECTID. --- lib/btrfsutil/old_rebuilt_forrest.go | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 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 f59a1f9..c146935 100644 --- a/lib/btrfsutil/old_rebuilt_forrest.go +++ b/lib/btrfsutil/old_rebuilt_forrest.go @@ -115,19 +115,12 @@ func NewOldRebuiltForrest(ctx context.Context, inner *btrfs.FS) *OldRebuiltForre } func (bt *OldRebuiltForrest) RebuiltTree(treeID btrfsprim.ObjID) oldRebuiltTree { - var treeRoot *btrfstree.TreeRoot - var sb *btrfstree.Superblock - var err error if treeID == btrfsprim.ROOT_TREE_OBJECTID { bt.rootTreeMu.Lock() defer bt.rootTreeMu.Unlock() if bt.rootTree != nil { return *bt.rootTree } - sb, err = bt.inner.Superblock() - if err == nil { - treeRoot, err = btrfstree.LookupTreeRoot(bt.inner, *sb, treeID) - } } else { bt.treesMu.Lock() defer bt.treesMu.Unlock() @@ -137,20 +130,12 @@ func (bt *OldRebuiltForrest) RebuiltTree(treeID btrfsprim.ObjID) oldRebuiltTree if cacheEntry, exists := bt.trees[treeID]; exists { return cacheEntry } - sb, err = bt.inner.Superblock() - if err == nil { - treeRoot, err = btrfstree.LookupTreeRoot(bt, *sb, treeID) - } } cacheEntry := newOldRebuiltTree() - if err != nil { - cacheEntry.RootErr = err - } else { - dlog.Infof(bt.ctx, "indexing tree %v...", treeID) - bt.rawTreeWalk(*treeRoot, cacheEntry) - dlog.Infof(bt.ctx, "... done indexing tree %v", treeID) - } + dlog.Infof(bt.ctx, "indexing tree %v...", treeID) + bt.rawTreeWalk(treeID, &cacheEntry) + dlog.Infof(bt.ctx, "... done indexing tree %v", treeID) if treeID == btrfsprim.ROOT_TREE_OBJECTID { bt.rootTree = &cacheEntry @@ -162,7 +147,18 @@ func (bt *OldRebuiltForrest) RebuiltTree(treeID btrfsprim.ObjID) oldRebuiltTree func discardOK[T any](x T, _ bool) T { return x } -func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry oldRebuiltTree) { +func (bt *OldRebuiltForrest) rawTreeWalk(treeID btrfsprim.ObjID, cacheEntry *oldRebuiltTree) { + sb, err := bt.inner.Superblock() + if err != nil { + cacheEntry.RootErr = err + return + } + root, err := btrfstree.LookupTreeRoot(bt, *sb, treeID) + if err != nil { + cacheEntry.RootErr = err + return + } + errHandle := func(err *btrfstree.TreeError) { if len(err.Path) > 0 && err.Path.Node(-1).ToNodeAddr == 0 { // This is a panic because on the filesystems I'm working with it more likely @@ -220,7 +216,7 @@ func (bt *OldRebuiltForrest) rawTreeWalk(root btrfstree.TreeRoot, cacheEntry old }, } - btrfstree.TreeOperatorImpl{NodeSource: bt.inner}.RawTreeWalk(bt.ctx, root, errHandle, cbs) + btrfstree.TreeOperatorImpl{NodeSource: bt.inner}.RawTreeWalk(bt.ctx, *root, errHandle, cbs) } func (bt *OldRebuiltForrest) TreeLookup(treeID btrfsprim.ObjID, key btrfsprim.Key) (btrfstree.Item, error) { -- 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 --- lib/btrfsutil/old_rebuilt_forrest.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 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 c146935..abe3329 100644 --- a/lib/btrfsutil/old_rebuilt_forrest.go +++ b/lib/btrfsutil/old_rebuilt_forrest.go @@ -247,9 +247,9 @@ func (bt *OldRebuiltForrest) readNode(nodeInfo nodeInfo) *btrfstree.Node { } node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](bt.inner, *sb, nodeInfo.LAddr, btrfstree.NodeExpectations{ - LAddr: containers.Optional[btrfsvol.LogicalAddr]{OK: true, Val: nodeInfo.LAddr}, - Level: containers.Optional[uint8]{OK: true, Val: nodeInfo.Level}, - Generation: containers.Optional[btrfsprim.Generation]{OK: true, Val: nodeInfo.Generation}, + LAddr: containers.OptionalValue(nodeInfo.LAddr), + Level: containers.OptionalValue(nodeInfo.Level), + Generation: containers.OptionalValue(nodeInfo.Generation), Owner: func(treeID btrfsprim.ObjID) error { if treeID != nodeInfo.Owner { return fmt.Errorf("expected owner=%v but claims to have owner=%v", @@ -257,8 +257,8 @@ func (bt *OldRebuiltForrest) readNode(nodeInfo nodeInfo) *btrfstree.Node { } return nil }, - MinItem: containers.Optional[btrfsprim.Key]{OK: true, Val: nodeInfo.MinItem}, - MaxItem: containers.Optional[btrfsprim.Key]{OK: true, Val: nodeInfo.MaxItem}, + MinItem: containers.OptionalValue(nodeInfo.MinItem), + MaxItem: containers.OptionalValue(nodeInfo.MaxItem), }) if err != nil { panic(fmt.Errorf("should not happen: i/o error: %w", err)) -- cgit v1.2.3-2-g168b