diff --git a/connection.go b/connection.go index ebb86b73..21ee46f7 100644 --- a/connection.go +++ b/connection.go @@ -174,13 +174,17 @@ func (c *Connection) Init() error { initOp.MaxReadahead = maxReadahead initOp.MaxWrite = buffer.MaxWriteSize - initOp.Flags = 0 + initOp.OutFlags = 0 + initOp.OutFlags2 = 0 + + // Initialize the extended flags + initOp.OutFlags |= fusekernel.InitExt // Tell the kernel not to use pitifully small 4 KiB writes. - initOp.Flags |= fusekernel.InitBigWrites + initOp.OutFlags |= fusekernel.InitBigWrites if c.cfg.EnableAsyncReads { - initOp.Flags |= fusekernel.InitAsyncRead + initOp.OutFlags |= fusekernel.InitAsyncRead } // kernel 4.20 increases the max from 32 -> 256 @@ -189,46 +193,51 @@ func (c *Connection) Init() error { // Enable writeback caching if the user hasn't asked us not to. if !c.cfg.DisableWritebackCaching { - initOp.Flags |= fusekernel.InitWritebackCache + initOp.OutFlags |= fusekernel.InitWritebackCache } // Enable caching symlink targets in the kernel page cache if the user opted // into it (might require fixing the size field of inode attributes first): if c.cfg.EnableSymlinkCaching && cacheSymlinks { - initOp.Flags |= fusekernel.InitCacheSymlinks + initOp.OutFlags |= fusekernel.InitCacheSymlinks } // Tell the kernel to treat returning -ENOSYS on OpenFile as not needing // OpenFile calls at all (Linux >= 3.16): if c.cfg.EnableNoOpenSupport && noOpenSupport { - initOp.Flags |= fusekernel.InitNoOpenSupport + initOp.OutFlags |= fusekernel.InitNoOpenSupport } // Tell the kernel to treat returning -ENOSYS on OpenDir as not needing // OpenDir calls at all (Linux >= 5.1): if c.cfg.EnableNoOpendirSupport && noOpendirSupport { - initOp.Flags |= fusekernel.InitNoOpendirSupport + initOp.OutFlags |= fusekernel.InitNoOpendirSupport } // Tell the Kernel to allow sending parallel lookup and readdir operations. if c.cfg.EnableParallelDirOps { - initOp.Flags |= fusekernel.InitParallelDirOps + initOp.OutFlags |= fusekernel.InitParallelDirOps } if c.cfg.EnableAtomicTrunc { - initOp.Flags |= fusekernel.InitAtomicTrunc + initOp.OutFlags |= fusekernel.InitAtomicTrunc } if c.cfg.EnableReaddirplus { // Enable Readdirplus support, allowing the kernel to use Readdirplus - initOp.Flags |= fusekernel.InitDoReaddirplus + initOp.OutFlags |= fusekernel.InitDoReaddirplus if c.cfg.EnableAutoReaddirplus { // Enable adaptive Readdirplus, allowing the kernel to choose between Readdirplus and Readdir - initOp.Flags |= fusekernel.InitReaddirplusAuto + initOp.OutFlags |= fusekernel.InitReaddirplusAuto } } + // Tell the kernel to allow shared mmap() for files opened with OpenDirectIO + if c.cfg.AllowDirectIOMmap { + initOp.OutFlags2 |= fusekernel.InitDirectIOAllowMmap + } + return c.Reply(ctx, nil) } diff --git a/internal/fusekernel/fuse_kernel.go b/internal/fusekernel/fuse_kernel.go index 8c47b524..fa1d9c95 100644 --- a/internal/fusekernel/fuse_kernel.go +++ b/internal/fusekernel/fuse_kernel.go @@ -252,7 +252,8 @@ var openResponseFlagNames = []flagName{ } // The InitFlags are used in the Init exchange. -type InitFlags uint32 +type InitFlags uint32 // first 32 bit flags +type InitFlags2 uint32 // second 32-bit flags, used when InitExt is set in the first 32 bits const ( InitAsyncRead InitFlags = 1 << 0 @@ -277,10 +278,13 @@ const ( InitMaxPages InitFlags = 1 << 22 InitCacheSymlinks InitFlags = 1 << 23 InitNoOpendirSupport InitFlags = 1 << 24 + InitExt InitFlags = 1 << 30 InitCaseSensitive InitFlags = 1 << 29 // OS X only InitVolRename InitFlags = 1 << 30 // OS X only InitXtimes InitFlags = 1 << 31 // OS X only + + InitDirectIOAllowMmap InitFlags2 = 1 << 4 ) type flagName struct { @@ -738,6 +742,7 @@ type InitIn struct { Minor uint32 MaxReadahead uint32 Flags uint32 + Flags2 uint32 } const InitInSize = int(unsafe.Sizeof(InitIn{})) @@ -753,7 +758,8 @@ type InitOut struct { TimeGran uint32 MaxPages uint16 MapAlignment uint16 - Unused [8]uint32 + Flags2 uint32 + Unused [7]uint32 } type InterruptIn struct { diff --git a/mount_config.go b/mount_config.go index f95895ad..8f629430 100644 --- a/mount_config.go +++ b/mount_config.go @@ -221,6 +221,9 @@ type MountConfig struct { // use ReaddirPlus for directory listing. EnableAutoReaddirplus bool + // Flag to allow mmap() with MAP_SHARED for files opened with OpenDirectIO + AllowDirectIOMmap bool + // UseVectoredRead is a legacy flag kept for backward compatibility. It is now a no-op. // // The term vectored read was a misnomer for this flag. Its actual meaning was that diff --git a/ops.go b/ops.go index fe21a64f..725cd87b 100644 --- a/ops.go +++ b/ops.go @@ -35,12 +35,13 @@ type interruptOp struct { type initOp struct { // In Kernel fusekernel.Protocol - - // In/out - Flags fusekernel.InitFlags + Flags fusekernel.InitFlags + Flags2 fusekernel.InitFlags2 // Out Library fusekernel.Protocol + OutFlags fusekernel.InitFlags + OutFlags2 fusekernel.InitFlags2 MaxReadahead uint32 MaxBackground uint16 MaxWrite uint32