diff --git a/connection.go b/connection.go index 038c2d5..d06171b 100644 --- a/connection.go +++ b/connection.go @@ -148,6 +148,8 @@ func (c *Connection) Init() error { c.protocol = initOp.Kernel } + cacheSymlinks := initOp.Flags&fusekernel.InitCacheSymlinks > 0 + // Respond to the init op. initOp.Library = c.protocol initOp.MaxReadahead = maxReadahead @@ -163,6 +165,12 @@ func (c *Connection) Init() error { initOp.Flags |= 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 + } + c.Reply(ctx, nil) return nil } diff --git a/internal/fusekernel/fuse_kernel.go b/internal/fusekernel/fuse_kernel.go index c716025..f06a8ea 100644 --- a/internal/fusekernel/fuse_kernel.go +++ b/internal/fusekernel/fuse_kernel.go @@ -266,6 +266,7 @@ const ( InitAsyncDIO InitFlags = 1 << 15 InitWritebackCache InitFlags = 1 << 16 InitNoOpenSupport InitFlags = 1 << 17 + InitCacheSymlinks InitFlags = 1 << 23 InitCaseSensitive InitFlags = 1 << 29 // OS X only InitVolRename InitFlags = 1 << 30 // OS X only @@ -296,6 +297,7 @@ var initFlagNames = []flagName{ {uint32(InitAsyncDIO), "InitAsyncDIO"}, {uint32(InitWritebackCache), "InitWritebackCache"}, {uint32(InitNoOpenSupport), "InitNoOpenSupport"}, + {uint32(InitCacheSymlinks), "InitCacheSymlinks"}, {uint32(InitCaseSensitive), "InitCaseSensitive"}, {uint32(InitVolRename), "InitVolRename"}, diff --git a/mount_config.go b/mount_config.go index f4941c7..62e1d17 100644 --- a/mount_config.go +++ b/mount_config.go @@ -128,6 +128,17 @@ type MountConfig struct { // entries will be cached for an arbitrarily long time. EnableVnodeCaching bool + // Linux only. + // + // Linux 4.20 introduced caching symlink targets in the page cache: + // https://github.com/torvalds/linux/commit/5571f1e65486be025f73fa6aa30fb03725d362a2 + // + // This is not enabled by default because the old behavior masked a bug: + // file systems could return any size in the inode attributes of + // symlinks. After enabling caching, the specified size caps the symlink + // target. + EnableSymlinkCaching bool + // OS X only. // // The name of the mounted volume, as displayed in the Finder. If empty, a