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
|
||||
func (d *Dir) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||
fs.Debug(d.path, "Dir.Attr")
|
||||
a.Gid = gid
|
||||
a.Uid = uid
|
||||
a.Mode = os.ModeDir | dirPerms
|
||||
// FIXME include Valid so get some caching? Also mtime
|
||||
return nil
|
||||
|
|
|
@ -46,6 +46,8 @@ func (f *File) Attr(ctx context.Context, a *fuse.Attr) error {
|
|||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
fs.Debug(f.o, "File.Attr")
|
||||
a.Gid = gid
|
||||
a.Uid = uid
|
||||
a.Mode = filePerms
|
||||
// if o is nil it isn't valid yet, so return the size so far
|
||||
if f.o == nil {
|
||||
|
|
|
@ -10,12 +10,6 @@ import (
|
|||
"github.com/ncw/rclone/fs"
|
||||
)
|
||||
|
||||
// Default permissions
|
||||
const (
|
||||
dirPerms = 0755
|
||||
filePerms = 0644
|
||||
)
|
||||
|
||||
// FS represents the top level filing system
|
||||
type FS struct {
|
||||
f fs.Fs
|
||||
|
@ -30,6 +24,36 @@ func (f *FS) Root() (fusefs.Node, error) {
|
|||
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
|
||||
//
|
||||
// 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
|
||||
// report an error when fusermount is called.
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -5,23 +5,56 @@
|
|||
package mount
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"bazil.org/fuse"
|
||||
"github.com/ncw/rclone/cmd"
|
||||
"github.com/ncw/rclone/fs"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Globals
|
||||
var (
|
||||
noModTime = 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() {
|
||||
umask = unix.Umask(0) // read the umask
|
||||
unix.Umask(umask) // set it back to what it was
|
||||
cmd.Root.AddCommand(mountCmd)
|
||||
mountCmd.Flags().BoolVarP(&noModTime, "no-modtime", "", false, "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(&noModTime, "no-modtime", "", noModTime, "Don't read the modification time (can speed things up).")
|
||||
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{
|
||||
|
@ -85,10 +118,13 @@ mount won't do that, so will be less reliable than the rclone command.
|
|||
* Preserve timestamps
|
||||
* Move directories
|
||||
`,
|
||||
RunE: func(command *cobra.Command, args []string) error {
|
||||
Run: func(command *cobra.Command, args []string) {
|
||||
cmd.CheckArgs(2, 2, command, 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
|
||||
errChan, err := mount(f, mountpoint)
|
||||
if err != nil {
|
||||
|
|
Loading…
Add table
Reference in a new issue