libfuse: highlevel API: fix directory file handle passed to ioctl() method
authorMiklos Szeredi <mszeredi@suse.cz>
Mon, 21 Jul 2014 16:53:04 +0000 (18:53 +0200)
committerMiklos Szeredi <mszeredi@suse.cz>
Mon, 21 Jul 2014 16:59:23 +0000 (18:59 +0200)
Reported by Eric Biggers

ChangeLog
include/fuse.h
lib/fuse.c

index f4657a033f0b6e4fb7f7d49a8481fa0b1bf886ab..da3b11a28908578bda89321348d68939a380aafc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-07-21  Miklos Szeredi <miklos@szeredi.hu>
+
+       * libfuse: highlevel API: fix directory file handle passed to
+       ioctl() method.  Reported by Eric Biggers
+
 2014-07-15  Miklos Szeredi <miklos@szeredi.hu>
 
        * fusermount, libfuse: send value as unsigned in "user_id=" and
index c657e676438e4111d79650f170ee5873c4bbfb57..911a676c5316e79133e4a7f173b2d7a32d3fc00f 100644 (file)
@@ -500,6 +500,9 @@ struct fuse_operations {
         * _IOC_READ in area and if both are set in/out area.  In all
         * non-NULL cases, the area is of _IOC_SIZE(cmd) bytes.
         *
+        * If flags has FUSE_IOCTL_DIR then the fuse_file_info refers to a
+        * directory file handle.
+        *
         * Introduced in version 2.8
         */
        int (*ioctl) (const char *, int cmd, void *arg,
index cfac238807a31f80abd85c97aa6b455ed9700610..7ba654a39c6a8515fd7abb26e4d90efd0e697df8 100644 (file)
@@ -3998,12 +3998,13 @@ static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
 }
 
 static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
-                          struct fuse_file_info *fi, unsigned int flags,
+                          struct fuse_file_info *llfi, unsigned int flags,
                           const void *in_buf, size_t in_bufsz,
                           size_t out_bufsz)
 {
        struct fuse *f = req_fuse_prepare(req);
        struct fuse_intr_data d;
+       struct fuse_file_info fi;
        char *path, *out_buf = NULL;
        int err;
 
@@ -4011,6 +4012,11 @@ static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
        if (flags & FUSE_IOCTL_UNRESTRICTED)
                goto err;
 
+       if (flags & FUSE_IOCTL_DIR)
+               get_dirhandle(llfi, &fi);
+       else
+               fi = *llfi;
+
        if (out_bufsz) {
                err = -ENOMEM;
                out_buf = malloc(out_bufsz);
@@ -4028,7 +4034,7 @@ static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
 
        fuse_prepare_interrupt(f, req, &d);
 
-       err = fuse_fs_ioctl(f->fs, path, cmd, arg, fi, flags,
+       err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags,
                            out_buf ?: (void *)in_buf);
 
        fuse_finish_interrupt(f, req, &d);