summaryrefslogtreecommitdiff
path: root/lib/btrfsprogs/btrfsutil
diff options
context:
space:
mode:
Diffstat (limited to 'lib/btrfsprogs/btrfsutil')
-rw-r--r--lib/btrfsprogs/btrfsutil/broken_btree.go9
-rw-r--r--lib/btrfsprogs/btrfsutil/skinny_paths.go23
2 files changed, 17 insertions, 15 deletions
diff --git a/lib/btrfsprogs/btrfsutil/broken_btree.go b/lib/btrfsprogs/btrfsutil/broken_btree.go
index 7ea31ce..15641ab 100644
--- a/lib/btrfsprogs/btrfsutil/broken_btree.go
+++ b/lib/btrfsprogs/btrfsutil/broken_btree.go
@@ -237,11 +237,13 @@ func (bt *brokenTrees) TreeSearch(treeID btrfsprim.ObjID, fn func(btrfsprim.Key,
itemPath := bt.arena.Inflate(indexItem.Value.Path)
node, err := bt.inner.ReadNode(itemPath.Parent())
+ defer btrfstree.FreeNodeRef(node)
if err != nil {
return btrfstree.Item{}, bt.addErrs(index, fn, err)
}
item := node.Data.BodyLeaf[itemPath.Node(-1).FromItemIdx]
+ 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().
@@ -271,13 +273,16 @@ func (bt *brokenTrees) TreeSearchAll(treeID btrfsprim.ObjID, fn func(btrfsprim.K
itemPath := bt.arena.Inflate(indexItems[i].Path)
if node == nil || node.Addr != itemPath.Node(-2).ToNodeAddr {
var err error
+ btrfstree.FreeNodeRef(node)
node, err = bt.inner.ReadNode(itemPath.Parent())
if err != nil {
+ btrfstree.FreeNodeRef(node)
return nil, bt.addErrs(index, fn, err)
}
}
ret[i] = node.Data.BodyLeaf[itemPath.Node(-1).FromItemIdx]
}
+ btrfstree.FreeNodeRef(node)
return ret, bt.addErrs(index, fn, nil)
}
@@ -306,8 +311,10 @@ func (bt *brokenTrees) TreeWalk(ctx context.Context, treeID btrfsprim.ObjID, err
itemPath := bt.arena.Inflate(indexItem.Value.Path)
if node == nil || node.Addr != itemPath.Node(-2).ToNodeAddr {
var err error
+ btrfstree.FreeNodeRef(node)
node, err = bt.inner.ReadNode(itemPath.Parent())
if err != nil {
+ btrfstree.FreeNodeRef(node)
errHandle(&btrfstree.TreeError{Path: itemPath, Err: err})
return true
}
@@ -319,6 +326,7 @@ func (bt *brokenTrees) TreeWalk(ctx context.Context, treeID btrfsprim.ObjID, err
}
return true
})
+ btrfstree.FreeNodeRef(node)
}
func (bt *brokenTrees) Superblock() (*btrfstree.Superblock, error) {
@@ -339,6 +347,7 @@ func (bt *brokenTrees) Augment(treeID btrfsprim.ObjID, nodeAddr btrfsvol.Logical
return nil, index.TreeRootErr
}
nodeRef, err := btrfstree.ReadNode[btrfsvol.LogicalAddr](bt.inner, *sb, nodeAddr, btrfstree.NodeExpectations{})
+ defer btrfstree.FreeNodeRef(nodeRef)
if err != nil {
return nil, err
}
diff --git a/lib/btrfsprogs/btrfsutil/skinny_paths.go b/lib/btrfsprogs/btrfsutil/skinny_paths.go
index 6a51739..1695990 100644
--- a/lib/btrfsprogs/btrfsutil/skinny_paths.go
+++ b/lib/btrfsprogs/btrfsutil/skinny_paths.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com>
+// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com>
//
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -29,21 +29,13 @@ type SkinnyPathArena struct {
SB btrfstree.Superblock
fatRoots map[btrfsvol.LogicalAddr]btrfstree.TreePathElem
- fatItems *containers.LRUCache[skinnyItem, btrfstree.TreePathElem]
+ fatItems containers.ARCache[skinnyItem, btrfstree.TreePathElem]
}
func (a *SkinnyPathArena) init() {
if a.fatRoots == nil {
a.fatRoots = make(map[btrfsvol.LogicalAddr]btrfstree.TreePathElem)
- // This cache size is sorta arbitrary. At first I figured
- // "let's allow 1GB of cached items", and figured 67bytes per
- // item, that's about 16M items. But with overhead of the
- // LRUCache, it's actually a lot higher than that. So then I
- // cut it to .5M, and that cut my total memory use to ~8GB,
- // which is a good number for me. Then I tought it to do a
- // better job of recovering trees, and so the memory grew, and I
- // cut it to 64K. Then to 8K. Then grew it to 128K.
- a.fatItems = containers.NewLRUCache[skinnyItem, btrfstree.TreePathElem](textui.Tunable(128 * 1024))
+ a.fatItems.MaxLen = textui.Tunable(128 * 1024)
}
}
@@ -54,7 +46,7 @@ func (a *SkinnyPathArena) getItem(parent btrfstree.TreePath, itemIdx int) (btrfs
a.init()
- ret, ok := a.fatItems.Get(skinnyItem{
+ ret, ok := a.fatItems.Load(skinnyItem{
Node: parent.Node(-1).ToNodeAddr,
Item: itemIdx,
})
@@ -63,6 +55,7 @@ func (a *SkinnyPathArena) getItem(parent btrfstree.TreePath, itemIdx int) (btrfs
}
node, err := btrfstree.ReadNode(a.FS, a.SB, parent.Node(-1).ToNodeAddr, btrfstree.NodeExpectations{})
+ defer btrfstree.FreeNodeRef(node)
if err != nil {
return btrfstree.TreePathElem{}, err
}
@@ -84,7 +77,7 @@ func (a *SkinnyPathArena) getItem(parent btrfstree.TreePath, itemIdx int) (btrfs
ToKey: item.Key,
ToMaxKey: toMaxKey,
}
- a.fatItems.Add(skinnyItem{Node: parent.Node(-1).ToNodeAddr, Item: i}, elem)
+ a.fatItems.Store(skinnyItem{Node: parent.Node(-1).ToNodeAddr, Item: i}, elem)
if i == itemIdx {
ret = elem
}
@@ -100,7 +93,7 @@ func (a *SkinnyPathArena) getItem(parent btrfstree.TreePath, itemIdx int) (btrfs
ToKey: item.Key,
ToMaxKey: item.Key,
}
- a.fatItems.Add(skinnyItem{Node: parent.Node(-1).ToNodeAddr, Item: i}, elem)
+ a.fatItems.Store(skinnyItem{Node: parent.Node(-1).ToNodeAddr, Item: i}, elem)
if i == itemIdx {
ret = elem
}
@@ -121,7 +114,7 @@ func (a *SkinnyPathArena) Deflate(fat btrfstree.TreePath) SkinnyPath {
a.fatRoots[elem.ToNodeAddr] = elem
ret.Root = elem.ToNodeAddr
} else {
- a.fatItems.Add(skinnyItem{Node: prevNode, Item: elem.FromItemIdx}, elem)
+ a.fatItems.Store(skinnyItem{Node: prevNode, Item: elem.FromItemIdx}, elem)
ret.Items = append(ret.Items, elem.FromItemIdx)
}
prevNode = elem.ToNodeAddr