mount: cleanup os specific option handling and documentation

This commit is contained in:
albertony 2020-11-11 00:17:25 +01:00 committed by Nick Craig-Wood
parent e92cb9e8f8
commit 5f47e1e034
3 changed files with 65 additions and 74 deletions

View File

@ -40,32 +40,14 @@ func init() {
func mountOptions(VFS *vfs.VFS, device string, mountpoint string, opt *mountlib.Options) (options []string) { func mountOptions(VFS *vfs.VFS, device string, mountpoint string, opt *mountlib.Options) (options []string) {
// Options // Options
options = []string{ options = []string{
"-o", "fsname=" + device,
"-o", "subtype=rclone",
"-o", fmt.Sprintf("max_readahead=%d", opt.MaxReadAhead),
"-o", fmt.Sprintf("attr_timeout=%g", opt.AttrTimeout.Seconds()), "-o", fmt.Sprintf("attr_timeout=%g", opt.AttrTimeout.Seconds()),
// This causes FUSE to supply O_TRUNC with the Open
// call which is more efficient for cmount. However
// it does not work with cgofuse on Windows with
// WinFSP so cmount must work with or without it.
"-o", "atomic_o_trunc",
} }
if opt.DebugFUSE { if opt.DebugFUSE {
options = append(options, "-o", "debug") options = append(options, "-o", "debug")
} }
// OSX options // Determine if ExtraOptions already has an opt in
if runtime.GOOS == "darwin" { hasExtraOption := func(optionName string) bool {
if opt.NoAppleDouble {
options = append(options, "-o", "noappledouble")
}
if opt.NoAppleXattr {
options = append(options, "-o", "noapplexattr")
}
}
// determine if ExtraOptions already has an opt in
hasOption := func(optionName string) bool {
optionName += "=" optionName += "="
for _, option := range opt.ExtraOptions { for _, option := range opt.ExtraOptions {
if strings.HasPrefix(option, optionName) { if strings.HasPrefix(option, optionName) {
@ -75,13 +57,12 @@ func mountOptions(VFS *vfs.VFS, device string, mountpoint string, opt *mountlib.
return false return false
} }
// Windows options
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
// These cause WinFsp to mean the current user // Setting uid and gid to -1 by default, which mean current user in WinFsp
if !hasOption("uid") { if !hasExtraOption("uid") {
options = append(options, "-o", "uid=-1") options = append(options, "-o", "uid=-1")
} }
if !hasOption("gid") { if !hasExtraOption("gid") {
options = append(options, "-o", "gid=-1") options = append(options, "-o", "gid=-1")
} }
options = append(options, "--FileSystemName=rclone") options = append(options, "--FileSystemName=rclone")
@ -92,31 +73,47 @@ func mountOptions(VFS *vfs.VFS, device string, mountpoint string, opt *mountlib.
options = append(options, "-o", "volname="+opt.VolumeName) options = append(options, "-o", "volname="+opt.VolumeName)
} }
} }
} else if runtime.GOOS == "darwin" { } else {
if opt.VolumeName != "" { options = append(options, "-o", "fsname="+device)
options = append(options, "-o", "volname="+opt.VolumeName) options = append(options, "-o", "subtype=rclone")
options = append(options, "-o", fmt.Sprintf("max_readahead=%d", opt.MaxReadAhead))
// This causes FUSE to supply O_TRUNC with the Open
// call which is more efficient for cmount. However
// it does not work with cgofuse on Windows with
// WinFSP so cmount must work with or without it.
options = append(options, "-o", "atomic_o_trunc")
if opt.DaemonTimeout != 0 {
options = append(options, "-o", fmt.Sprintf("daemon_timeout=%d", int(opt.DaemonTimeout.Seconds())))
}
if opt.AllowNonEmpty {
options = append(options, "-o", "nonempty")
}
if opt.AllowOther {
options = append(options, "-o", "allow_other")
}
if opt.AllowRoot {
options = append(options, "-o", "allow_root")
}
if opt.DefaultPermissions {
options = append(options, "-o", "default_permissions")
}
if VFS.Opt.ReadOnly {
options = append(options, "-o", "ro")
}
if opt.WritebackCache {
// FIXME? options = append(options, "-o", WritebackCache())
}
if runtime.GOOS == "darwin" {
if opt.VolumeName != "" {
options = append(options, "-o", "volname="+opt.VolumeName)
}
if opt.NoAppleDouble {
options = append(options, "-o", "noappledouble")
}
if opt.NoAppleXattr {
options = append(options, "-o", "noapplexattr")
}
} }
}
if opt.AllowNonEmpty {
options = append(options, "-o", "nonempty")
}
if opt.AllowOther {
options = append(options, "-o", "allow_other")
}
if opt.AllowRoot {
options = append(options, "-o", "allow_root")
}
if opt.DefaultPermissions {
options = append(options, "-o", "default_permissions")
}
if VFS.Opt.ReadOnly {
options = append(options, "-o", "ro")
}
if opt.WritebackCache {
// FIXME? options = append(options, "-o", WritebackCache())
}
if opt.DaemonTimeout != 0 {
options = append(options, "-o", fmt.Sprintf("daemon_timeout=%d", int(opt.DaemonTimeout.Seconds())))
} }
for _, option := range opt.ExtraOptions { for _, option := range opt.ExtraOptions {
options = append(options, "-o", option) options = append(options, "-o", option)

View File

@ -35,12 +35,6 @@ func mountOptions(VFS *vfs.VFS, device string, opt *mountlib.Options) (options [
if opt.AsyncRead { if opt.AsyncRead {
options = append(options, fuse.AsyncRead()) options = append(options, fuse.AsyncRead())
} }
if opt.NoAppleDouble {
options = append(options, fuse.NoAppleDouble())
}
if opt.NoAppleXattr {
options = append(options, fuse.NoAppleXattr())
}
if opt.AllowNonEmpty { if opt.AllowNonEmpty {
options = append(options, fuse.AllowNonEmptyMount()) options = append(options, fuse.AllowNonEmptyMount())
} }

View File

@ -84,25 +84,26 @@ var (
func AddFlags(flagSet *pflag.FlagSet) { func AddFlags(flagSet *pflag.FlagSet) {
rc.AddOption("mount", &Opt) rc.AddOption("mount", &Opt)
flags.BoolVarP(flagSet, &Opt.DebugFUSE, "debug-fuse", "", Opt.DebugFUSE, "Debug the FUSE internals - needs -v.") flags.BoolVarP(flagSet, &Opt.DebugFUSE, "debug-fuse", "", Opt.DebugFUSE, "Debug the FUSE internals - needs -v.")
flags.BoolVarP(flagSet, &Opt.AllowNonEmpty, "allow-non-empty", "", Opt.AllowNonEmpty, "Allow mounting over a non-empty directory (not Windows).")
flags.BoolVarP(flagSet, &Opt.AllowRoot, "allow-root", "", Opt.AllowRoot, "Allow access to root user (not Windows).")
flags.BoolVarP(flagSet, &Opt.AllowOther, "allow-other", "", Opt.AllowOther, "Allow access to other users (not Windows).")
flags.BoolVarP(flagSet, &Opt.DefaultPermissions, "default-permissions", "", Opt.DefaultPermissions, "Makes kernel enforce access control based on the file mode.")
flags.BoolVarP(flagSet, &Opt.WritebackCache, "write-back-cache", "", Opt.WritebackCache, "Makes kernel buffer writes before sending them to rclone. Without this, writethrough caching is used.")
flags.FVarP(flagSet, &Opt.MaxReadAhead, "max-read-ahead", "", "The number of bytes that can be prefetched for sequential reads.")
flags.DurationVarP(flagSet, &Opt.AttrTimeout, "attr-timeout", "", Opt.AttrTimeout, "Time for which file/directory attributes are cached.") flags.DurationVarP(flagSet, &Opt.AttrTimeout, "attr-timeout", "", Opt.AttrTimeout, "Time for which file/directory attributes are cached.")
flags.StringArrayVarP(flagSet, &Opt.ExtraOptions, "option", "o", []string{}, "Option for libfuse/WinFsp. Repeat if required.") flags.StringArrayVarP(flagSet, &Opt.ExtraOptions, "option", "o", []string{}, "Option for libfuse/WinFsp. Repeat if required.")
flags.StringArrayVarP(flagSet, &Opt.ExtraFlags, "fuse-flag", "", []string{}, "Flags or arguments to be passed direct to libfuse/WinFsp. Repeat if required.") flags.StringArrayVarP(flagSet, &Opt.ExtraFlags, "fuse-flag", "", []string{}, "Flags or arguments to be passed direct to libfuse/WinFsp. Repeat if required.")
flags.BoolVarP(flagSet, &Opt.Daemon, "daemon", "", Opt.Daemon, "Run mount as a daemon (background mode).") // Non-Windows only
flags.StringVarP(flagSet, &Opt.VolumeName, "volname", "", Opt.VolumeName, "Set the volume name (not supported by all OSes).") flags.BoolVarP(flagSet, &Opt.Daemon, "daemon", "", Opt.Daemon, "Run mount as a daemon (background mode). Not supported on Windows.")
flags.DurationVarP(flagSet, &Opt.DaemonTimeout, "daemon-timeout", "", Opt.DaemonTimeout, "Time limit for rclone to respond to kernel (not supported by all OSes).") flags.DurationVarP(flagSet, &Opt.DaemonTimeout, "daemon-timeout", "", Opt.DaemonTimeout, "Time limit for rclone to respond to kernel. Not supported on Windows.")
flags.BoolVarP(flagSet, &Opt.AsyncRead, "async-read", "", Opt.AsyncRead, "Use asynchronous reads.") flags.BoolVarP(flagSet, &Opt.DefaultPermissions, "default-permissions", "", Opt.DefaultPermissions, "Makes kernel enforce access control based on the file mode. Not supported on Windows.")
if runtime.GOOS == "darwin" { flags.BoolVarP(flagSet, &Opt.AllowNonEmpty, "allow-non-empty", "", Opt.AllowNonEmpty, "Allow mounting over a non-empty directory. Not supported on Windows.")
flags.BoolVarP(flagSet, &Opt.NoAppleDouble, "noappledouble", "", Opt.NoAppleDouble, "Sets the OSXFUSE option noappledouble.") flags.BoolVarP(flagSet, &Opt.AllowRoot, "allow-root", "", Opt.AllowRoot, "Allow access to root user. Not supported on Windows.")
flags.BoolVarP(flagSet, &Opt.NoAppleXattr, "noapplexattr", "", Opt.NoAppleXattr, "Sets the OSXFUSE option noapplexattr.") flags.BoolVarP(flagSet, &Opt.AllowOther, "allow-other", "", Opt.AllowOther, "Allow access to other users. Not supported on Windows.")
} else if runtime.GOOS == "windows" { flags.BoolVarP(flagSet, &Opt.AsyncRead, "async-read", "", Opt.AsyncRead, "Use asynchronous reads. Not supported on Windows.")
flags.BoolVarP(flagSet, &Opt.NetworkMode, "network-mode", "", Opt.NetworkMode, "Mount as remote network drive, instead of fixed disk drive.") flags.FVarP(flagSet, &Opt.MaxReadAhead, "max-read-ahead", "", "The number of bytes that can be prefetched for sequential reads. Not supported on Windows.")
} flags.BoolVarP(flagSet, &Opt.WritebackCache, "write-back-cache", "", Opt.WritebackCache, "Makes kernel buffer writes before sending them to rclone. Without this, writethrough caching is used. Not supported on Windows.")
// Windows and OSX
flags.StringVarP(flagSet, &Opt.VolumeName, "volname", "", Opt.VolumeName, "Set the volume name. Supported on Windows and OSX only.")
// OSX only
flags.BoolVarP(flagSet, &Opt.NoAppleDouble, "noappledouble", "", Opt.NoAppleDouble, "Ignore Apple Double (._) and .DS_Store files. Supported on OSX only.")
flags.BoolVarP(flagSet, &Opt.NoAppleXattr, "noapplexattr", "", Opt.NoAppleXattr, "Ignore all \"com.apple.*\" extended attributes. Supported on OSX only.")
// Windows only
flags.BoolVarP(flagSet, &Opt.NetworkMode, "network-mode", "", Opt.NetworkMode, "Mount as remote network drive, instead of fixed disk drive. Supported on Windows only")
} }
// Check if folder is empty // Check if folder is empty
@ -165,10 +166,9 @@ FUSE.
First set up your remote using ` + "`rclone config`" + `. Check it works with ` + "`rclone ls`" + ` etc. First set up your remote using ` + "`rclone config`" + `. Check it works with ` + "`rclone ls`" + ` etc.
You can either run mount in foreground mode or background (daemon) mode. Mount runs in On Linux and OSX, you can either run mount in foreground mode or background (daemon) mode.
foreground mode by default, use the ` + "`--daemon`" + ` flag to specify background mode. Mount runs in foreground mode by default, use the ` + "`--daemon`" + ` flag to specify background mode.
Background mode is only supported on Linux and OSX, you can only run mount in You can only run mount in foreground mode on Windows.
foreground mode on Windows.
On Linux/macOS/FreeBSD Start the mount like this where ` + "`/path/to/local/mount`" + ` On Linux/macOS/FreeBSD Start the mount like this where ` + "`/path/to/local/mount`" + `
is an **empty** **existing** directory. is an **empty** **existing** directory.