Add support for ioctl on directories
authorMiklos Szeredi <mszeredi@suse.cz>
Mon, 5 Dec 2011 14:21:28 +0000 (15:21 +0100)
committerMiklos Szeredi <mszeredi@suse.cz>
Mon, 5 Dec 2011 14:21:28 +0000 (15:21 +0100)
Reported by Antonio SJ Musumeci

ChangeLog
include/fuse_common.h
include/fuse_kernel.h
lib/fuse_lowlevel.c

index 64efa5f947c1a8e8e4ecf283ce5b2ca0ae15f1b1..62699544674fc43ba4ff05595341b333eeb39abf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,9 @@
        * Low level API: lock argument of fuse_reply_lock should have a
        'const' qualifier.  Reported by Shachar Sharon
 
+       * Add support for ioctl on directories.  Reported by Antonio SJ
+       Musumeci
+
 2011-10-13  Miklos Szeredi <miklos@szeredi.hu>
 
        * Reply to request with ENOMEM in case of failure to allocate
index 76f72001b51a3673be37e058a3c134c0196e1b1c..a4d980d5a1ac40707daee440cd969fecdab5962a 100644 (file)
@@ -99,6 +99,7 @@ struct fuse_file_info {
  * FUSE_CAP_SPLICE_WRITE: ability to use splice() to write to the fuse device
  * FUSE_CAP_SPLICE_MOVE: ability to move data to the fuse device with splice()
  * FUSE_CAP_SPLICE_READ: ability to use splice() to read from the fuse device
+ * FUSE_CAP_IOCTL_DIR: ioctl support on directories
  */
 #define FUSE_CAP_ASYNC_READ    (1 << 0)
 #define FUSE_CAP_POSIX_LOCKS   (1 << 1)
@@ -110,6 +111,7 @@ struct fuse_file_info {
 #define FUSE_CAP_SPLICE_MOVE   (1 << 8)
 #define FUSE_CAP_SPLICE_READ   (1 << 9)
 #define FUSE_CAP_FLOCK_LOCKS   (1 << 10)
+#define FUSE_CAP_IOCTL_DIR     (1 << 11)
 
 /**
  * Ioctl flags
@@ -117,12 +119,14 @@ struct fuse_file_info {
  * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
  * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
  * FUSE_IOCTL_RETRY: retry with new iovecs
+ * FUSE_IOCTL_DIR: is a directory
  *
  * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
  */
 #define FUSE_IOCTL_COMPAT      (1 << 0)
 #define FUSE_IOCTL_UNRESTRICTED        (1 << 1)
 #define FUSE_IOCTL_RETRY       (1 << 2)
+#define FUSE_IOCTL_DIR         (1 << 4)
 
 #define FUSE_IOCTL_MAX_IOV     256
 
index 8b65f46776488db62552a03ab7cf83c5830f803d..eb8c790b57a31047ab4b46b8d312d5970b7f909b 100644 (file)
@@ -76,6 +76,9 @@
  *
  * 7.17
  *  - add FUSE_FLOCK_LOCKS and FUSE_RELEASE_FLOCK_UNLOCK
+ *
+ * 7.18
+ *  - add FUSE_IOCTL_DIR flag
  */
 
 #ifndef _LINUX_FUSE_H
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 17
+#define FUSE_KERNEL_MINOR_VERSION 18
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -245,6 +248,7 @@ struct fuse_file_lock {
  * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
  * FUSE_IOCTL_RETRY: retry with new iovecs
  * FUSE_IOCTL_32BIT: 32bit ioctl
+ * FUSE_IOCTL_DIR: is a directory
  *
  * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
  */
@@ -252,6 +256,7 @@ struct fuse_file_lock {
 #define FUSE_IOCTL_UNRESTRICTED        (1 << 1)
 #define FUSE_IOCTL_RETRY       (1 << 2)
 #define FUSE_IOCTL_32BIT       (1 << 3)
+#define FUSE_IOCTL_DIR         (1 << 4)
 
 #define FUSE_IOCTL_MAX_IOV     256
 
index 885522ff606cf9c9107fc21543b13a640369f4fe..8012d49f0c7dc70bd8885537b6e6014b7029027a 100644 (file)
@@ -1647,6 +1647,12 @@ static void do_ioctl(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
        void *in_buf = arg->in_size ? PARAM(arg) : NULL;
        struct fuse_file_info fi;
 
+       if (flags & FUSE_IOCTL_DIR &&
+           !(req->f->conn.want & FUSE_CAP_IOCTL_DIR)) {
+               fuse_reply_err(req, ENOTTY);
+               return;
+       }
+
        memset(&fi, 0, sizeof(fi));
        fi.fh = arg->fh;
        fi.fh_old = fi.fh;
@@ -1774,6 +1780,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
                        f->conn.want |= FUSE_CAP_SPLICE_READ;
 #endif
        }
+       if (req->f->conn.proto_minor >= 18)
+               f->conn.capable |= FUSE_CAP_IOCTL_DIR;
 
        if (f->atomic_o_trunc)
                f->conn.want |= FUSE_CAP_ATOMIC_O_TRUNC;