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

Konstantin Khorenko khorenko at virtuozzo.com
Tue Feb 1 19:13:26 MSK 2022


The commit is pushed to "branch-rh9-5.14.0-4.vz9.12.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh9-5.14.0-4.vz9.12.4
------>
commit 9edb923addbb573fbbe0aba1f71c617da9e55416
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date:   Tue Feb 1 19:13:26 2022 +0300

    fs: Use standard fiemap behavior for all filesystems except FUSE
    
    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: 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 87a3834fcd32..cdae748e4720 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 de73720874b8..b13f18b4448c 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 cd71b108ee24..f2a0f448b571 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