aboutsummaryrefslogtreecommitdiff
path: root/mount.go
diff options
context:
space:
mode:
Diffstat (limited to 'mount.go')
-rw-r--r--mount.go35
1 files changed, 31 insertions, 4 deletions
diff --git a/mount.go b/mount.go
index f7378aa..489ae31 100644
--- a/mount.go
+++ b/mount.go
@@ -274,6 +274,7 @@ func initFuseFrontend(args *argContainer) (rootNode fs.InodeEmbedder, wipeKeys f
PlaintextNames: args.plaintextnames,
LongNames: args.longnames,
ConfigCustom: args._configCustom,
+ Config: args.config,
NoPrealloc: args.noprealloc,
ForceOwner: args._forceOwner,
Exclude: args.exclude,
@@ -329,8 +330,11 @@ func initFuseFrontend(args *argContainer) (rootNode fs.InodeEmbedder, wipeKeys f
// Init crypto backend
cCore := cryptocore.New(masterkey, cryptoBackend, IVBits, args.hkdf)
cEnc := contentenc.New(cCore, contentenc.DefaultBS)
- nameTransform := nametransform.New(cCore.EMECipher, frontendArgs.LongNames, args.longnamemax,
- args.raw64, []string(args.badname), frontendArgs.DeterministicNames)
+ var nameTransform *nametransform.NameTransform
+ if !args.plaintextnames {
+ nameTransform = nametransform.New(cCore.EMECipher, frontendArgs.LongNames, args.longnamemax,
+ args.raw64, []string(args.badname), frontendArgs.DeterministicNames)
+ }
// After the crypto backend is initialized,
// we can purge the master key from memory.
for i := range masterkey {
@@ -389,6 +393,7 @@ func initGoFuse(rootNode fs.InodeEmbedder, args *argContainer) *fuse.Server {
// Enable go-fuse warnings
fuseOpts.Logger = log.New(os.Stderr, "go-fuse: ", log.Lmicroseconds)
fuseOpts.MountOptions = fuse.MountOptions{
+ DisableReadDirPlus: !args.readdirplus,
// Writes and reads are usually capped at 128kiB on Linux through
// the FUSE_MAX_PAGES_PER_REQ kernel constant in fuse_i.h. Our
// sync.Pool buffer pools are sized acc. to the default. Users may set
@@ -449,9 +454,18 @@ func initGoFuse(rootNode fs.InodeEmbedder, args *argContainer) *fuse.Server {
if runtime.GOOS == "darwin" {
opts["volname"] = strings.Replace(path.Base(args.mountpoint), ",", "_", -1)
}
+ underlyingFilesystemRo, err := isReadOnlyFilesystem(args.cipherdir)
+ if err != nil {
+ tlog.Debug.Printf("Error checking if cipherdir is on a read-only filesystem: %s", err)
+ } else if underlyingFilesystemRo && args.rw {
+ tlog.Fatal.Printf("Writeable mount explicitly requested but cipherdir %s is on a read-only filesystem, refusing.", args.cipherdir)
+ os.Exit(exitcodes.Usage)
+ } else if underlyingFilesystemRo && !args.ro {
+ tlog.Info.Printf("Cipherdir %s is on a read-only filesystem, mounting as read-only.", args.cipherdir)
+ }
// The kernel enforces read-only operation, we just have to pass "ro".
- // Reverse mounts are always read-only.
- if args.ro || args.reverse {
+ // Reverse mounts and mounts with cipherdirs on read-only filesystems are always read-only.
+ if args.ro || args.reverse || underlyingFilesystemRo {
opts["ro"] = ""
} else if args.rw {
opts["rw"] = ""
@@ -562,3 +576,16 @@ func unmount(srv *fuse.Server, mountpoint string) {
}
}
}
+
+const (
+ ST_RDONLY = 0x1
+)
+
+func isReadOnlyFilesystem(path string) (bool, error) {
+ var stat syscall.Statfs_t
+ if err := syscall.Statfs(path, &stat); err != nil {
+ return false, err
+ }
+
+ return (stat.Flags & ST_RDONLY) != 0, nil
+}