aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Austin <chad@chadaustin.me>2019-04-16 11:44:59 -0700
committerNikolaus Rath <Nikolaus@rath.org>2019-04-16 19:44:59 +0100
commit6439231f9ba8af9c0eab8dcda54a8fc31e63ae99 (patch)
tree2ba872c19ceab7e7e59977df21db2c9246f803f3
parent7bf25b6987d84c816aebd5325b95cfa0d311b1e6 (diff)
downloadlibfuse-6439231f9ba8af9c0eab8dcda54a8fc31e63ae99.tar.gz
Add documentation for opting out of opendir and releasedir (#391)
-rw-r--r--ChangeLog.rst1
-rw-r--r--example/printcap.c2
-rw-r--r--include/fuse_common.h12
-rw-r--r--include/fuse_lowlevel.h7
-rw-r--r--lib/fuse_lowlevel.c2
5 files changed, 24 insertions, 0 deletions
diff --git a/ChangeLog.rst b/ChangeLog.rst
index d1bbbec..a32d9ec 100644
--- a/ChangeLog.rst
+++ b/ChangeLog.rst
@@ -8,6 +8,7 @@ libfuse 3.5.0 (UNRELEASED)
on mountpoints within SMB 2.0 filesystems).
* Added a new `cache_readdir` flag to `fuse_file_info` to enable
caching of readdir results. Supported by kernels 4.20 and newer.
+* Add support and documentation for FUSE_CAP_NO_OPENDIR_SUPPORT.
libfuse 3.4.2 (2019-03-09)
==========================
diff --git a/example/printcap.c b/example/printcap.c
index 77dea14..580f52c 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_NO_OPENDIR_SUPPORT)
+ printf("\tFUSE_CAP_NO_OPENDIR_SUPPORT\n");
fuse_session_exit(se);
}
diff --git a/include/fuse_common.h b/include/fuse_common.h
index 823a37d..0481aac 100644
--- a/include/fuse_common.h
+++ b/include/fuse_common.h
@@ -336,6 +336,18 @@ struct fuse_loop_config {
#define FUSE_CAP_HANDLE_KILLPRIV (1 << 20)
/**
+ * 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
+ * opendir and releasedir messages will be handled in the kernel. (If this
+ * flag is not set, returning ENOSYS will be treated as an error and signalled
+ * to the caller.)
+ *
+ * Setting (or unsetting) this flag in the `want` field has *no effect*.
+ */
+#define FUSE_CAP_NO_OPENDIR_SUPPORT (1 << 24)
+
+/**
* Ioctl flags
*
* FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
index 87c362a..b7afe16 100644
--- a/include/fuse_lowlevel.h
+++ b/include/fuse_lowlevel.h
@@ -665,6 +665,13 @@ struct fuse_lowlevel_ops {
* etc) in fi->fh, and use this in other all other directory
* stream operations (readdir, releasedir, fsyncdir).
*
+ * If this request is answered with an error code of ENOSYS and
+ * FUSE_CAP_NO_OPENDIR_SUPPORT is set in `fuse_conn_info.capable`,
+ * this is treated as success and future calls to opendir and
+ * releasedir will also succeed without being sent to the filesystem
+ * process. In addition, the kernel will cache readdir results
+ * as if opendir returned FOPEN_KEEP_CACHE | FOPEN_CACHE_DIR.
+ *
* Valid replies:
* fuse_reply_open
* fuse_reply_err
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index 50fff4d..ec0daaf 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -1907,6 +1907,8 @@ static 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_NO_OPENDIR_SUPPORT)
+ se->conn.capable |= FUSE_CAP_NO_OPENDIR_SUPPORT;
} else {
se->conn.max_readahead = 0;
}