hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I9VTE3 CVE: NA
--------------------------------
Add mount option "atomicalways", If the file support atomic write, while the user initiates a direct I/O write, convert the write to atomic write, it makes database like Mysql could use atomic write without any other more modify. This also causes some direct writes (such as offset misalignment and invalid length) to the files which with atomic write enabled to return fails.
Signed-off-by: Long Li leo.lilong@huawei.com --- fs/xfs/xfs_file.c | 4 ++++ fs/xfs/xfs_mount.h | 2 ++ fs/xfs/xfs_super.c | 6 +++++- 3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 49db1611de96..75928200d7e9 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -814,6 +814,10 @@ xfs_file_write_iter( return xfs_file_dax_write(iocb, from);
if (iocb->ki_flags & IOCB_DIRECT) { + + if (xfs_inode_atomicwrites(ip) && + xfs_has_atomicalways(ip->i_mount)) + iocb->ki_flags |= IOCB_ATOMIC; /* * Allow a directio write to fall back to a buffered * write *only* in the case that we're doing a reflink diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 888d6bf9bea7..6b952ff031b6 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -279,6 +279,7 @@ typedef struct xfs_mount {
/* Mount features */ +#define XFS_FEAT_ATOMICALWAYS (1ULL << 47) /* convert dio to atomic writes always */ #define XFS_FEAT_NOATTR2 (1ULL << 48) /* disable attr2 creation */ #define XFS_FEAT_NOALIGN (1ULL << 49) /* ignore alignment */ #define XFS_FEAT_ALLOCSIZE (1ULL << 50) /* user specified allocation size */ @@ -365,6 +366,7 @@ __XFS_HAS_FEAT(dax_always, DAX_ALWAYS) __XFS_HAS_FEAT(dax_never, DAX_NEVER) __XFS_HAS_FEAT(norecovery, NORECOVERY) __XFS_HAS_FEAT(nouuid, NOUUID) +__XFS_HAS_FEAT(atomicalways, ATOMICALWAYS)
/* * Operational mount state flags diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index d43f76a4b99a..0359713fefd8 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -116,7 +116,7 @@ enum { Opt_filestreams, Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_uquota, Opt_gquota, Opt_pquota, Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce, - Opt_discard, Opt_nodiscard, Opt_dax, Opt_dax_enum, + Opt_discard, Opt_nodiscard, Opt_dax, Opt_dax_enum, Opt_atomicalways, };
static const struct fs_parameter_spec xfs_fs_parameters[] = { @@ -161,6 +161,7 @@ static const struct fs_parameter_spec xfs_fs_parameters[] = { fsparam_flag("nodiscard", Opt_nodiscard), fsparam_flag("dax", Opt_dax), fsparam_enum("dax", Opt_dax_enum, dax_param_enums), + fsparam_flag("atomicalways", Opt_atomicalways), {} };
@@ -1361,6 +1362,9 @@ xfs_fc_parse_param( xfs_fs_warn_deprecated(fc, param, XFS_FEAT_NOATTR2, true); parsing_mp->m_features |= XFS_FEAT_NOATTR2; return 0; + case Opt_atomicalways: + parsing_mp->m_features |= XFS_FEAT_ATOMICALWAYS; + return 0; default: xfs_warn(parsing_mp, "unknown mount option [%s].", param->key); return -EINVAL;