Add documentation for opting out of opendir and releasedir (#391)
authorChad Austin <chad@chadaustin.me>
Tue, 16 Apr 2019 18:44:59 +0000 (11:44 -0700)
committerNikolaus Rath <Nikolaus@rath.org>
Tue, 16 Apr 2019 18:44:59 +0000 (19:44 +0100)
ChangeLog.rst
example/printcap.c
include/fuse_common.h
include/fuse_lowlevel.h
lib/fuse_lowlevel.c

index d1bbbec4407737607e54a5d48df5a53863b6f284..a32d9ec589689c1e34827a54c5204d23e9b5f36f 100644 (file)
@@ -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)
 ==========================
index 77dea1468d8d0c65e721a0ddd28babf320a29e98..580f52ca73e585362755693800f3190ce37e73f3 100644 (file)
@@ -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);
 }
 
index 823a37db50ac2f612d5cbe20305f3530ea9e2672..0481aac4a5f8cc733955e455deceae4958d88b8c 100644 (file)
@@ -335,6 +335,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
  *
index 87c362ac569d98d5a6bc0b8952c3cd68f0672a2e..b7afe16803d08c9ff791f8ebacfe07c460f14d82 100644 (file)
@@ -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
index 50fff4d1e1ff0474e05bad248ae36493638a0466..ec0daaf8ea0694b0bab50c332a654242668e7de9 100644 (file)
@@ -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;
        }