Stock kernels don't have FIEMAP support in fuse filesystems,
we've added the support for FIEMAP for pStorage performance.

Now if you call FIEMAP ioctl on a FUSE fs (for example mergerfs, sshfs,
mhddfs), libfuse crashes (the function fuse_lib_ioctl aborts due to
inbufsz > != outbufsz), so FIEMAP support autodetection does not work.

Let's pretend we don't provide FIEMAP for any FUSE fs except for pStorage.

https://bugs.openvz.org/browse/OVZ-7145

Signed-off-by: Konstantin Khorenko <khore...@virtuozzo.com>

v2: don't perform the check for FUSE fs every fiemap call,
do it only once on fuse mount.

---
 fs/fuse/inode.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index fc5f066d3e4d9..7c8d9350d34d6 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1439,23 +1439,33 @@ static struct dentry *fuse_mount(struct 
file_system_type *fs_type,
                       void *raw_data)
 {
        struct dentry *dentry;
+       struct fuse_conn *fc;
 
        dentry = mount_nodev(fs_type, flags, raw_data, fuse_fill_super);
+       if (IS_ERR(dentry))
+               return dentry;
+
+       fc = dentry->d_sb->s_fs_info;
 
-       /* Hack to distinguish pcs fuse service and to force synchronous close 
for it.
-        * Seems, this is the only place where we have some variable 
(dev_name), which
-        * is not confined by fuse API and already defined.
+       /* Hack to distinguish pcs fuse service and to force synchronous
+        * close for it. Seems, this is the only place where we have some
+        * variable (dev_name), which is not confined by fuse API and
+        * already defined.
+        *
+        * libfuse is not ready for fiemap autodetection, so disable fiemap
+        * support check in advance for all FUSE fs except for pStorage.
         */
-       if (!IS_ERR(dentry) && dev_name &&
-                       (strncmp(dev_name, "pstorage://", 11) == 0 ||
-                               strncmp(dev_name, "vstorage://", 11) == 0) ) {
-               struct fuse_conn *fc = dentry->d_sb->s_fs_info;
+       if (dev_name &&
+           (strncmp(dev_name, "pstorage://", 11) == 0 ||
+            strncmp(dev_name, "vstorage://", 11) == 0)) {
 
                if (!(fc->flags & FUSE_DISABLE_CLOSE_WAIT))
                        fc->close_wait = 1;
 
                fc->compat_inval_files = 1;
-       }
+       } else
+               fc->no_fiemap = 1;
+
        return dentry;
 }
 
-- 
2.15.1

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to