aboutsummaryrefslogblamecommitdiffstats
path: root/vendor/bazil.org/fuse/options.go
blob: 65ce8a5410d2729f23fd8c9b901d1e00dde69e4e (plain) (tree)





















































































































































































































































































































                                                                                                    
package fuse

import (
    "errors"
    "strings"
)

func dummyOption(conf *mountConfig) error {
    return nil
}

// mountConfig holds the configuration for a mount operation.
// Use it by passing MountOption values to Mount.
type mountConfig struct {
    options          map[string]string
    maxReadahead     uint32
    initFlags        InitFlags
    osxfuseLocations []OSXFUSEPaths
}

func escapeComma(s string) string {
    s = strings.Replace(s, `\`, `\\`, -1)
    s = strings.Replace(s, `,`, `\,`, -1)
    return s
}

// getOptions makes a string of options suitable for passing to FUSE
// mount flag `-o`. Returns an empty string if no options were set.
// Any platform specific adjustments should happen before the call.
func (m *mountConfig) getOptions() string {
    var opts []string
    for k, v := range m.options {
        k = escapeComma(k)
        if v != "" {
            k += "=" + escapeComma(v)
        }
        opts = append(opts, k)
    }
    return strings.Join(opts, ",")
}

type mountOption func(*mountConfig) error

// MountOption is passed to Mount to change the behavior of the mount.
type MountOption mountOption

// FSName sets the file system name (also called source) that is
// visible in the list of mounted file systems.
//
// FreeBSD ignores this option.
func FSName(name string) MountOption {
    return func(conf *mountConfig) error {
        conf.options["fsname"] = name
        return nil
    }
}

// Subtype sets the subtype of the mount. The main type is always
// `fuse`. The type in a list of mounted file systems will look like
// `fuse.foo`.
//
// OS X ignores this option.
// FreeBSD ignores this option.
func Subtype(fstype string) MountOption {
    return func(conf *mountConfig) error {
        conf.options["subtype"] = fstype
        return nil
    }
}

// LocalVolume sets the volume to be local (instead of network),
// changing the behavior of Finder, Spotlight, and such.
//
// OS X only. Others ignore this option.
func LocalVolume() MountOption {
    return localVolume
}

// VolumeName sets the volume name shown in Finder.
//
// OS X only. Others ignore this option.
func VolumeName(name string) MountOption {
    return volumeName(name)
}

// NoAppleDouble makes OSXFUSE disallow files with names used by OS X
// to store extended attributes on file systems that do not support
// them natively.
//
// Such file names are:
//
//     ._*
//     .DS_Store
//
// OS X only.  Others ignore this option.
func NoAppleDouble() MountOption {
    return noAppleDouble
}

// NoAppleXattr makes OSXFUSE disallow extended attributes with the
// prefix "com.apple.". This disables persistent Finder state and
// other such information.
//
// OS X only.  Others ignore this option.
func NoAppleXattr() MountOption {
    return noAppleXattr
}

// ExclCreate causes O_EXCL flag to be set for only "truly" exclusive creates,
// i.e. create calls for which the initiator explicitly set the O_EXCL flag.
//
// OSXFUSE expects all create calls to return EEXIST in case the file
// already exists, regardless of whether O_EXCL was specified or not.
// To ensure this behavior, it normally sets OpenExclusive for all
// Create calls, regardless of whether the original call had it set.
// For distributed filesystems, that may force every file create to be
// a distributed consensus action, causing undesirable delays.
//
// This option makes the FUSE filesystem see the original flag value,
// and better decide when to ensure global consensus.
//
// Note that returning EEXIST on existing file create is still
// expected with OSXFUSE, regardless of the presence of the
// OpenExclusive flag.
//
// For more information, see
// https://github.com/osxfuse/osxfuse/issues/209
//
// OS X only. Others ignore this options.
// Requires OSXFUSE 3.4.1 or newer.
func ExclCreate() MountOption {
    return exclCreate
}

// DaemonTimeout sets the time in seconds between a request and a reply before
// the FUSE mount is declared dead.
//
// OS X and FreeBSD only. Others ignore this option.
func DaemonTimeout(name string) MountOption {
    return daemonTimeout(name)
}

var ErrCannotCombineAllowOtherAndAllowRoot = errors.New("cannot combine AllowOther and AllowRoot")

// AllowOther allows other users to access the file system.
//
// Only one of AllowOther or AllowRoot can be used.
func AllowOther() MountOption {
    return func(conf *mountConfig) error {
        if _, ok := conf.options["allow_root"]; ok {
            return ErrCannotCombineAllowOtherAndAllowRoot
        }
        conf.options["allow_other"] = ""
        return nil
    }
}

// AllowRoot allows other users to access the file system.
//
// Only one of AllowOther or AllowRoot can be used.
//
// FreeBSD ignores this option.
func AllowRoot() MountOption {
    return func(conf *mountConfig) error {
        if _, ok := conf.options["allow_other"]; ok {
            return ErrCannotCombineAllowOtherAndAllowRoot
        }
        conf.options["allow_root"] = ""
        return nil
    }
}

// AllowDev enables interpreting character or block special devices on the
// filesystem.
func AllowDev() MountOption {
    return func(conf *mountConfig) error {
        conf.options["dev"] = ""
        return nil
    }
}

// AllowSUID allows set-user-identifier or set-group-identifier bits to take
// effect.
func AllowSUID() MountOption {
    return func(conf *mountConfig) error {
        conf.options["suid"] = ""
        return nil
    }
}

// DefaultPermissions makes the kernel enforce access control based on
// the file mode (as in chmod).
//
// Without this option, the Node itself decides what is and is not
// allowed. This is normally ok because FUSE file systems cannot be
// accessed by other users without AllowOther/AllowRoot.
//
// FreeBSD ignores this option.
func DefaultPermissions() MountOption {
    return func(conf *mountConfig) error {
        conf.options["default_permissions"] = ""
        return nil
    }
}

// ReadOnly makes the mount read-only.
func ReadOnly() MountOption {
    return func(conf *mountConfig) error {
        conf.options["ro"] = ""
        return nil
    }
}

// MaxReadahead sets the number of bytes that can be prefetched for
// sequential reads. The kernel can enforce a maximum value lower than
// this.
//
// This setting makes the kernel perform speculative reads that do not
// originate from any client process. This usually tremendously
// improves read performance.
func MaxReadahead(n uint32) MountOption {
    return func(conf *mountConfig) error {
        conf.maxReadahead = n
        return nil
    }
}

// AsyncRead enables multiple outstanding read requests for the same
// handle. Without this, there is at most one request in flight at a
// time.
func AsyncRead() MountOption {
    return func(conf *mountConfig) error {
        conf.initFlags |= InitAsyncRead
        return nil
    }
}

// WritebackCache enables the kernel to buffer writes before sending
// them to the FUSE server. Without this, writethrough caching is
// used.
func WritebackCache() MountOption {
    return func(conf *mountConfig) error {
        conf.initFlags |= InitWritebackCache
        return nil
    }
}

// OSXFUSEPaths describes the paths used by an installed OSXFUSE
// version. See OSXFUSELocationV3 for typical values.
type OSXFUSEPaths struct {
    // Prefix for the device file. At mount time, an incrementing
    // number is suffixed until a free FUSE device is found.
    DevicePrefix string
    // Path of the load helper, used to load the kernel extension if
    // no device files are found.
    Load string
    // Path of the mount helper, used for the actual mount operation.
    Mount string
    // Environment variable used to pass the path to the executable
    // calling the mount helper.
    DaemonVar string
}

// Default paths for OSXFUSE. See OSXFUSELocations.
var (
    OSXFUSELocationV3 = OSXFUSEPaths{
        DevicePrefix: "/dev/osxfuse",
        Load:         "/Library/Filesystems/osxfuse.fs/Contents/Resources/load_osxfuse",
        Mount:        "/Library/Filesystems/osxfuse.fs/Contents/Resources/mount_osxfuse",
        DaemonVar:    "MOUNT_OSXFUSE_DAEMON_PATH",
    }
    OSXFUSELocationV2 = OSXFUSEPaths{
        DevicePrefix: "/dev/osxfuse",
        Load:         "/Library/Filesystems/osxfusefs.fs/Support/load_osxfusefs",
        Mount:        "/Library/Filesystems/osxfusefs.fs/Support/mount_osxfusefs",
        DaemonVar:    "MOUNT_FUSEFS_DAEMON_PATH",
    }
)

// OSXFUSELocations sets where to look for OSXFUSE files. The
// arguments are all the possible locations. The previous locations
// are replaced.
//
// Without this option, OSXFUSELocationV3 and OSXFUSELocationV2 are
// used.
//
// OS X only. Others ignore this option.
func OSXFUSELocations(paths ...OSXFUSEPaths) MountOption {
    return func(conf *mountConfig) error {
        if len(paths) == 0 {
            return errors.New("must specify at least one location for OSXFUSELocations")
        }
        // replace previous values, but make a copy so there's no
        // worries about caller mutating their slice
        conf.osxfuseLocations = append(conf.osxfuseLocations[:0], paths...)
        return nil
    }
}

// AllowNonEmptyMount allows the mounting over a non-empty directory.
//
// The files in it will be shadowed by the freshly created mount. By
// default these mounts are rejected to prevent accidental covering up
// of data, which could for example prevent automatic backup.
func AllowNonEmptyMount() MountOption {
    return func(conf *mountConfig) error {
        conf.options["nonempty"] = ""
        return nil
    }
}