summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/btrfs-rec/inspect/lsfiles/lsfiles.go5
-rw-r--r--lib/btrfs/csums.go9
-rw-r--r--lib/btrfs/io2_lv.go17
-rw-r--r--lib/btrfs/io4_fs.go52
4 files changed, 40 insertions, 43 deletions
diff --git a/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go b/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go
index af8f690..dec472d 100644
--- a/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go
+++ b/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go
@@ -21,8 +21,6 @@ import (
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsprim"
"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/maps"
"git.lukeshu.com/btrfs-progs-ng/lib/textui"
)
@@ -32,8 +30,7 @@ func LsFiles(
out io.Writer,
fs interface {
btrfstree.TreeOperator
- Superblock() (*btrfstree.Superblock, error)
- diskio.ReaderAt[btrfsvol.LogicalAddr]
+ btrfs.ReadableFS
},
) (err error) {
defer func() {
diff --git a/lib/btrfs/csums.go b/lib/btrfs/csums.go
index 8515d12..c5bcfd6 100644
--- a/lib/btrfs/csums.go
+++ b/lib/btrfs/csums.go
@@ -5,6 +5,7 @@
package btrfs
import (
+ "context"
"fmt"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem"
@@ -47,8 +48,12 @@ func ChecksumQualifiedPhysical(fs *FS, alg btrfssum.CSumType, paddr btrfsvol.Qua
return ChecksumPhysical(dev, alg, paddr.Addr)
}
-func LookupCSum(fs btrfstree.TreeOperator, alg btrfssum.CSumType, laddr btrfsvol.LogicalAddr) (btrfssum.SumRun[btrfsvol.LogicalAddr], error) {
- item, err := fs.TreeSearch(btrfsprim.CSUM_TREE_OBJECTID, btrfstree.SearchCSum(laddr, alg.Size()))
+func LookupCSum(ctx context.Context, fs btrfstree.Forrest, alg btrfssum.CSumType, laddr btrfsvol.LogicalAddr) (btrfssum.SumRun[btrfsvol.LogicalAddr], error) {
+ csumTree, err := fs.ForrestLookup(ctx, btrfsprim.CSUM_TREE_OBJECTID)
+ if err != nil {
+ return btrfssum.SumRun[btrfsvol.LogicalAddr]{}, err
+ }
+ item, err := csumTree.TreeSearch(ctx, btrfstree.SearchCSum(laddr, alg.Size()))
if err != nil {
return btrfssum.SumRun[btrfsvol.LogicalAddr]{}, err
}
diff --git a/lib/btrfs/io2_lv.go b/lib/btrfs/io2_lv.go
index 40fa8e9..e9de215 100644
--- a/lib/btrfs/io2_lv.go
+++ b/lib/btrfs/io2_lv.go
@@ -161,12 +161,15 @@ func (fs *FS) initDev(ctx context.Context, sb btrfstree.Superblock) error {
}
}
}
+ chunkTree, err := fs.ForrestLookup(ctx, btrfsprim.CHUNK_TREE_OBJECTID)
+ if err != nil {
+ return err
+ }
+
var errs derror.MultiError
- fs.TreeWalk(ctx, btrfsprim.CHUNK_TREE_OBJECTID, func(err *btrfstree.TreeError) {
- errs = append(errs, err)
- }, btrfstree.TreeWalkHandler{Item: func(_ btrfstree.Path, item btrfstree.Item) {
+ if err := chunkTree.TreeRange(ctx, func(item btrfstree.Item) bool {
if item.Key.ItemType != btrfsitem.CHUNK_ITEM_KEY {
- return
+ return true
}
switch itemBody := item.Body.(type) {
case *btrfsitem.Chunk:
@@ -183,10 +186,14 @@ func (fs *FS) initDev(ctx context.Context, sb btrfstree.Superblock) error {
// updated.
panic(fmt.Errorf("should not happen: CHUNK_ITEM has unexpected item type: %T", itemBody))
}
- }})
+ return true
+ }); err != nil {
+ errs = append(errs, err)
+ }
if len(errs) > 0 {
return errs
}
+
return nil
}
diff --git a/lib/btrfs/io4_fs.go b/lib/btrfs/io4_fs.go
index 57eca57..9b70713 100644
--- a/lib/btrfs/io4_fs.go
+++ b/lib/btrfs/io4_fs.go
@@ -20,7 +20,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/slices"
"git.lukeshu.com/btrfs-progs-ng/lib/textui"
@@ -63,17 +62,14 @@ type File struct {
}
type Subvolume struct {
- ctx context.Context //nolint:containedctx // don't have an option while keeping the same API
- fs interface {
- btrfstree.TreeOperator
- Superblock() (*btrfstree.Superblock, error)
- diskio.ReaderAt[btrfsvol.LogicalAddr]
- }
+ ctx context.Context //nolint:containedctx // don't have an option while keeping the same API
+ fs ReadableFS
TreeID btrfsprim.ObjID
noChecksums bool
- rootInfo btrfstree.TreeRoot
rootErr error
+ rootInfo btrfstree.TreeRoot
+ tree btrfstree.Tree
bareInodeCache containers.Cache[btrfsprim.ObjID, BareInode]
fullInodeCache containers.Cache[btrfsprim.ObjID, FullInode]
@@ -83,31 +79,26 @@ type Subvolume struct {
func NewSubvolume(
ctx context.Context,
- fs interface {
- btrfstree.TreeOperator
- Superblock() (*btrfstree.Superblock, error)
- diskio.ReaderAt[btrfsvol.LogicalAddr]
- },
+ fs ReadableFS,
treeID btrfsprim.ObjID,
noChecksums bool,
) *Subvolume {
sv := &Subvolume{
+ ctx: ctx,
fs: fs,
TreeID: treeID,
noChecksums: noChecksums,
}
- sb, err := sv.fs.Superblock()
- if err != nil {
- sv.rootErr = err
- return sv
- }
- rootInfo, err := btrfstree.OldLookupTreeRoot(ctx, sv.fs.TreeSearch, *sb, sv.TreeID)
+ tree, err := sv.fs.ForrestLookup(ctx, sv.TreeID)
if err != nil {
sv.rootErr = err
return sv
}
+ sb, _ := sv.fs.Superblock()
+ rootInfo, _ := btrfstree.LookupTreeRoot(ctx, sv.fs, *sb, sv.TreeID)
sv.rootInfo = *rootInfo
+ sv.tree = tree
sv.bareInodeCache = containers.NewARCache[btrfsprim.ObjID, BareInode](textui.Tunable(128),
containers.SourceFunc[btrfsprim.ObjID, BareInode](sv.loadBareInode))
@@ -142,11 +133,11 @@ func (sv *Subvolume) ReleaseBareInode(inode btrfsprim.ObjID) {
sv.bareInodeCache.Release(inode)
}
-func (sv *Subvolume) loadBareInode(_ context.Context, inode btrfsprim.ObjID, val *BareInode) {
+func (sv *Subvolume) loadBareInode(ctx context.Context, inode btrfsprim.ObjID, val *BareInode) {
*val = BareInode{
Inode: inode,
}
- item, err := sv.fs.TreeLookup(sv.TreeID, btrfsprim.Key{
+ item, err := sv.tree.TreeLookup(ctx, btrfsprim.Key{
ObjectID: inode,
ItemType: btrfsitem.INODE_ITEM_KEY,
Offset: 0,
@@ -180,21 +171,14 @@ func (sv *Subvolume) ReleaseFullInode(inode btrfsprim.ObjID) {
sv.fullInodeCache.Release(inode)
}
-func (sv *Subvolume) loadFullInode(_ context.Context, inode btrfsprim.ObjID, val *FullInode) {
+func (sv *Subvolume) loadFullInode(ctx context.Context, inode btrfsprim.ObjID, val *FullInode) {
*val = FullInode{
BareInode: BareInode{
Inode: inode,
},
XAttrs: make(map[string]string),
}
- items, err := sv.fs.TreeSearchAll(sv.TreeID, btrfstree.SearchObject(inode))
- if err != nil {
- val.Errs = append(val.Errs, err)
- if len(items) == 0 {
- return
- }
- }
- for _, item := range items {
+ if err := sv.tree.TreeSubrange(ctx, 1, btrfstree.SearchObject(inode), func(item btrfstree.Item) bool {
switch item.Key.ItemType {
case btrfsitem.INODE_ITEM_KEY:
switch itemBody := item.Body.(type) {
@@ -203,7 +187,7 @@ func (sv *Subvolume) loadFullInode(_ context.Context, inode btrfsprim.ObjID, val
if !reflect.DeepEqual(itemBody, *val.InodeItem) {
val.Errs = append(val.Errs, fmt.Errorf("multiple inodes"))
}
- continue
+ return true
}
bodyCopy := itemBody.Clone()
val.InodeItem = &bodyCopy
@@ -222,8 +206,12 @@ func (sv *Subvolume) loadFullInode(_ context.Context, inode btrfsprim.ObjID, val
panic(fmt.Errorf("should not happen: XATTR_ITEM has unexpected item type: %T", itemBody))
}
default:
+ item.Body = item.Body.CloneItem()
val.OtherItems = append(val.OtherItems, item)
}
+ return true
+ }); err != nil {
+ val.Errs = append(val.Errs, err)
}
}
@@ -503,7 +491,7 @@ func (file *File) maybeShortReadAt(dat []byte, off int64) (int, error) {
return 0, err
}
if !file.SV.noChecksums {
- sumRun, err := LookupCSum(file.SV.fs, sb.ChecksumType, blockBeg)
+ sumRun, err := LookupCSum(file.SV.ctx, file.SV.fs, sb.ChecksumType, blockBeg)
if err != nil {
return 0, fmt.Errorf("checksum@%v: %w", blockBeg, err)
}