diff options
Diffstat (limited to 'cmd/btrfs-mount/main.go')
-rw-r--r-- | cmd/btrfs-mount/main.go | 144 |
1 files changed, 18 insertions, 126 deletions
diff --git a/cmd/btrfs-mount/main.go b/cmd/btrfs-mount/main.go index 8e07e77..e059351 100644 --- a/cmd/btrfs-mount/main.go +++ b/cmd/btrfs-mount/main.go @@ -7,16 +7,12 @@ import ( "path/filepath" "sync/atomic" - "github.com/datawire/dlib/dcontext" "github.com/datawire/dlib/dgroup" "github.com/datawire/dlib/dlog" "github.com/jacobsa/fuse" - "github.com/jacobsa/fuse/fuseops" - "github.com/jacobsa/fuse/fuseutil" "github.com/sirupsen/logrus" "lukeshu.com/btrfs-tools/pkg/btrfs" - "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsvol" "lukeshu.com/btrfs-tools/pkg/btrfsmisc" ) @@ -38,6 +34,14 @@ func main() { } } +func tryAbs(rel string) string { + abs, err := filepath.Abs(rel) + if err != nil { + return rel + } + return abs +} + func Main(ctx context.Context, mountpoint string, imgfilenames ...string) (err error) { maybeSetErr := func(_err error) { if _err != nil && err == nil { @@ -53,138 +57,26 @@ func Main(ctx context.Context, mountpoint string, imgfilenames ...string) (err e maybeSetErr(fs.Close()) }() - fsAdapter := &FSAdapter{ - fs: fs, - } - - devname, err := filepath.Abs(imgfilenames[0]) - if err != nil { - devname = imgfilenames[0] - } - mount, err := fuse.Mount( - mountpoint, - fuseutil.NewFileSystemServer(fsAdapter), - &fuse.MountConfig{ - OpContext: ctx, - ErrorLogger: dlog.StdLogger(ctx, dlog.LogLevelError), - DebugLogger: dlog.StdLogger(ctx, dlog.LogLevelDebug), - - FSName: devname, - Subtype: "btrfs", - - ReadOnly: true, - }) - if err != nil { - return err - } - mounted := uint32(1) grp := dgroup.NewGroup(ctx, dgroup.GroupConfig{ ShutdownOnNonError: true, }) - grp.Go("send-unmount", func(ctx context.Context) error { + grp.Go("shutdown", func(ctx context.Context) error { <-ctx.Done() if atomic.LoadUint32(&mounted) == 0 { return nil } return fuse.Unmount(os.Args[1]) }) - grp.Go("recv-unmount", func(ctx context.Context) error { - ret := mount.Join(dcontext.HardContext(ctx)) - atomic.StoreUint32(&mounted, 0) - return ret + grp.Go("main", func(ctx context.Context) error { + defer atomic.StoreUint32(&mounted, 0) + rootSubvol := &Subvolume{ + FS: fs, + DeviceName: tryAbs(imgfilenames[0]), + Mountpoint: mountpoint, + TreeID: btrfs.FS_TREE_OBJECTID, + } + return rootSubvol.Run(ctx) }) return grp.Wait() } - -type FSAdapter struct { - fuseutil.NotImplementedFileSystem - - fs *btrfs.FS - - rootInodeOnce sync.Once - rootInodeVal btrfs.ObjID - rootInodeErr error - - inode2treeMu sync.Mutex - inode2tree map[btrfs.ObjID]btrfsvol.LogicalAddr -} - -func (a *FSAdapter) getRootInode() (btrfs.ObjID, error) { - a.rootInodeOnce.Do(func() { - a.rootInodeVal, a.rootInodeErr = func() (btrfs.ObjID, error) { - sb, err := a.fs.Superblock() - if err != nil { - return 0, err - } - - root, err := fs.TreeLookup(sb.Data.RootTree, btrfs.Key{ - ObjectID: btrfs.FS_TREE_OBJECTID, - ItemType: btrfsitem.ROOT_ITEM_KEY, - Offset: 0, - }) - if err != nil { - return 0, err - } - rootBody, ok := root.Body.(btrfsitem.Root) - if !ok { - return 0, fmt.Errorf("FS_TREE_ ROOT_ITEM has malformed body") - } - return rootBody.RootDirID, nil - }() - }) - return a.rootInodeVal, a.rootInodeErr -} - -func (a *FSAdapter) StatFS(_ context.Context, op *fuseops.StatFSOp) error { - // See linux.git/fs/btrfs/super.c:btrfs_statfs() - sb, err := a.fs.Superblock() - if err != nil { - return err - } - - op.IoSize = sb.Data.SectorSize - op.BlockSize = sb.Data.SectorSize - op.Blocks = sb.Data.TotalBytes / uint64(sb.Data.SectorSize) // TODO: adjust for RAID type - //op.BlocksFree = TODO - - // btrfs doesn't have a fixed number of inodes - op.Inodes = 0 - op.InodesFree = 0 - - // jacobsa/fuse doesn't expose namelen, instead hard-coding it - // to 255. Which is fine by us, because that's what it is for - // btrfs. - - return nil -} - -// func (a *FSAdapter) LookUpInode(_ context.Context, op *fuseops.LookUpInodeOp) error {} - -func (a *FSAdapter) GetInodeAttributes(ctx context.Context, op *fuseops.GetInodeAttributesOp) error { - sb, err := a.fs.Superblock() - if err != nil { - return err - } - - if op.Inode == fuseops.RootInodeID { - io.Inode, err = a.getRootInode() - if err != nil { - return err - } - } - -} - -// func (a *FSAdapter) ForgetInode(_ context.Context, op *fuseops.ForgetInodeOp) error {} -// func (a *FSAdapter) BatchForget(_ context.Context, op *fuseops.BatchForgetOp) error {} -// func (a *FSAdapter) OpenDir(_ context.Context, op *fuseops.OpenDirOp) error {} -// func (a *FSAdapter) ReadDir(_ context.Context, op *fuseops.ReadDirOp) error {} -// func (a *FSAdapter) ReleaseDirHandle(_ context.Context, op *fuseops.ReleaseDirHandleOp) error {} -// func (a *FSAdapter) OpenFile(_ context.Context, op *fuseops.OpenFileOp) error {} -// func (a *FSAdapter) ReadFile(_ context.Context, op *fuseops.ReadFileOp) error {} -// func (a *FSAdapter) ReleaseFileHandle(_ context.Context, op *fuseops.ReleaseFileHandleOp) error {} -// func (a *FSAdapter) ReadSymlink(_ context.Context, op *fuseops.ReadSymlinkOp) error {} -// func (a *FSAdapter) GetXattr(_ context.Context, op *fuseops.GetXattrOp) error {} -// func (a *FSAdapter) ListXattr(_ context.Context, op *fuseops.ListXattrOp) error {} -// func (a *FSAdapter) Destroy() {} |