summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-07-06 03:05:07 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-07-08 00:15:59 -0600
commitcc09287d752ec6d9c4d4876ab41c4e5859b90f78 (patch)
tree62be91b774959caf88bc160cf5ef6d244c6429c3
parent5647659f27f8aa18bc10ca4742f8856162325d5c (diff)
Move subvol.go to btrfs/io3_fs.go
-rw-r--r--cmd/btrfs-mount/main.go6
-rw-r--r--cmd/btrfs-mount/subvol_fuse.go51
-rw-r--r--pkg/btrfs/io3_fs.go (renamed from cmd/btrfs-mount/subvol.go)128
-rw-r--r--pkg/util/lru.go (renamed from cmd/btrfs-mount/lru.go)2
4 files changed, 93 insertions, 94 deletions
diff --git a/cmd/btrfs-mount/main.go b/cmd/btrfs-mount/main.go
index e059351..64cae30 100644
--- a/cmd/btrfs-mount/main.go
+++ b/cmd/btrfs-mount/main.go
@@ -71,10 +71,12 @@ func Main(ctx context.Context, mountpoint string, imgfilenames ...string) (err e
grp.Go("main", func(ctx context.Context) error {
defer atomic.StoreUint32(&mounted, 0)
rootSubvol := &Subvolume{
- FS: fs,
+ Subvolume: btrfs.Subvolume{
+ FS: fs,
+ TreeID: btrfs.FS_TREE_OBJECTID,
+ },
DeviceName: tryAbs(imgfilenames[0]),
Mountpoint: mountpoint,
- TreeID: btrfs.FS_TREE_OBJECTID,
}
return rootSubvol.Run(ctx)
})
diff --git a/cmd/btrfs-mount/subvol_fuse.go b/cmd/btrfs-mount/subvol_fuse.go
index 6f3f267..1163e9f 100644
--- a/cmd/btrfs-mount/subvol_fuse.go
+++ b/cmd/btrfs-mount/subvol_fuse.go
@@ -6,6 +6,9 @@ import (
"sync/atomic"
"syscall"
+ "github.com/datawire/dlib/dcontext"
+ "github.com/datawire/dlib/dlog"
+ "github.com/jacobsa/fuse"
"github.com/jacobsa/fuse/fuseops"
"github.com/jacobsa/fuse/fuseutil"
@@ -15,21 +18,45 @@ import (
)
type dirState struct {
- Dir *dir
+ Dir *btrfs.Dir
}
type fileState struct {
- File *file
+ File *btrfs.File
}
-type subvolumeFUSE struct {
+type Subvolume struct {
+ btrfs.Subvolume
+ DeviceName string
+ Mountpoint string
+
fuseutil.NotImplementedFileSystem
lastHandle uint64
dirHandles util.SyncMap[fuseops.HandleID, *dirState]
fileHandles util.SyncMap[fuseops.HandleID, *fileState]
}
-func (sv *subvolumeFUSE) newHandle() fuseops.HandleID {
+func (sv *Subvolume) Run(ctx context.Context) error {
+ mount, err := fuse.Mount(
+ sv.Mountpoint,
+ fuseutil.NewFileSystemServer(sv),
+ &fuse.MountConfig{
+ OpContext: ctx,
+ ErrorLogger: dlog.StdLogger(ctx, dlog.LogLevelError),
+ DebugLogger: dlog.StdLogger(ctx, dlog.LogLevelDebug),
+
+ FSName: sv.DeviceName,
+ Subtype: "btrfs",
+
+ ReadOnly: true,
+ })
+ if err != nil {
+ return err
+ }
+ return mount.Join(dcontext.HardContext(ctx))
+}
+
+func (sv *Subvolume) newHandle() fuseops.HandleID {
return fuseops.HandleID(atomic.AddUint64(&sv.lastHandle, 1))
}
@@ -73,14 +100,14 @@ func (sv *Subvolume) StatFS(_ context.Context, op *fuseops.StatFSOp) error {
func (sv *Subvolume) LookUpInode(_ context.Context, op *fuseops.LookUpInodeOp) error {
if op.Parent == fuseops.RootInodeID {
- parent, err := sv.getRootInode()
+ parent, err := sv.GetRootInode()
if err != nil {
return err
}
op.Parent = fuseops.InodeID(parent)
}
- dir, err := sv.loadDir(btrfs.ObjID(op.Parent))
+ dir, err := sv.LoadDir(btrfs.ObjID(op.Parent))
if err != nil {
return err
}
@@ -91,7 +118,7 @@ func (sv *Subvolume) LookUpInode(_ context.Context, op *fuseops.LookUpInodeOp) e
if entry.Location.ItemType != btrfsitem.INODE_ITEM_KEY {
return fmt.Errorf("child %q is not an inode: %w", op.Name, syscall.ENOSYS)
}
- bareInode, err := sv.loadBareInode(entry.Location.ObjectID)
+ bareInode, err := sv.LoadBareInode(entry.Location.ObjectID)
if err != nil {
return err
}
@@ -105,14 +132,14 @@ func (sv *Subvolume) LookUpInode(_ context.Context, op *fuseops.LookUpInodeOp) e
func (sv *Subvolume) GetInodeAttributes(_ context.Context, op *fuseops.GetInodeAttributesOp) error {
if op.Inode == fuseops.RootInodeID {
- inode, err := sv.getRootInode()
+ inode, err := sv.GetRootInode()
if err != nil {
return err
}
op.Inode = fuseops.InodeID(inode)
}
- bareInode, err := sv.loadBareInode(btrfs.ObjID(op.Inode))
+ bareInode, err := sv.LoadBareInode(btrfs.ObjID(op.Inode))
if err != nil {
return err
}
@@ -123,14 +150,14 @@ func (sv *Subvolume) GetInodeAttributes(_ context.Context, op *fuseops.GetInodeA
func (sv *Subvolume) OpenDir(_ context.Context, op *fuseops.OpenDirOp) error {
if op.Inode == fuseops.RootInodeID {
- inode, err := sv.getRootInode()
+ inode, err := sv.GetRootInode()
if err != nil {
return err
}
op.Inode = fuseops.InodeID(inode)
}
- dir, err := sv.loadDir(btrfs.ObjID(op.Inode))
+ dir, err := sv.LoadDir(btrfs.ObjID(op.Inode))
if err != nil {
return err
}
@@ -184,7 +211,7 @@ func (sv *Subvolume) ReleaseDirHandle(_ context.Context, op *fuseops.ReleaseDirH
}
func (sv *Subvolume) OpenFile(_ context.Context, op *fuseops.OpenFileOp) error {
- file, err := sv.loadFile(btrfs.ObjID(op.Inode))
+ file, err := sv.LoadFile(btrfs.ObjID(op.Inode))
if err != nil {
return err
}
diff --git a/cmd/btrfs-mount/subvol.go b/pkg/btrfs/io3_fs.go
index 1d5e9db..a418b05 100644
--- a/cmd/btrfs-mount/subvol.go
+++ b/pkg/btrfs/io3_fs.go
@@ -1,89 +1,59 @@
-package main
+package btrfs
import (
- "context"
"fmt"
"io"
"reflect"
"sort"
"sync"
- "github.com/datawire/dlib/dcontext"
"github.com/datawire/dlib/derror"
- "github.com/datawire/dlib/dlog"
- "github.com/jacobsa/fuse"
- "github.com/jacobsa/fuse/fuseutil"
- "lukeshu.com/btrfs-tools/pkg/btrfs"
"lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem"
"lukeshu.com/btrfs-tools/pkg/btrfs/btrfsvol"
"lukeshu.com/btrfs-tools/pkg/util"
)
-type bareInode struct {
- Inode btrfs.ObjID
+type BareInode struct {
+ Inode ObjID
InodeItem *btrfsitem.Inode
Errs derror.MultiError
}
-type fullInode struct {
- bareInode
- OtherItems []btrfs.Item
+type FullInode struct {
+ BareInode
+ OtherItems []Item
}
-type dir struct {
- fullInode
+type Dir struct {
+ FullInode
ChildrenByName map[string]btrfsitem.DirEntry
ChildrenByIndex map[uint64]btrfsitem.DirEntry
}
-type fileExtent struct {
+type FileExtent struct {
OffsetWithinFile int64
btrfsitem.FileExtent
}
-type file struct {
- fullInode
- Extents []fileExtent
- FS *btrfs.FS
+type File struct {
+ FullInode
+ Extents []FileExtent
+ FS *FS
}
type Subvolume struct {
- FS *btrfs.FS
- DeviceName string
- Mountpoint string
- TreeID btrfs.ObjID
+ FS *FS
+ TreeID ObjID
rootOnce sync.Once
rootVal btrfsitem.Root
rootErr error
- bareInodeCache LRUCache[btrfs.ObjID, *bareInode]
- fullInodeCache LRUCache[btrfs.ObjID, *fullInode]
- dirCache LRUCache[btrfs.ObjID, *dir]
- fileCache LRUCache[btrfs.ObjID, *file]
-
- subvolumeFUSE
-}
-
-func (sv *Subvolume) Run(ctx context.Context) error {
- mount, err := fuse.Mount(
- sv.Mountpoint,
- fuseutil.NewFileSystemServer(sv),
- &fuse.MountConfig{
- OpContext: ctx,
- ErrorLogger: dlog.StdLogger(ctx, dlog.LogLevelError),
- DebugLogger: dlog.StdLogger(ctx, dlog.LogLevelDebug),
-
- FSName: sv.DeviceName,
- Subtype: "btrfs",
-
- ReadOnly: true,
- })
- if err != nil {
- return err
- }
- return mount.Join(dcontext.HardContext(ctx))
+ bareInodeCache util.LRUCache[ObjID, *BareInode]
+ fullInodeCache util.LRUCache[ObjID, *FullInode]
+ dirCache util.LRUCache[ObjID, *Dir]
+ fileCache util.LRUCache[ObjID, *File]
}
func (sv *Subvolume) init() {
@@ -94,7 +64,7 @@ func (sv *Subvolume) init() {
return
}
- root, err := sv.FS.TreeLookup(sb.Data.RootTree, btrfs.Key{
+ root, err := sv.FS.TreeLookup(sb.Data.RootTree, Key{
ObjectID: sv.TreeID,
ItemType: btrfsitem.ROOT_ITEM_KEY,
Offset: 0,
@@ -114,27 +84,27 @@ func (sv *Subvolume) init() {
})
}
-func (sv *Subvolume) getRootInode() (btrfs.ObjID, error) {
+func (sv *Subvolume) GetRootInode() (ObjID, error) {
sv.init()
return sv.rootVal.RootDirID, sv.rootErr
}
-func (sv *Subvolume) getFSTree() (btrfsvol.LogicalAddr, error) {
+func (sv *Subvolume) GetFSTree() (btrfsvol.LogicalAddr, error) {
sv.init()
return sv.rootVal.ByteNr, sv.rootErr
}
-func (sv *Subvolume) loadBareInode(inode btrfs.ObjID) (*bareInode, error) {
- val := sv.bareInodeCache.GetOrElse(inode, func() (val *bareInode) {
- val = &bareInode{
+func (sv *Subvolume) LoadBareInode(inode ObjID) (*BareInode, error) {
+ val := sv.bareInodeCache.GetOrElse(inode, func() (val *BareInode) {
+ val = &BareInode{
Inode: inode,
}
- tree, err := sv.getFSTree()
+ tree, err := sv.GetFSTree()
if err != nil {
val.Errs = append(val.Errs, err)
return
}
- item, err := sv.FS.TreeLookup(tree, btrfs.Key{
+ item, err := sv.FS.TreeLookup(tree, Key{
ObjectID: inode,
ItemType: btrfsitem.INODE_ITEM_KEY,
Offset: 0,
@@ -159,19 +129,19 @@ func (sv *Subvolume) loadBareInode(inode btrfs.ObjID) (*bareInode, error) {
return val, nil
}
-func (sv *Subvolume) loadFullInode(inode btrfs.ObjID) (*fullInode, error) {
- val := sv.fullInodeCache.GetOrElse(inode, func() (val *fullInode) {
- val = &fullInode{
- bareInode: bareInode{
+func (sv *Subvolume) LoadFullInode(inode ObjID) (*FullInode, error) {
+ val := sv.fullInodeCache.GetOrElse(inode, func() (val *FullInode) {
+ val = &FullInode{
+ BareInode: BareInode{
Inode: inode,
},
}
- tree, err := sv.getFSTree()
+ tree, err := sv.GetFSTree()
if err != nil {
val.Errs = append(val.Errs, err)
return
}
- items, err := sv.FS.TreeSearchAll(tree, func(key btrfs.Key) int {
+ items, err := sv.FS.TreeSearchAll(tree, func(key Key) int {
return util.CmpUint(inode, key.ObjectID)
})
if err != nil {
@@ -203,15 +173,15 @@ func (sv *Subvolume) loadFullInode(inode btrfs.ObjID) (*fullInode, error) {
return val, nil
}
-func (sv *Subvolume) loadDir(inode btrfs.ObjID) (*dir, error) {
- val := sv.dirCache.GetOrElse(inode, func() (val *dir) {
- val = new(dir)
- fullInode, err := sv.loadFullInode(inode)
+func (sv *Subvolume) LoadDir(inode ObjID) (*Dir, error) {
+ val := sv.dirCache.GetOrElse(inode, func() (val *Dir) {
+ val = new(Dir)
+ fullInode, err := sv.LoadFullInode(inode)
if err != nil {
val.Errs = append(val.Errs, err)
return
}
- val.fullInode = *fullInode
+ val.FullInode = *fullInode
val.populate()
return
})
@@ -221,7 +191,7 @@ func (sv *Subvolume) loadDir(inode btrfs.ObjID) (*dir, error) {
return val, nil
}
-func (ret *dir) populate() {
+func (ret *Dir) populate() {
ret.ChildrenByName = make(map[string]btrfsitem.DirEntry)
ret.ChildrenByIndex = make(map[uint64]btrfsitem.DirEntry)
for _, item := range ret.OtherItems {
@@ -295,15 +265,15 @@ func (ret *dir) populate() {
return
}
-func (sv *Subvolume) loadFile(inode btrfs.ObjID) (*file, error) {
- val := sv.fileCache.GetOrElse(inode, func() (val *file) {
- val = new(file)
- fullInode, err := sv.loadFullInode(inode)
+func (sv *Subvolume) LoadFile(inode ObjID) (*File, error) {
+ val := sv.fileCache.GetOrElse(inode, func() (val *File) {
+ val = new(File)
+ fullInode, err := sv.LoadFullInode(inode)
if err != nil {
val.Errs = append(val.Errs, err)
return
}
- val.fullInode = *fullInode
+ val.FullInode = *fullInode
val.FS = sv.FS
val.populate()
return
@@ -314,13 +284,13 @@ func (sv *Subvolume) loadFile(inode btrfs.ObjID) (*file, error) {
return val, nil
}
-func (ret *file) populate() {
+func (ret *File) populate() {
for _, item := range ret.OtherItems {
switch item.Head.Key.ItemType {
case btrfsitem.INODE_REF_KEY:
// TODO
case btrfsitem.EXTENT_DATA_KEY:
- ret.Extents = append(ret.Extents, fileExtent{
+ ret.Extents = append(ret.Extents, FileExtent{
OffsetWithinFile: int64(item.Head.Key.Offset),
FileExtent: item.Body.(btrfsitem.FileExtent),
})
@@ -364,7 +334,7 @@ func (ret *file) populate() {
}
}
-func (file *file) ReadAt(dat []byte, off int64) (int, error) {
+func (file *File) ReadAt(dat []byte, off int64) (int, error) {
// These stateles maybe-short-reads each do an O(n) extent
// lookup, so reading a file is O(n^2), but we expect n to be
// small, so whatev. Turn file.Extents it in to an rbtree if
@@ -380,7 +350,7 @@ func (file *file) ReadAt(dat []byte, off int64) (int, error) {
return done, nil
}
-func (file *file) maybeShortReadAt(dat []byte, off int64) (int, error) {
+func (file *File) maybeShortReadAt(dat []byte, off int64) (int, error) {
for _, extent := range file.Extents {
extBeg := extent.OffsetWithinFile
if extBeg > off {
@@ -409,4 +379,4 @@ func (file *file) maybeShortReadAt(dat []byte, off int64) (int, error) {
return 0, fmt.Errorf("read: could not map position %v", off)
}
-var _ io.ReaderAt = (*file)(nil)
+var _ io.ReaderAt = (*File)(nil)
diff --git a/cmd/btrfs-mount/lru.go b/pkg/util/lru.go
index bf91c5e..2b62e69 100644
--- a/cmd/btrfs-mount/lru.go
+++ b/pkg/util/lru.go
@@ -1,4 +1,4 @@
-package main
+package util
import (
"sync"