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/rebuilt_readitem.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'lib/btrfsutil/rebuilt_readitem.go') 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))) -- cgit v1.2.3-2-g168b From d7a616119a4f5fbfa8d0f028e337037a48272048 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 28 Feb 2023 23:50:32 -0700 Subject: rebuildtrees: Move item-data from btrfsutil.KeyIO to scan --- lib/btrfsutil/rebuilt_readitem.go | 69 ++------------------------------------- 1 file changed, 2 insertions(+), 67 deletions(-) (limited to 'lib/btrfsutil/rebuilt_readitem.go') diff --git a/lib/btrfsutil/rebuilt_readitem.go b/lib/btrfsutil/rebuilt_readitem.go index b1a0656..7e9be09 100644 --- a/lib/btrfsutil/rebuilt_readitem.go +++ b/lib/btrfsutil/rebuilt_readitem.go @@ -29,37 +29,20 @@ func (ptr ItemPtr) String() string { return fmt.Sprintf("node@%v[%v]", ptr.Node, ptr.Slot) } -type SizeAndErr struct { - Size uint64 - Err error -} - -type FlagsAndErr struct { - NoDataSum bool - Err error -} - type KeyIO struct { rawFile diskio.File[btrfsvol.LogicalAddr] sb btrfstree.Superblock graph Graph - Flags map[ItemPtr]FlagsAndErr // INODE_ITEM - Names map[ItemPtr][]byte // DIR_INDEX - Sizes map[ItemPtr]SizeAndErr // EXTENT_CSUM and EXTENT_DATA - mu sync.Mutex cache containers.ARCache[btrfsvol.LogicalAddr, *btrfstree.Node] } -func NewKeyIO(file diskio.File[btrfsvol.LogicalAddr], sb btrfstree.Superblock) *KeyIO { +func NewKeyIO(file diskio.File[btrfsvol.LogicalAddr], sb btrfstree.Superblock, graph Graph) *KeyIO { return &KeyIO{ rawFile: file, sb: sb, - - Flags: make(map[ItemPtr]FlagsAndErr), - Names: make(map[ItemPtr][]byte), - Sizes: make(map[ItemPtr]SizeAndErr), + graph: graph, cache: containers.ARCache[btrfsvol.LogicalAddr, *btrfstree.Node]{ MaxLen: textui.Tunable(8), @@ -70,54 +53,6 @@ func NewKeyIO(file diskio.File[btrfsvol.LogicalAddr], sb btrfstree.Superblock) * } } -func (o *KeyIO) InsertNode(node *btrfstree.Node) { - for i, item := range node.BodyLeaf { - ptr := ItemPtr{ - Node: node.Head.Addr, - Slot: i, - } - switch itemBody := item.Body.(type) { - case *btrfsitem.Inode: - o.Flags[ptr] = FlagsAndErr{ - NoDataSum: itemBody.Flags.Has(btrfsitem.INODE_NODATASUM), - Err: nil, - } - case *btrfsitem.DirEntry: - if item.Key.ItemType == btrfsprim.DIR_INDEX_KEY { - o.Names[ptr] = append([]byte(nil), itemBody.Name...) - } - case *btrfsitem.ExtentCSum: - o.Sizes[ptr] = SizeAndErr{ - Size: uint64(itemBody.Size()), - Err: nil, - } - case *btrfsitem.FileExtent: - size, err := itemBody.Size() - o.Sizes[ptr] = SizeAndErr{ - Size: uint64(size), - Err: err, - } - case *btrfsitem.Error: - switch item.Key.ItemType { - case btrfsprim.INODE_ITEM_KEY: - o.Flags[ptr] = FlagsAndErr{ - Err: fmt.Errorf("error decoding item: ptr=%v (tree=%v key=%v): %w", - 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, node.Head.Owner, item.Key, itemBody.Err), - } - } - } - } -} - -func (o *KeyIO) SetGraph(graph Graph) { - o.graph = graph -} - 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) -- cgit v1.2.3-2-g168b From 8b17537fc562ef422aee7976cf4a44dd040900aa Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 4 Mar 2023 11:07:37 -0700 Subject: btrfsutil: Merge KeyIO in to RebuiltForrest --- lib/btrfsutil/rebuilt_readitem.go | 53 ++++++++++----------------------------- 1 file changed, 13 insertions(+), 40 deletions(-) (limited to 'lib/btrfsutil/rebuilt_readitem.go') diff --git a/lib/btrfsutil/rebuilt_readitem.go b/lib/btrfsutil/rebuilt_readitem.go index 7e9be09..68aabdd 100644 --- a/lib/btrfsutil/rebuilt_readitem.go +++ b/lib/btrfsutil/rebuilt_readitem.go @@ -7,7 +7,6 @@ package btrfsutil import ( "context" "fmt" - "sync" "github.com/datawire/dlib/dlog" @@ -16,8 +15,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/textui" ) type ItemPtr struct { @@ -29,43 +26,19 @@ func (ptr ItemPtr) String() string { return fmt.Sprintf("node@%v[%v]", ptr.Node, ptr.Slot) } -type KeyIO struct { - rawFile diskio.File[btrfsvol.LogicalAddr] - sb btrfstree.Superblock - graph Graph - - mu sync.Mutex - cache containers.ARCache[btrfsvol.LogicalAddr, *btrfstree.Node] -} - -func NewKeyIO(file diskio.File[btrfsvol.LogicalAddr], sb btrfstree.Superblock, graph Graph) *KeyIO { - return &KeyIO{ - rawFile: file, - sb: sb, - graph: graph, - - cache: containers.ARCache[btrfsvol.LogicalAddr, *btrfstree.Node]{ - MaxLen: textui.Tunable(8), - OnRemove: func(_ btrfsvol.LogicalAddr, node *btrfstree.Node) { - node.Free() - }, - }, - } -} - -func (o *KeyIO) readNode(ctx context.Context, laddr btrfsvol.LogicalAddr) *btrfstree.Node { - if cached, ok := o.cache.Load(laddr); ok { +func (ts *RebuiltForrest) readNode(ctx context.Context, laddr btrfsvol.LogicalAddr) *btrfstree.Node { + if cached, ok := ts.nodes.Load(laddr); ok { dlog.Tracef(ctx, "cache-hit node@%v", laddr) return cached } - graphInfo, ok := o.graph.Nodes[laddr] + graphInfo, ok := ts.graph.Nodes[laddr] if !ok { panic(fmt.Errorf("should not happen: node@%v is not mentioned in the in-memory graph", laddr)) } dlog.Debugf(ctx, "cache-miss node@%v, reading...", laddr) - node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](o.rawFile, o.sb, laddr, btrfstree.NodeExpectations{ + node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](ts.file, ts.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}, @@ -83,23 +56,23 @@ func (o *KeyIO) readNode(ctx context.Context, laddr btrfsvol.LogicalAddr) *btrfs panic(fmt.Errorf("should not happen: i/o error: %w", err)) } - o.cache.Store(laddr, node) + ts.nodes.Store(laddr, node) return node } -func (o *KeyIO) ReadItem(ctx context.Context, ptr ItemPtr) btrfsitem.Item { - o.mu.Lock() - defer o.mu.Unlock() - if o.graph.Nodes[ptr.Node].Level != 0 { - panic(fmt.Errorf("should not happen: btrfsutil.KeyIO.ReadItem called for non-leaf node@%v", ptr.Node)) +func (ts *RebuiltForrest) readItem(ctx context.Context, ptr ItemPtr) btrfsitem.Item { + ts.nodesMu.Lock() + defer ts.nodesMu.Unlock() + if ts.graph.Nodes[ptr.Node].Level != 0 { + panic(fmt.Errorf("should not happen: btrfsutil.RebuiltForrest.readItem called for non-leaf node@%v", ptr.Node)) } if ptr.Slot < 0 { - panic(fmt.Errorf("should not happen: btrfsutil.KeyIO.ReadItem called for negative item slot: %v", ptr.Slot)) + panic(fmt.Errorf("should not happen: btrfsutil.RebuiltForrest.readItem called for negative item slot: %v", ptr.Slot)) } - items := o.readNode(ctx, ptr.Node).BodyLeaf + items := ts.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", + panic(fmt.Errorf("should not happen: btrfsutil.RebuiltForrest.readItem called for out-of-bounds item slot: slot=%v len=%v", ptr.Slot, len(items))) } return items[ptr.Slot].Body.CloneItem() -- 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/rebuilt_readitem.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/btrfsutil/rebuilt_readitem.go') diff --git a/lib/btrfsutil/rebuilt_readitem.go b/lib/btrfsutil/rebuilt_readitem.go index 68aabdd..ff919f0 100644 --- a/lib/btrfsutil/rebuilt_readitem.go +++ b/lib/btrfsutil/rebuilt_readitem.go @@ -39,9 +39,9 @@ func (ts *RebuiltForrest) readNode(ctx context.Context, laddr btrfsvol.LogicalAd dlog.Debugf(ctx, "cache-miss node@%v, reading...", laddr) node, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](ts.file, ts.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}, + LAddr: containers.OptionalValue(laddr), + Level: containers.OptionalValue(graphInfo.Level), + Generation: containers.OptionalValue(graphInfo.Generation), Owner: func(treeID btrfsprim.ObjID) error { if treeID != graphInfo.Owner { return fmt.Errorf("expected owner=%v but claims to have owner=%v", @@ -49,8 +49,8 @@ func (ts *RebuiltForrest) readNode(ctx context.Context, laddr btrfsvol.LogicalAd } return nil }, - MinItem: containers.Optional[btrfsprim.Key]{OK: true, Val: graphInfo.MinItem()}, - MaxItem: containers.Optional[btrfsprim.Key]{OK: true, Val: graphInfo.MaxItem()}, + MinItem: containers.OptionalValue(graphInfo.MinItem()), + MaxItem: containers.OptionalValue(graphInfo.MaxItem()), }) if err != nil { panic(fmt.Errorf("should not happen: i/o error: %w", err)) -- cgit v1.2.3-2-g168b