diff options
-rw-r--r-- | cmd/btrfs-rec/inspect/lsfiles/lsfiles.go | 5 | ||||
-rw-r--r-- | lib/btrfs/csums.go | 9 | ||||
-rw-r--r-- | lib/btrfs/io2_lv.go | 17 | ||||
-rw-r--r-- | lib/btrfs/io4_fs.go | 52 |
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) } |