[Devel] [PATCH RH9] fs: Use standard fiemap behavior for all filesystems except FUSE

Kirill Tkhai ktkhai at virtuozzo.com
Mon Jan 31 16:38:52 MSK 2022


Fiemap with FIEMAP_FLAG_SYNC expects all file is sync, while we want
to avoid this for vstorage, since it's expensive.
This fixes xfstests generic/223 for ext4: it expects that
ioctl(file1, FS_IOC_FIEMAP, [fm_start=0, fm_length=1, fm_flags=FIEMAP_FLAG_SYNC))
syncs all the file despite fm_length=1.

To merge with 52c4c2fd083d0
"fs: FIEMAP should sync only required range with FIEMAP_FLAG_SYNC"
https://jira.sw.ru/browse/PSBM-137869
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 fs/fuse/inode.c    |    2 +-
 fs/ioctl.c         |   11 ++++++++---
 include/linux/fs.h |    1 +
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 87a3834fcd326..cdae748e47208 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1958,7 +1958,7 @@ static void fuse_kill_sb_anon(struct super_block *sb)
 static struct file_system_type fuse_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "fuse",
-	.fs_flags	= FS_HAS_SUBTYPE | FS_USERNS_MOUNT | FS_VIRTUALIZED,
+	.fs_flags	= FS_HAS_SUBTYPE | FS_USERNS_MOUNT | FS_VIRTUALIZED | FS_FIEMAP_RELAXED_FSYNC,
 	.init_fs_context = fuse_init_fs_context,
 	.parameters	= fuse_fs_parameters,
 	.kill_sb	= fuse_kill_sb_anon,
diff --git a/fs/ioctl.c b/fs/ioctl.c
index de73720874b83..b13f18b4448c7 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -190,9 +190,14 @@ int fiemap_prep(struct inode *inode, struct fiemap_extent_info *fieinfo,
 		return -EBADR;
 	}
 
-	if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
-		ret = filemap_write_and_wait_range(inode->i_mapping,
-			start, start + *len - 1);
+	if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC) {
+		/* Complete sync is expensive for vstorage */
+		if (inode->i_sb->s_type->fs_flags & FS_FIEMAP_RELAXED_FSYNC)
+			ret = filemap_write_and_wait_range(inode->i_mapping,
+						   start, start + *len - 1);
+		else
+			ret = filemap_write_and_wait(inode->i_mapping);
+	}
 	return ret;
 }
 EXPORT_SYMBOL(fiemap_prep);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index cd71b108ee24e..f2a0f448b5716 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2488,6 +2488,7 @@ struct file_system_type {
 #define FS_VIRTUALIZED		64	/* Can mount this fstype inside ve */
 #define FS_VE_MOUNT		128	/* Can be mounted in VE init userns */
 #define FS_RENAME_DOES_D_MOVE	32768	/* FS will handle d_move() during rename() internally. */
+#define FS_FIEMAP_RELAXED_FSYNC	65536	/* FIEMAP_FLAG_SYNC syncs only requested area */
 	int (*init_fs_context)(struct fs_context *);
 	const struct fs_parameter_spec *parameters;
 	struct dentry *(*mount) (struct file_system_type *, int,




More information about the Devel mailing list