forked from TrueCloudLab/rclone
mount: Implement FUSE mount options - fixes #653
This commit is contained in:
parent
5b913884cf
commit
5c91623148
4 changed files with 79 additions and 11 deletions
|
@ -130,6 +130,8 @@ var _ fusefs.Node = (*Dir)(nil)
|
||||||
// Attr updates the attribes of a directory
|
// Attr updates the attribes of a directory
|
||||||
func (d *Dir) Attr(ctx context.Context, a *fuse.Attr) error {
|
func (d *Dir) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
fs.Debug(d.path, "Dir.Attr")
|
fs.Debug(d.path, "Dir.Attr")
|
||||||
|
a.Gid = gid
|
||||||
|
a.Uid = uid
|
||||||
a.Mode = os.ModeDir | dirPerms
|
a.Mode = os.ModeDir | dirPerms
|
||||||
// FIXME include Valid so get some caching? Also mtime
|
// FIXME include Valid so get some caching? Also mtime
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -46,6 +46,8 @@ func (f *File) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
f.mu.Lock()
|
f.mu.Lock()
|
||||||
defer f.mu.Unlock()
|
defer f.mu.Unlock()
|
||||||
fs.Debug(f.o, "File.Attr")
|
fs.Debug(f.o, "File.Attr")
|
||||||
|
a.Gid = gid
|
||||||
|
a.Uid = uid
|
||||||
a.Mode = filePerms
|
a.Mode = filePerms
|
||||||
// if o is nil it isn't valid yet, so return the size so far
|
// if o is nil it isn't valid yet, so return the size so far
|
||||||
if f.o == nil {
|
if f.o == nil {
|
||||||
|
|
|
@ -10,12 +10,6 @@ import (
|
||||||
"github.com/ncw/rclone/fs"
|
"github.com/ncw/rclone/fs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Default permissions
|
|
||||||
const (
|
|
||||||
dirPerms = 0755
|
|
||||||
filePerms = 0644
|
|
||||||
)
|
|
||||||
|
|
||||||
// FS represents the top level filing system
|
// FS represents the top level filing system
|
||||||
type FS struct {
|
type FS struct {
|
||||||
f fs.Fs
|
f fs.Fs
|
||||||
|
@ -30,6 +24,36 @@ func (f *FS) Root() (fusefs.Node, error) {
|
||||||
return newDir(f.f, ""), nil
|
return newDir(f.f, ""), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mountOptions configures the options from the command line flags
|
||||||
|
func mountOptions(device string) (options []fuse.MountOption) {
|
||||||
|
options = []fuse.MountOption{
|
||||||
|
fuse.MaxReadahead(uint32(maxReadAhead)),
|
||||||
|
fuse.Subtype("rclone"),
|
||||||
|
fuse.FSName(device), fuse.VolumeName(device),
|
||||||
|
fuse.NoAppleDouble(),
|
||||||
|
fuse.NoAppleXattr(),
|
||||||
|
}
|
||||||
|
if allowNonEmpty {
|
||||||
|
options = append(options, fuse.AllowNonEmptyMount())
|
||||||
|
}
|
||||||
|
if allowOther {
|
||||||
|
options = append(options, fuse.AllowOther())
|
||||||
|
}
|
||||||
|
if allowRoot {
|
||||||
|
options = append(options, fuse.AllowRoot())
|
||||||
|
}
|
||||||
|
if defaultPermissions {
|
||||||
|
options = append(options, fuse.DefaultPermissions())
|
||||||
|
}
|
||||||
|
if readOnly {
|
||||||
|
options = append(options, fuse.ReadOnly())
|
||||||
|
}
|
||||||
|
if writebackCache {
|
||||||
|
options = append(options, fuse.WritebackCache())
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
// mount the file system
|
// mount the file system
|
||||||
//
|
//
|
||||||
// The mount point will be ready when this returns.
|
// The mount point will be ready when this returns.
|
||||||
|
@ -37,7 +61,7 @@ func (f *FS) Root() (fusefs.Node, error) {
|
||||||
// returns an error, and an error channel for the serve process to
|
// returns an error, and an error channel for the serve process to
|
||||||
// report an error when fusermount is called.
|
// report an error when fusermount is called.
|
||||||
func mount(f fs.Fs, mountpoint string) (<-chan error, error) {
|
func mount(f fs.Fs, mountpoint string) (<-chan error, error) {
|
||||||
c, err := fuse.Mount(mountpoint)
|
c, err := fuse.Mount(mountpoint, mountOptions(f.Name()+":"+f.Root())...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,23 +5,56 @@
|
||||||
package mount
|
package mount
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
"bazil.org/fuse"
|
"bazil.org/fuse"
|
||||||
"github.com/ncw/rclone/cmd"
|
"github.com/ncw/rclone/cmd"
|
||||||
"github.com/ncw/rclone/fs"
|
"github.com/ncw/rclone/fs"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
var (
|
var (
|
||||||
noModTime = false
|
noModTime = false
|
||||||
debugFUSE = false
|
debugFUSE = false
|
||||||
|
// mount options
|
||||||
|
readOnly = false
|
||||||
|
allowNonEmpty = false
|
||||||
|
allowRoot = false
|
||||||
|
allowOther = false
|
||||||
|
defaultPermissions = false
|
||||||
|
writebackCache = false
|
||||||
|
maxReadAhead fs.SizeSuffix = 128 * 1024
|
||||||
|
umask = 0
|
||||||
|
uid = uint32(unix.Geteuid())
|
||||||
|
gid = uint32(unix.Getegid())
|
||||||
|
// foreground = false
|
||||||
|
// default permissions for directories - modified by umask in Mount
|
||||||
|
dirPerms = os.FileMode(0777)
|
||||||
|
filePerms = os.FileMode(0666)
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
umask = unix.Umask(0) // read the umask
|
||||||
|
unix.Umask(umask) // set it back to what it was
|
||||||
cmd.Root.AddCommand(mountCmd)
|
cmd.Root.AddCommand(mountCmd)
|
||||||
mountCmd.Flags().BoolVarP(&noModTime, "no-modtime", "", false, "Don't read the modification time (can speed things up).")
|
mountCmd.Flags().BoolVarP(&noModTime, "no-modtime", "", noModTime, "Don't read the modification time (can speed things up).")
|
||||||
mountCmd.Flags().BoolVarP(&debugFUSE, "debug-fuse", "", false, "Debug the FUSE internals - needs -v.")
|
mountCmd.Flags().BoolVarP(&debugFUSE, "debug-fuse", "", debugFUSE, "Debug the FUSE internals - needs -v.")
|
||||||
|
// mount options
|
||||||
|
mountCmd.Flags().BoolVarP(&readOnly, "read-only", "", readOnly, "Mount read-only.")
|
||||||
|
mountCmd.Flags().BoolVarP(&allowNonEmpty, "allow-non-empty", "", allowNonEmpty, "Allow mounting over a non-empty directory.")
|
||||||
|
mountCmd.Flags().BoolVarP(&allowRoot, "allow-root", "", allowRoot, "Allow access to root user.")
|
||||||
|
mountCmd.Flags().BoolVarP(&allowOther, "allow-other", "", allowOther, "Allow access to other users.")
|
||||||
|
mountCmd.Flags().BoolVarP(&defaultPermissions, "default-permissions", "", defaultPermissions, "Makes kernel enforce access control based on the file mode.")
|
||||||
|
mountCmd.Flags().BoolVarP(&writebackCache, "write-back-cache", "", writebackCache, "Makes kernel buffer writes before sending them to rclone. Without this, writethrough caching is used.")
|
||||||
|
mountCmd.Flags().VarP(&maxReadAhead, "max-read-ahead", "", "The number of bytes that can be prefetched for sequential reads.")
|
||||||
|
mountCmd.Flags().IntVarP(&umask, "umask", "", umask, "Override the permission bits set by the filesystem.")
|
||||||
|
mountCmd.Flags().Uint32VarP(&uid, "uid", "", uid, "Override the uid field set by the filesystem.")
|
||||||
|
mountCmd.Flags().Uint32VarP(&gid, "gid", "", gid, "Override the gid field set by the filesystem.")
|
||||||
|
//mountCmd.Flags().BoolVarP(&foreground, "foreground", "", foreground, "Do not detach.")
|
||||||
}
|
}
|
||||||
|
|
||||||
var mountCmd = &cobra.Command{
|
var mountCmd = &cobra.Command{
|
||||||
|
@ -85,10 +118,13 @@ mount won't do that, so will be less reliable than the rclone command.
|
||||||
* Preserve timestamps
|
* Preserve timestamps
|
||||||
* Move directories
|
* Move directories
|
||||||
`,
|
`,
|
||||||
RunE: func(command *cobra.Command, args []string) error {
|
Run: func(command *cobra.Command, args []string) {
|
||||||
cmd.CheckArgs(2, 2, command, args)
|
cmd.CheckArgs(2, 2, command, args)
|
||||||
fdst := cmd.NewFsDst(args)
|
fdst := cmd.NewFsDst(args)
|
||||||
return Mount(fdst, args[1])
|
err := Mount(fdst, args[1])
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Fatal error: %v", err)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +138,10 @@ func Mount(f fs.Fs, mountpoint string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set permissions
|
||||||
|
dirPerms = 0777 &^ os.FileMode(umask)
|
||||||
|
filePerms = 0666 &^ os.FileMode(umask)
|
||||||
|
|
||||||
// Mount it
|
// Mount it
|
||||||
errChan, err := mount(f, mountpoint)
|
errChan, err := mount(f, mountpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Add table
Reference in a new issue