diff options
Diffstat (limited to 'cmd/btrfs-rec/inspect')
-rw-r--r-- | cmd/btrfs-rec/inspect/lsfiles/lsfiles.go | 30 | ||||
-rw-r--r-- | cmd/btrfs-rec/inspect/mount/mount.go | 33 |
2 files changed, 43 insertions, 20 deletions
diff --git a/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go b/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go index e42050f..af8f690 100644 --- a/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go +++ b/cmd/btrfs-rec/inspect/lsfiles/lsfiles.go @@ -84,12 +84,14 @@ func printSubvol(out io.Writer, prefix string, isLast bool, name string, subvol subvol.TreeID, fmtErr(err))) return } - dir, err := subvol.LoadDir(rootInode) + + dir, err := subvol.AcquireDir(rootInode) if err != nil { printText(out, prefix, isLast, name+"/", textui.Sprintf("subvol_id=%v err=%v", subvol.TreeID, fmtErr(err))) return } + if name == "/" { printDir(out, prefix, isLast, name, dir) return @@ -127,19 +129,23 @@ func fmtInode(inode btrfs.BareInode) string { func printDir(out io.Writer, prefix string, isLast bool, name string, dir *btrfs.Dir) { printText(out, prefix, isLast, name+"/", fmtInode(dir.BareInode)) + childrenByName := dir.ChildrenByName + subvol := dir.SV + subvol.ReleaseDir(dir.Inode) + if isLast { prefix += tS } else { prefix += tl } - for i, childName := range maps.SortedKeys(dir.ChildrenByName) { + for i, childName := range maps.SortedKeys(childrenByName) { printDirEntry( out, prefix, - i == len(dir.ChildrenByName)-1, - dir.SV, + i == len(childrenByName)-1, + subvol, path.Join(name, childName), - dir.ChildrenByName[childName]) + childrenByName[childName]) } } @@ -151,7 +157,7 @@ func printDirEntry(out io.Writer, prefix string, isLast bool, subvol *btrfs.Subv case btrfsitem.FT_DIR: switch entry.Location.ItemType { case btrfsitem.INODE_ITEM_KEY: - dir, err := subvol.LoadDir(entry.Location.ObjectID) + dir, err := subvol.AcquireDir(entry.Location.ObjectID) if err != nil { printText(out, prefix, isLast, name, textui.Sprintf("%v err=%v", entry.Type, fmtErr(err))) return @@ -168,44 +174,48 @@ func printDirEntry(out io.Writer, prefix string, isLast bool, subvol *btrfs.Subv panic(fmt.Errorf("TODO: I don't know how to handle an FT_SYMLINK with location.ItemType=%v: %q", entry.Location.ItemType, name)) } - file, err := subvol.LoadFile(entry.Location.ObjectID) + file, err := subvol.AcquireFile(entry.Location.ObjectID) if err != nil { printText(out, prefix, isLast, name, textui.Sprintf("%v err=%v", entry.Type, fmtErr(err))) return } + defer subvol.ReleaseFile(entry.Location.ObjectID) printSymlink(out, prefix, isLast, name, file) case btrfsitem.FT_REG_FILE: if entry.Location.ItemType != btrfsitem.INODE_ITEM_KEY { panic(fmt.Errorf("TODO: I don't know how to handle an FT_REG_FILE with location.ItemType=%v: %q", entry.Location.ItemType, name)) } - file, err := subvol.LoadFile(entry.Location.ObjectID) + file, err := subvol.AcquireFile(entry.Location.ObjectID) if err != nil { printText(out, prefix, isLast, name, textui.Sprintf("%v err=%v", entry.Type, fmtErr(err))) return } + defer subvol.ReleaseFile(entry.Location.ObjectID) printFile(out, prefix, isLast, name, file) case btrfsitem.FT_SOCK: if entry.Location.ItemType != btrfsitem.INODE_ITEM_KEY { panic(fmt.Errorf("TODO: I don't know how to handle an FT_SOCK with location.ItemType=%v: %q", entry.Location.ItemType, name)) } - file, err := subvol.LoadFile(entry.Location.ObjectID) + file, err := subvol.AcquireFile(entry.Location.ObjectID) if err != nil { printText(out, prefix, isLast, name, textui.Sprintf("%v err=%v", entry.Type, fmtErr(err))) return } + defer subvol.ReleaseFile(entry.Location.ObjectID) printSocket(out, prefix, isLast, name, file) case btrfsitem.FT_FIFO: if entry.Location.ItemType != btrfsitem.INODE_ITEM_KEY { panic(fmt.Errorf("TODO: I don't know how to handle an FT_FIFO with location.ItemType=%v: %q", entry.Location.ItemType, name)) } - file, err := subvol.LoadFile(entry.Location.ObjectID) + file, err := subvol.AcquireFile(entry.Location.ObjectID) if err != nil { printText(out, prefix, isLast, name, textui.Sprintf("%v err=%v", entry.Type, fmtErr(err))) return } + defer subvol.ReleaseFile(entry.Location.ObjectID) printPipe(out, prefix, isLast, name, file) default: panic(fmt.Errorf("TODO: I don't know how to handle a fileType=%v: %q", diff --git a/cmd/btrfs-rec/inspect/mount/mount.go b/cmd/btrfs-rec/inspect/mount/mount.go index d4d2e0a..143131a 100644 --- a/cmd/btrfs-rec/inspect/mount/mount.go +++ b/cmd/btrfs-rec/inspect/mount/mount.go @@ -169,8 +169,8 @@ func inodeItemToFUSE(itemBody btrfsitem.Inode) fuseops.InodeAttributes { } } -func (sv *subvolume) LoadDir(inode btrfsprim.ObjID) (val *btrfs.Dir, err error) { - val, err = sv.Subvolume.LoadDir(inode) +func (sv *subvolume) AcquireDir(inode btrfsprim.ObjID) (val *btrfs.Dir, err error) { + val, err = sv.Subvolume.AcquireDir(inode) if val != nil { haveSubvolumes := false for _, index := range maps.SortedKeys(val.ChildrenByIndex) { @@ -245,10 +245,11 @@ func (sv *subvolume) LookUpInode(_ context.Context, op *fuseops.LookUpInodeOp) e op.Parent = fuseops.InodeID(parent) } - dir, err := sv.LoadDir(btrfsprim.ObjID(op.Parent)) + dir, err := sv.AcquireDir(btrfsprim.ObjID(op.Parent)) if err != nil { return err } + defer sv.Subvolume.ReleaseDir(btrfsprim.ObjID(op.Parent)) entry, ok := dir.ChildrenByName[op.Name] if !ok { return syscall.ENOENT @@ -275,10 +276,13 @@ func (sv *subvolume) LookUpInode(_ context.Context, op *fuseops.LookUpInodeOp) e } return nil } - bareInode, err := sv.LoadBareInode(entry.Location.ObjectID) + + bareInode, err := sv.AcquireBareInode(entry.Location.ObjectID) if err != nil { return err } + defer sv.ReleaseBareInode(entry.Location.ObjectID) + op.Entry = fuseops.ChildInodeEntry{ Child: fuseops.InodeID(entry.Location.ObjectID), Generation: fuseops.GenerationNumber(bareInode.InodeItem.Sequence), @@ -296,10 +300,11 @@ func (sv *subvolume) GetInodeAttributes(_ context.Context, op *fuseops.GetInodeA op.Inode = fuseops.InodeID(inode) } - bareInode, err := sv.LoadBareInode(btrfsprim.ObjID(op.Inode)) + bareInode, err := sv.AcquireBareInode(btrfsprim.ObjID(op.Inode)) if err != nil { return err } + defer sv.Subvolume.ReleaseBareInode(btrfsprim.ObjID(op.Inode)) op.Attributes = inodeItemToFUSE(*bareInode.InodeItem) return nil @@ -314,10 +319,12 @@ func (sv *subvolume) OpenDir(_ context.Context, op *fuseops.OpenDirOp) error { op.Inode = fuseops.InodeID(inode) } - dir, err := sv.LoadDir(btrfsprim.ObjID(op.Inode)) + dir, err := sv.AcquireDir(btrfsprim.ObjID(op.Inode)) if err != nil { return err } + defer sv.Subvolume.ReleaseDir(btrfsprim.ObjID(op.Inode)) + handle := sv.newHandle() sv.dirHandles.Store(handle, &dirState{ Dir: dir, @@ -369,10 +376,12 @@ func (sv *subvolume) ReleaseDirHandle(_ context.Context, op *fuseops.ReleaseDirH } func (sv *subvolume) OpenFile(_ context.Context, op *fuseops.OpenFileOp) error { - file, err := sv.LoadFile(btrfsprim.ObjID(op.Inode)) + file, err := sv.AcquireFile(btrfsprim.ObjID(op.Inode)) if err != nil { return err } + defer sv.Subvolume.ReleaseFile(btrfsprim.ObjID(op.Inode)) + handle := sv.newHandle() sv.fileHandles.Store(handle, &fileState{ File: file, @@ -415,10 +424,12 @@ func (sv *subvolume) ReleaseFileHandle(_ context.Context, op *fuseops.ReleaseFil } func (sv *subvolume) ReadSymlink(_ context.Context, op *fuseops.ReadSymlinkOp) error { - file, err := sv.LoadFile(btrfsprim.ObjID(op.Inode)) + file, err := sv.AcquireFile(btrfsprim.ObjID(op.Inode)) if err != nil { return err } + defer sv.Subvolume.ReleaseFile(btrfsprim.ObjID(op.Inode)) + reader := io.NewSectionReader(file, 0, file.InodeItem.Size) tgt, err := io.ReadAll(reader) if err != nil { @@ -437,10 +448,11 @@ func (sv *subvolume) ListXattr(_ context.Context, op *fuseops.ListXattrOp) error op.Inode = fuseops.InodeID(inode) } - fullInode, err := sv.LoadFullInode(btrfsprim.ObjID(op.Inode)) + fullInode, err := sv.AcquireFullInode(btrfsprim.ObjID(op.Inode)) if err != nil { return err } + defer sv.Subvolume.ReleaseFullInode(btrfsprim.ObjID(op.Inode)) size := 0 for name := range fullInode.XAttrs { @@ -469,10 +481,11 @@ func (sv *subvolume) GetXattr(_ context.Context, op *fuseops.GetXattrOp) error { op.Inode = fuseops.InodeID(inode) } - fullInode, err := sv.LoadFullInode(btrfsprim.ObjID(op.Inode)) + fullInode, err := sv.AcquireFullInode(btrfsprim.ObjID(op.Inode)) if err != nil { return err } + defer sv.Subvolume.ReleaseFullInode(btrfsprim.ObjID(op.Inode)) val, ok := fullInode.XAttrs[op.Name] if !ok { |