summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEtienne Dublé <etienne.duble@imag.fr>2020-09-20 20:08:15 +0200
committerGitHub <noreply@github.com>2020-09-20 19:08:15 +0100
commitba3b225a126ebb3c6d4fe27c9f7c73aa4167001e (patch)
tree19149b92c169f419778e5e9799054b0c52243150
parent5b901ee0315658035661332d6d85d8bfd8816b6b (diff)
downloadfuse-ba3b225a126ebb3c6d4fe27c9f7c73aa4167001e.tar.gz
Allow caching symlinks in kernel page cache. (#551)
This commit defines a new capability called `FUSE_CAP_CACHE_SYMLINKS`. It is off by default but you can now enable it by setting this flag in in the `want` field of the `fuse_conn_info` structure. When enabled, the kernel will save symlinks in its page cache, by making use of the feature introduced in kernel 4.20: https://github.com/torvalds/linux/commit/5571f1e65486be025f73fa6aa30fb03725d362a2
-rw-r--r--ChangeLog.rst2
-rw-r--r--example/printcap.c2
-rw-r--r--include/fuse_common.h13
-rw-r--r--lib/fuse_lowlevel.c4
4 files changed, 20 insertions, 1 deletions
diff --git a/ChangeLog.rst b/ChangeLog.rst
index d176dfa..4cb1478 100644
--- a/ChangeLog.rst
+++ b/ChangeLog.rst
@@ -1,7 +1,7 @@
Unreleased Changes
==================
-* (none so far)
+* Add FUSE_CAP_CACHE_SYMLINKS: allow caching symlinks in kernel page cache.
libfuse 3.9.4 (2020-08-09)
==========================
diff --git a/example/printcap.c b/example/printcap.c
index e0eb6b6..bf058f5 100644
--- a/example/printcap.c
+++ b/example/printcap.c
@@ -77,6 +77,8 @@ static void pc_init(void *userdata,
printf("\tFUSE_CAP_PARALLEL_DIROPS\n");
if(conn->capable & FUSE_CAP_POSIX_ACL)
printf("\tFUSE_CAP_POSIX_ACL\n");
+ if(conn->capable & FUSE_CAP_CACHE_SYMLINKS)
+ printf("\tFUSE_CAP_CACHE_SYMLINKS\n");
if(conn->capable & FUSE_CAP_NO_OPENDIR_SUPPORT)
printf("\tFUSE_CAP_NO_OPENDIR_SUPPORT\n");
if(conn->capable & FUSE_CAP_EXPLICIT_INVAL_DATA)
diff --git a/include/fuse_common.h b/include/fuse_common.h
index 39937d3..f5bfb6a 100644
--- a/include/fuse_common.h
+++ b/include/fuse_common.h
@@ -347,6 +347,19 @@ struct fuse_loop_config {
#define FUSE_CAP_HANDLE_KILLPRIV (1 << 20)
/**
+ * Indicates that the kernel supports caching symlinks in its page cache.
+ *
+ * When this feature is enabled, symlink targets are saved in the page cache.
+ * You can invalidate a cached link by calling:
+ * `fuse_lowlevel_notify_inval_inode(se, ino, 0, 0);`
+ *
+ * This feature is disabled by default.
+ * If the kernel supports it (>= 4.20), you can enable this feature by
+ * setting this flag in the `want` field of the `fuse_conn_info` structure.
+ */
+#define FUSE_CAP_CACHE_SYMLINKS (1 << 23)
+
+/**
* Indicates support for zero-message opendirs. If this flag is set in
* the `capable` field of the `fuse_conn_info` structure, then the filesystem
* may return `ENOSYS` from the opendir() handler to indicate success. Further
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index 21379c1..83510b3 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -1963,6 +1963,8 @@ void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
se->conn.capable |= FUSE_CAP_POSIX_ACL;
if (arg->flags & FUSE_HANDLE_KILLPRIV)
se->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV;
+ if (arg->flags & FUSE_CACHE_SYMLINKS)
+ se->conn.capable |= FUSE_CAP_CACHE_SYMLINKS;
if (arg->flags & FUSE_NO_OPENDIR_SUPPORT)
se->conn.capable |= FUSE_CAP_NO_OPENDIR_SUPPORT;
if (arg->flags & FUSE_EXPLICIT_INVAL_DATA)
@@ -2087,6 +2089,8 @@ void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
outarg.flags |= FUSE_WRITEBACK_CACHE;
if (se->conn.want & FUSE_CAP_POSIX_ACL)
outarg.flags |= FUSE_POSIX_ACL;
+ if (se->conn.want & FUSE_CAP_CACHE_SYMLINKS)
+ outarg.flags |= FUSE_CACHE_SYMLINKS;
if (se->conn.want & FUSE_CAP_EXPLICIT_INVAL_DATA)
outarg.flags |= FUSE_EXPLICIT_INVAL_DATA;
outarg.max_readahead = se->conn.max_readahead;