summaryrefslogtreecommitdiff
path: root/lib/btrfsprogs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/btrfsprogs')
-rw-r--r--lib/btrfsprogs/btrfsinspect/rebuildnodes/btrees/rebuilt_btrees.go16
-rw-r--r--lib/btrfsprogs/btrfsinspect/rebuildnodes/keyio/keyio.go6
-rw-r--r--lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go32
-rw-r--r--lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild_graph.go10
4 files changed, 39 insertions, 25 deletions
diff --git a/lib/btrfsprogs/btrfsinspect/rebuildnodes/btrees/rebuilt_btrees.go b/lib/btrfsprogs/btrfsinspect/rebuildnodes/btrees/rebuilt_btrees.go
index b53a28e..b1ae7be 100644
--- a/lib/btrfsprogs/btrfsinspect/rebuildnodes/btrees/rebuilt_btrees.go
+++ b/lib/btrfsprogs/btrfsinspect/rebuildnodes/btrees/rebuilt_btrees.go
@@ -363,15 +363,23 @@ func (tree *rebuiltTree) indexNode(graph pkggraph.Graph, node btrfsvol.LogicalAd
}
}
+// Resolve a key to a keyio.ItemPtr.
+//
+// It is not nescessary to call AddTree for that tree first; Resolve will
+// call it for you.
+func (ts *RebuiltTrees) Resolve(ctx context.Context, treeID btrfsprim.ObjID, key btrfsprim.Key) (ptr keyio.ItemPtr, ok bool) {
+ if !ts.AddTree(ctx, treeID) {
+ return keyio.ItemPtr{}, false
+ }
+ return ts.trees[treeID].Items.Load(key)
+}
+
// Load reads an item from a tree.
//
// It is not nescessary to call AddTree for that tree first; Load will
// call it for you.
func (ts *RebuiltTrees) Load(ctx context.Context, treeID btrfsprim.ObjID, key btrfsprim.Key) (item btrfsitem.Item, ok bool) {
- if !ts.AddTree(ctx, treeID) {
- return nil, false
- }
- ptr, ok := ts.trees[treeID].Items.Load(key)
+ ptr, ok := ts.Resolve(ctx, treeID, key)
if !ok {
return nil, false
}
diff --git a/lib/btrfsprogs/btrfsinspect/rebuildnodes/keyio/keyio.go b/lib/btrfsprogs/btrfsinspect/rebuildnodes/keyio/keyio.go
index 24c3dcf..eb03004 100644
--- a/lib/btrfsprogs/btrfsinspect/rebuildnodes/keyio/keyio.go
+++ b/lib/btrfsprogs/btrfsinspect/rebuildnodes/keyio/keyio.go
@@ -39,6 +39,7 @@ type Handle struct {
sb btrfstree.Superblock
graph graph.Graph
+ Names map[ItemPtr][]byte
Sizes map[ItemPtr]SizeAndErr
cache *containers.LRUCache[btrfsvol.LogicalAddr, *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.Node]]
@@ -49,6 +50,7 @@ func NewHandle(file diskio.File[btrfsvol.LogicalAddr], sb btrfstree.Superblock)
rawFile: file,
sb: sb,
+ Names: make(map[ItemPtr][]byte),
Sizes: make(map[ItemPtr]SizeAndErr),
cache: containers.NewLRUCache[btrfsvol.LogicalAddr, *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.Node]](textui.Tunable(8)),
@@ -62,6 +64,10 @@ func (o *Handle) InsertNode(nodeRef *diskio.Ref[btrfsvol.LogicalAddr, btrfstree.
Idx: i,
}
switch itemBody := item.Body.(type) {
+ 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()),
diff --git a/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go b/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go
index 7e55732..4f5990e 100644
--- a/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go
+++ b/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go
@@ -5,6 +5,7 @@
package rebuildnodes
import (
+ "bytes"
"context"
"fmt"
"sort"
@@ -456,12 +457,7 @@ func (o *rebuilder) _wantOff(ctx context.Context, treeID btrfsprim.ObjID, tgt bt
return false
}
-// wantFunc implements rebuildCallbacks.
-func (o *rebuilder) wantFunc(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, typ btrfsprim.ItemType, fn func(btrfsitem.Item) bool) {
- ctx = dlog.WithField(ctx, "btrfsinspect.rebuild-nodes.rebuild.want.reason", reason)
- ctx = dlog.WithField(ctx, "btrfsinspect.rebuild-nodes.rebuild.want.key",
- fmt.Sprintf("tree=%v key={%v %v ?} +func", treeID, objID, typ))
-
+func (o *rebuilder) _wantFunc(ctx context.Context, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, typ btrfsprim.ItemType, fn func(keyio.ItemPtr) bool) {
if !o.rebuilt.AddTree(ctx, treeID) {
o.itemQueue = append(o.itemQueue, o.curKey)
return
@@ -478,11 +474,11 @@ func (o *rebuilder) wantFunc(ctx context.Context, reason string, treeID btrfspri
return tgt.Cmp(key)
})
for _, itemKey := range keys {
- itemBody, ok := o.rebuilt.Load(ctx, treeID, itemKey)
+ itemPtr, ok := o.rebuilt.Resolve(ctx, treeID, itemKey)
if !ok {
- o.ioErr(ctx, fmt.Errorf("could not read previously read item: %v", itemKey))
+ o.ioErr(ctx, fmt.Errorf("could not resolve previously read item: %v", itemKey))
}
- if fn(itemBody) {
+ if fn(itemPtr) {
return
}
}
@@ -493,11 +489,7 @@ func (o *rebuilder) wantFunc(ctx context.Context, reason string, treeID btrfspri
o.rebuilt.Keys(treeID).Subrange(
func(k btrfsprim.Key, _ keyio.ItemPtr) int { k.Offset = 0; return tgt.Cmp(k) },
func(k btrfsprim.Key, v keyio.ItemPtr) bool {
- itemBody, ok := o.keyIO.ReadItem(ctx, v)
- if !ok {
- o.ioErr(ctx, fmt.Errorf("could not read previously read item: %v at %v", k, v))
- }
- if fn(itemBody) {
+ if fn(v) {
wants.InsertFrom(o.rebuilt.LeafToRoots(ctx, treeID, v.Node))
}
return true
@@ -505,6 +497,18 @@ func (o *rebuilder) wantFunc(ctx context.Context, reason string, treeID btrfspri
o.wantAugment(ctx, treeID, wants)
}
+// wantDirIndex implements rebuildCallbacks.
+func (o *rebuilder) wantDirIndex(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, name []byte) {
+ typ := btrfsitem.DIR_INDEX_KEY
+ ctx = dlog.WithField(ctx, "btrfsinspect.rebuild-nodes.rebuild.want.reason", reason)
+ ctx = dlog.WithField(ctx, "btrfsinspect.rebuild-nodes.rebuild.want.key",
+ fmt.Sprintf("tree=%v key={%v %v ?} name=%q", treeID, objID, typ, name))
+ o._wantFunc(ctx, treeID, objID, typ, func(ptr keyio.ItemPtr) bool {
+ itemName, ok := o.keyIO.Names[ptr]
+ return ok && bytes.Equal(itemName, name)
+ })
+}
+
func (o *rebuilder) _wantRange(
ctx context.Context,
treeID btrfsprim.ObjID, objID btrfsprim.ObjID, typ btrfsprim.ItemType,
diff --git a/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild_graph.go b/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild_graph.go
index bf4c95d..271595e 100644
--- a/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild_graph.go
+++ b/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild_graph.go
@@ -7,7 +7,6 @@ package rebuildnodes
import (
"context"
"fmt"
- "reflect"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsprim"
@@ -20,7 +19,7 @@ type rebuildCallbacks interface {
fsErr(ctx context.Context, e error)
want(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, typ btrfsprim.ItemType)
wantOff(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, typ btrfsprim.ItemType, off uint64)
- wantFunc(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, typ btrfsprim.ItemType, fn func(btrfsitem.Item) bool)
+ wantDirIndex(ctx context.Context, reason string, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, name []byte)
wantCSum(ctx context.Context, reason string, beg, end btrfsvol.LogicalAddr) // interval is [beg, end)
wantFileExt(ctx context.Context, reason string, treeID btrfsprim.ObjID, ino btrfsprim.ObjID, size int64)
}
@@ -65,13 +64,10 @@ func handleItem(o rebuildCallbacks, ctx context.Context, treeID btrfsprim.ObjID,
// siblings
switch item.Key.ItemType {
case btrfsitem.DIR_ITEM_KEY:
- o.wantFunc(ctx, "corresponding DIR_INDEX",
+ o.wantDirIndex(ctx, "corresponding DIR_INDEX",
treeID,
item.Key.ObjectID,
- btrfsitem.DIR_INDEX_KEY,
- func(peerItem btrfsitem.Item) bool {
- return reflect.DeepEqual(item, peerItem)
- })
+ body.Name)
case btrfsitem.DIR_INDEX_KEY:
o.wantOff(ctx, "corresponding DIR_ITEM",
treeID,