From e3f95263a703d45f091dcf9655806978d2577797 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 5 Dec 2011 15:21:28 +0100 Subject: [PATCH] Add support for ioctl on directories Reported by Antonio SJ Musumeci --- ChangeLog | 3 +++ include/fuse_common.h | 4 ++++ include/fuse_kernel.h | 7 ++++++- lib/fuse_lowlevel.c | 8 ++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 64efa5f..6269954 100644 --- 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 * Reply to request with ENOMEM in case of failure to allocate diff --git a/include/fuse_common.h b/include/fuse_common.h index 76f7200..a4d980d 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -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 diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h index 8b65f46..eb8c790 100644 --- a/include/fuse_kernel.h +++ b/include/fuse_kernel.h @@ -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 @@ -112,7 +115,7 @@ #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 diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 885522f..8012d49 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -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; -- 2.30.2