diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2022-09-18 00:09:56 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2022-09-18 00:09:56 -0600 |
commit | 534673fd8b9c6d8f31f5a412746d5671600ad10d (patch) | |
tree | b07d2cad04a2e555d4f0dbf4569955a9f1dbcbf2 /lib/btrfsprogs/btrfsinspect/rebuildnodes/uuidmap.go | |
parent | 525adfb185a0a73f38f9c0acaa748f5ebd825e1f (diff) |
wip
Diffstat (limited to 'lib/btrfsprogs/btrfsinspect/rebuildnodes/uuidmap.go')
-rw-r--r-- | lib/btrfsprogs/btrfsinspect/rebuildnodes/uuidmap.go | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/btrfsprogs/btrfsinspect/rebuildnodes/uuidmap.go b/lib/btrfsprogs/btrfsinspect/rebuildnodes/uuidmap.go index c67b7af..4ce90ae 100644 --- a/lib/btrfsprogs/btrfsinspect/rebuildnodes/uuidmap.go +++ b/lib/btrfsprogs/btrfsinspect/rebuildnodes/uuidmap.go @@ -7,6 +7,7 @@ package rebuildnodes import ( "context" "fmt" + "strings" "github.com/datawire/dlib/dlog" @@ -75,14 +76,36 @@ func newFullAncestorLister(uuidMap uuidMap, treeAncestors map[btrfsprim.ObjID]co } } +type loopError []btrfsprim.ObjID + +func (le loopError) Error() string { + var buf strings.Builder + buf.WriteString("loop: ") + for i, treeID := range le { + if i > 0 { + buf.WriteString("->") + } + fmt.Fprintf(&buf, "%d", treeID) + } + return buf.String() +} + func (fa fullAncestorLister) GetFullAncestors(child btrfsprim.ObjID) containers.Set[btrfsprim.ObjID] { if memoized, ok := fa.memos[child]; ok { if memoized == nil { - panic(fmt.Errorf("loop involving tree %v", child)) + panic(loopError{child}) } return memoized } fa.memos[child] = nil + defer func() { + if r := recover(); r != nil { + if le, ok := r.(loopError); ok { + r = append(loopError{child}, le...) + } + panic(r) + } + }() ret := make(containers.Set[btrfsprim.ObjID]) defer func() { @@ -124,7 +147,7 @@ func (m uuidMap) considerAncestors(ctx context.Context, treeAncestors map[btrfsp } potentialParents := make(containers.Set[btrfsprim.ObjID]) potentialParents.InsertFrom(fa.GetFullAncestors(missingRoot)) - for ancestor := range fa.GetFullAncestors(missingRoot) { + for _, ancestor := range maps.SortedKeys(fa.GetFullAncestors(missingRoot)) { potentialParents.DeleteFrom(fa.GetFullAncestors(ancestor)) } if len(potentialParents) == 1 { |