[rh7,v2] fuse: don't declare FUSE FIEMAP support for any FUSE fs

Submitted by Konstantin Khorenko on Dec. 13, 2019, 11:23 a.m.

Details

Message ID 20191213112307.27202-1-khorenko@virtuozzo.com
State New
Series "fuse: don't declare FUSE FIEMAP support for generic FUSE fs"
Headers show

Commit Message

Konstantin Khorenko Dec. 13, 2019, 11:23 a.m.
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 <khorenko@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(-)

Patch hide | download patch | download mbox

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;
 }
 

Comments

Kirill Tkhai Dec. 13, 2019, 11:27 a.m.
On 13.12.2019 14:23, Konstantin Khorenko wrote:
> 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 <khorenko@virtuozzo.com>

Acked-by: Kirill Tkhai <ktkhai@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;
>  }