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/graph.go | 32 +++++++++++++++---------------- lib/btrfsutil/listnodes.go | 5 ++--- lib/btrfsutil/old_rebuilt_forrest.go | 37 ++++++++++++++++++------------------ lib/btrfsutil/rebuilt_readitem.go | 28 +++++++++++++-------------- lib/btrfsutil/scan.go | 9 ++++----- lib/btrfsutil/skinny_paths.go | 24 +++++++++++------------ 6 files changed, 66 insertions(+), 69 deletions(-) (limited to 'lib/btrfsutil') diff --git a/lib/btrfsutil/graph.go b/lib/btrfsutil/graph.go index 09a17b4..a7c299a 100644 --- a/lib/btrfsutil/graph.go +++ b/lib/btrfsutil/graph.go @@ -149,29 +149,29 @@ func NewGraph(sb btrfstree.Superblock) *Graph { return g } -func (g Graph) InsertNode(nodeRef *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.Node]) { +func (g Graph) InsertNode(node *btrfstree.Node) { nodeData := GraphNode{ - Level: nodeRef.Data.Head.Level, - Generation: nodeRef.Data.Head.Generation, - Owner: nodeRef.Data.Head.Owner, + Level: node.Head.Level, + Generation: node.Head.Generation, + Owner: node.Head.Owner, } - if nodeRef.Data.Head.Level == 0 { + if node.Head.Level == 0 { cnt := 0 - for _, item := range nodeRef.Data.BodyLeaf { + for _, item := range node.BodyLeaf { if _, ok := item.Body.(*btrfsitem.Root); ok { cnt++ } } kps := make([]GraphEdge, 0, cnt) - keys := make([]btrfsprim.Key, len(nodeRef.Data.BodyLeaf)) + keys := make([]btrfsprim.Key, len(node.BodyLeaf)) nodeData.Items = keys - g.Nodes[nodeRef.Addr] = nodeData - for i, item := range nodeRef.Data.BodyLeaf { + g.Nodes[node.Head.Addr] = nodeData + for i, item := range node.BodyLeaf { keys[i] = item.Key if itemBody, ok := item.Body.(*btrfsitem.Root); ok { kps = append(kps, GraphEdge{ - FromRoot: nodeRef.Addr, + FromRoot: node.Head.Addr, FromItem: i, FromTree: item.Key.ObjectID, ToNode: itemBody.ByteNr, @@ -182,15 +182,15 @@ func (g Graph) InsertNode(nodeRef *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.No } } } else { - g.Nodes[nodeRef.Addr] = nodeData - kps := make([]GraphEdge, len(nodeRef.Data.BodyInterior)) - for i, kp := range nodeRef.Data.BodyInterior { + g.Nodes[node.Head.Addr] = nodeData + kps := make([]GraphEdge, len(node.BodyInterior)) + for i, kp := range node.BodyInterior { kps[i] = GraphEdge{ - FromNode: nodeRef.Addr, + FromNode: node.Head.Addr, FromItem: i, - FromTree: nodeRef.Data.Head.Owner, + FromTree: node.Head.Owner, ToNode: kp.BlockPtr, - ToLevel: nodeRef.Data.Head.Level - 1, + ToLevel: node.Head.Level - 1, ToKey: kp.Key, ToGeneration: kp.Generation, } diff --git a/lib/btrfsutil/listnodes.go b/lib/btrfsutil/listnodes.go index 5505d23..70b647c 100644 --- a/lib/btrfsutil/listnodes.go +++ b/lib/btrfsutil/listnodes.go @@ -11,7 +11,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" "git.lukeshu.com/btrfs-progs-ng/lib/maps" "git.lukeshu.com/btrfs-progs-ng/lib/textui" ) @@ -44,8 +43,8 @@ func (*nodeScanner) ScanSector(context.Context, *btrfs.Device, btrfsvol.Physical return nil } -func (s *nodeScanner) ScanNode(_ context.Context, nodeRef *diskio.Ref[btrfsvol.PhysicalAddr, btrfstree.Node]) error { - s.nodes.Insert(nodeRef.Data.Head.Addr) +func (s *nodeScanner) ScanNode(_ context.Context, _ btrfsvol.PhysicalAddr, node *btrfstree.Node) error { + s.nodes.Insert(node.Head.Addr) return nil } 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 } diff --git a/lib/btrfsutil/rebuilt_readitem.go b/lib/btrfsutil/rebuilt_readitem.go index 016299c..b1a0656 100644 --- a/lib/btrfsutil/rebuilt_readitem.go +++ b/lib/btrfsutil/rebuilt_readitem.go @@ -49,7 +49,7 @@ type KeyIO struct { Sizes map[ItemPtr]SizeAndErr // EXTENT_CSUM and EXTENT_DATA mu sync.Mutex - cache containers.ARCache[btrfsvol.LogicalAddr, *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.Node]] + cache containers.ARCache[btrfsvol.LogicalAddr, *btrfstree.Node] } func NewKeyIO(file diskio.File[btrfsvol.LogicalAddr], sb btrfstree.Superblock) *KeyIO { @@ -61,19 +61,19 @@ func NewKeyIO(file diskio.File[btrfsvol.LogicalAddr], sb btrfstree.Superblock) * Names: make(map[ItemPtr][]byte), Sizes: make(map[ItemPtr]SizeAndErr), - cache: containers.ARCache[btrfsvol.LogicalAddr, *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.Node]]{ + cache: containers.ARCache[btrfsvol.LogicalAddr, *btrfstree.Node]{ MaxLen: textui.Tunable(8), - OnRemove: func(_ btrfsvol.LogicalAddr, nodeRef *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.Node]) { - btrfstree.FreeNodeRef(nodeRef) + OnRemove: func(_ btrfsvol.LogicalAddr, node *btrfstree.Node) { + node.Free() }, }, } } -func (o *KeyIO) InsertNode(nodeRef *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.Node]) { - for i, item := range nodeRef.Data.BodyLeaf { +func (o *KeyIO) InsertNode(node *btrfstree.Node) { + for i, item := range node.BodyLeaf { ptr := ItemPtr{ - Node: nodeRef.Addr, + Node: node.Head.Addr, Slot: i, } switch itemBody := item.Body.(type) { @@ -102,12 +102,12 @@ func (o *KeyIO) InsertNode(nodeRef *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.N case btrfsprim.INODE_ITEM_KEY: o.Flags[ptr] = FlagsAndErr{ Err: fmt.Errorf("error decoding item: ptr=%v (tree=%v key=%v): %w", - ptr, nodeRef.Data.Head.Owner, item.Key, itemBody.Err), + ptr, node.Head.Owner, item.Key, itemBody.Err), } case btrfsprim.EXTENT_CSUM_KEY, btrfsprim.EXTENT_DATA_KEY: o.Sizes[ptr] = SizeAndErr{ Err: fmt.Errorf("error decoding item: ptr=%v (tree=%v key=%v): %w", - ptr, nodeRef.Data.Head.Owner, item.Key, itemBody.Err), + ptr, node.Head.Owner, item.Key, itemBody.Err), } } } @@ -118,7 +118,7 @@ func (o *KeyIO) SetGraph(graph Graph) { o.graph = graph } -func (o *KeyIO) readNode(ctx context.Context, laddr btrfsvol.LogicalAddr) *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.Node] { +func (o *KeyIO) readNode(ctx context.Context, laddr btrfsvol.LogicalAddr) *btrfstree.Node { if cached, ok := o.cache.Load(laddr); ok { dlog.Tracef(ctx, "cache-hit node@%v", laddr) return cached @@ -130,7 +130,7 @@ func (o *KeyIO) readNode(ctx context.Context, laddr btrfsvol.LogicalAddr) *diski } dlog.Debugf(ctx, "cache-miss node@%v, reading...", laddr) - ref, err := btrfstree.ReadNode(o.rawFile, o.sb, laddr, btrfstree.NodeExpectations{ + node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](o.rawFile, o.sb, laddr, btrfstree.NodeExpectations{ LAddr: containers.Optional[btrfsvol.LogicalAddr]{OK: true, Val: laddr}, Level: containers.Optional[uint8]{OK: true, Val: graphInfo.Level}, Generation: containers.Optional[btrfsprim.Generation]{OK: true, Val: graphInfo.Generation}, @@ -148,9 +148,9 @@ func (o *KeyIO) readNode(ctx context.Context, laddr btrfsvol.LogicalAddr) *diski panic(fmt.Errorf("should not happen: i/o error: %w", err)) } - o.cache.Store(laddr, ref) + o.cache.Store(laddr, node) - return ref + return node } func (o *KeyIO) ReadItem(ctx context.Context, ptr ItemPtr) btrfsitem.Item { @@ -162,7 +162,7 @@ func (o *KeyIO) ReadItem(ctx context.Context, ptr ItemPtr) btrfsitem.Item { if ptr.Slot < 0 { panic(fmt.Errorf("should not happen: btrfsutil.KeyIO.ReadItem called for negative item slot: %v", ptr.Slot)) } - items := o.readNode(ctx, ptr.Node).Data.BodyLeaf + items := o.readNode(ctx, ptr.Node).BodyLeaf if ptr.Slot >= len(items) { panic(fmt.Errorf("should not happen: btrfsutil.KeyIO.ReadItem called for out-of-bounds item slot: slot=%v len=%v", ptr.Slot, len(items))) diff --git a/lib/btrfsutil/scan.go b/lib/btrfsutil/scan.go index 97220aa..05b27d5 100644 --- a/lib/btrfsutil/scan.go +++ b/lib/btrfsutil/scan.go @@ -19,7 +19,6 @@ import ( "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/diskio" "git.lukeshu.com/btrfs-progs-ng/lib/textui" ) @@ -30,7 +29,7 @@ type DeviceScannerFactory[Stats comparable, Result any] func(ctx context.Context type DeviceScanner[Stats comparable, Result any] interface { ScanStats() Stats ScanSector(ctx context.Context, dev *btrfs.Device, paddr btrfsvol.PhysicalAddr) error - ScanNode(ctx context.Context, nodeRef *diskio.Ref[btrfsvol.PhysicalAddr, btrfstree.Node]) error + ScanNode(ctx context.Context, addr btrfsvol.PhysicalAddr, node *btrfstree.Node) error ScanDone(ctx context.Context) (Result, error) } @@ -123,19 +122,19 @@ func ScanOneDevice[Stats comparable, Result any](ctx context.Context, dev *btrfs } if checkForNode { - nodeRef, err := btrfstree.ReadNode[btrfsvol.PhysicalAddr](dev, *sb, pos, btrfstree.NodeExpectations{}) + node, err := btrfstree.ReadNode[btrfsvol.PhysicalAddr](dev, *sb, pos, btrfstree.NodeExpectations{}) if err != nil { if !errors.Is(err, btrfstree.ErrNotANode) { dlog.Errorf(ctx, "error: %v", err) } } else { - if err := scanner.ScanNode(ctx, nodeRef); err != nil { + if err := scanner.ScanNode(ctx, pos, node); err != nil { var zero Result return zero, err } minNextNode = pos + btrfsvol.PhysicalAddr(sb.NodeSize) } - btrfstree.FreeNodeRef(nodeRef) + node.Free() } } diff --git a/lib/btrfsutil/skinny_paths.go b/lib/btrfsutil/skinny_paths.go index adf539b..1361fff 100644 --- a/lib/btrfsutil/skinny_paths.go +++ b/lib/btrfsutil/skinny_paths.go @@ -54,26 +54,26 @@ func (a *SkinnyPathArena) getItem(parent btrfstree.TreePath, itemSlot int) (btrf return ret, nil } - node, err := btrfstree.ReadNode(a.FS, a.SB, parent.Node(-1).ToNodeAddr, btrfstree.NodeExpectations{}) - defer btrfstree.FreeNodeRef(node) + node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](a.FS, a.SB, parent.Node(-1).ToNodeAddr, btrfstree.NodeExpectations{}) + defer node.Free() if err != nil { return btrfstree.TreePathElem{}, err } - if node.Data.Head.Level > 0 { - if itemSlot >= len(node.Data.BodyInterior) { + if node.Head.Level > 0 { + if itemSlot >= len(node.BodyInterior) { panic("should not happen") } - for i, item := range node.Data.BodyInterior { + for i, item := range node.BodyInterior { toMaxKey := parent.Node(-1).ToMaxKey - if i+1 < len(node.Data.BodyInterior) { - toMaxKey = node.Data.BodyInterior[i+1].Key.Mm() + if i+1 < len(node.BodyInterior) { + toMaxKey = node.BodyInterior[i+1].Key.Mm() } elem := btrfstree.TreePathElem{ - FromTree: node.Data.Head.Owner, + FromTree: node.Head.Owner, FromItemSlot: i, ToNodeAddr: item.BlockPtr, ToNodeGeneration: item.Generation, - ToNodeLevel: node.Data.Head.Level - 1, + ToNodeLevel: node.Head.Level - 1, ToKey: item.Key, ToMaxKey: toMaxKey, } @@ -83,12 +83,12 @@ func (a *SkinnyPathArena) getItem(parent btrfstree.TreePath, itemSlot int) (btrf } } } else { - if itemSlot >= len(node.Data.BodyLeaf) { + if itemSlot >= len(node.BodyLeaf) { panic("should not happen") } - for i, item := range node.Data.BodyLeaf { + for i, item := range node.BodyLeaf { elem := btrfstree.TreePathElem{ - FromTree: node.Data.Head.Owner, + FromTree: node.Head.Owner, FromItemSlot: i, ToKey: item.Key, ToMaxKey: item.Key, -- cgit v1.2.3-2-g168b