Commit 48c07fc7 authored by Kirill Smelkov's avatar Kirill Smelkov Committed by Han-Wen Nienhuys

fuse: allow filesystems to disable CAP_AUTO_INVAL_DATA

CAP_AUTO_INVAL_DATA is capability of kernel, but from the point of view
of a filesystem it is not a capability, but a behaviour request: if set,
it requests to kernel - filesystem client - to perform data cache
invalidations based on heuristics. Current heuristic is to drop data
cache for a file if kernel sees file's mtime being changed:

	https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/fuse/inode.c?id=v5.0-0-g1c163f4c7b3f#n238
	https://git.kernel.org/linus/eed2179efe

However this could be unwanted behaviour if filesystem is careful to
explicitly invalidate local file cache: despite filesystem attempts to
preciously keep data cache, the whole cache of the file is unnecessarily
dropped.

-> To fix add a new mount options for filesystems to indicate they are
careful with respect to data cache invalidations and thus should be
fully responsible for invalidating data cache. Teach go-fuse to not send
CAP_AUTO_INVAL_DATA in this mode to kernel on FUSE handshake.

Note, as of upcoming Linux 5.1 (estimated to be released mid 2019), FUSE
client in kernel still automatically and unconditionally drops whole
data cache of a file if its sees size change. Kernel and go-fuse patches
to fix that are here:

	https://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git/commit/?id=ad2ba64dd489
	https://github.com/hanwen/go-fuse/pull/273

The kernel patch is likely to enter mainline kernel when 5.2 merge
window opens. We'll remove XXX in a follow-up go-fuse patch that adds
support for CAP_EXPLICIT_INVAL_DATA.
parent 98229206
......@@ -154,6 +154,16 @@ type MountOptions struct {
// If set, ask kernel to forward file locks to FUSE. If using,
// you must implement the GetLk/SetLk/SetLkw methods.
EnableLocks bool
// If set, ask kernel not to do automatic data cache invalidation.
// The filesystem is fully responsible for invalidating data cache.
//
// XXX for Linux ExplicitDataCacheControl currently disables data cache
// to be automatically invalidated only on file mtime change. If file size
// changes, Linux currently unconditionally discards whole cache of the
// file. See https://github.com/hanwen/go-fuse/pull/273 for kernel +
// go-fuse patches with corresponding fixes.
ExplicitDataCacheControl bool
}
// RawFileSystem is an interface close to the FUSE wire protocol.
......
......@@ -89,12 +89,26 @@ func doInit(server *Server, req *request) {
server.reqMu.Lock()
server.kernelSettings = *input
server.kernelSettings.Flags = input.Flags & (CAP_ASYNC_READ | CAP_BIG_WRITES | CAP_FILE_OPS |
CAP_AUTO_INVAL_DATA | CAP_READDIRPLUS | CAP_NO_OPEN_SUPPORT | CAP_PARALLEL_DIROPS)
CAP_READDIRPLUS | CAP_NO_OPEN_SUPPORT | CAP_PARALLEL_DIROPS)
if server.opts.EnableLocks {
server.kernelSettings.Flags |= CAP_FLOCK_LOCKS | CAP_POSIX_LOCKS
}
dataCacheMode := input.Flags & CAP_AUTO_INVAL_DATA
if server.opts.ExplicitDataCacheControl {
// XXX this only disables automatic invalidations on mtime
// change, but not on size change.
//
// TODO explicitly disable invalidations on size change when
// kernel has proper support. Details:
//
// https://github.com/hanwen/go-fuse/pull/273
dataCacheMode = 0
}
server.kernelSettings.Flags |= dataCacheMode
if input.Minor >= 13 {
server.setSplice()
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment