xfsprogs/0054-mkfs-Add-atomic-writes-suppport.patch
zhangjian f908c320a1 support atomic write
(cherry picked from commit 40226fa996b6e2d02ded47834cf5289a5f7160e6)
2024-06-19 11:40:47 +08:00

194 lines
5.8 KiB
Diff

From c85d383b0bb1d86c676ccf817dd22ad43b589b61 Mon Sep 17 00:00:00 2001
From: John Garry <john.g.garry@oracle.com>
Date: Fri, 1 Mar 2024 17:40:12 +0000
Subject: [PATCH 08/11] mkfs: Add atomic writes suppport
Use a command like the following to enable:
/mkfs.xfs -f -i forcealign=1 -d extsize=4096 -d atomic-writes=1 /dev/sda
Forcealign enablement is required, and with that a specific extent size
needs to be set. And extent size of 4096B (for 4K FS block size) is
acceptable.
Signed-off-by: John Garry <john.g.garry@oracle.com>
---
include/linux.h | 4 ++++
libxfs/xfs_format.h | 8 ++++++--
mkfs/xfs_mkfs.c | 49 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/include/linux.h b/include/linux.h
index d95365b..7f295f0 100644
--- a/include/linux.h
+++ b/include/linux.h
@@ -251,6 +251,10 @@ struct fsxattr {
#define FS_XFLAG_FORCEALIGN 0x00020000
#endif
+#ifndef FS_XFLAG_ATOMICWRITES
+#define FS_XFLAG_ATOMICWRITES 0x00040000
+#endif
+
#ifdef HAVE_GETFSMAP
# include <linux/fsmap.h>
#else
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index c2db380..1dfb11c 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -451,12 +451,14 @@ xfs_sb_has_compat_feature(
#define XFS_SB_FEAT_RO_COMPAT_REFLINK (1 << 2) /* reflinked files */
#define XFS_SB_FEAT_RO_COMPAT_INOBTCNT (1 << 3) /* inobt block counts */
#define XFS_SB_FEAT_RO_COMPAT_FORCEALIGN (1 << 30) /* aligned file data extents */
+#define XFS_SB_FEAT_RO_COMPAT_ATOMICWRITES (1 << 31) /* aligned file data extents */
#define XFS_SB_FEAT_RO_COMPAT_ALL \
(XFS_SB_FEAT_RO_COMPAT_FINOBT | \
XFS_SB_FEAT_RO_COMPAT_RMAPBT | \
XFS_SB_FEAT_RO_COMPAT_REFLINK| \
XFS_SB_FEAT_RO_COMPAT_FORCEALIGN| \
- XFS_SB_FEAT_RO_COMPAT_INOBTCNT)
+ XFS_SB_FEAT_RO_COMPAT_INOBTCNT| \
+ XFS_SB_FEAT_RO_COMPAT_ATOMICWRITES)
#define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL
static inline bool
xfs_sb_has_ro_compat_feature(
@@ -1180,16 +1182,18 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
#define XFS_DIFLAG2_BIGTIME_BIT 3 /* big timestamps */
/* data extent mappings for regular files must be aligned to extent size hint */
#define XFS_DIFLAG2_FORCEALIGN_BIT 5
+#define XFS_DIFLAG2_ATOMICWRITES_BIT 6
#define XFS_DIFLAG2_DAX (1 << XFS_DIFLAG2_DAX_BIT)
#define XFS_DIFLAG2_REFLINK (1 << XFS_DIFLAG2_REFLINK_BIT)
#define XFS_DIFLAG2_COWEXTSIZE (1 << XFS_DIFLAG2_COWEXTSIZE_BIT)
#define XFS_DIFLAG2_BIGTIME (1 << XFS_DIFLAG2_BIGTIME_BIT)
#define XFS_DIFLAG2_FORCEALIGN (1 << XFS_DIFLAG2_FORCEALIGN_BIT)
+#define XFS_DIFLAG2_ATOMICWRITES (1 << XFS_DIFLAG2_ATOMICWRITES_BIT)
#define XFS_DIFLAG2_ANY \
(XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE | \
- XFS_DIFLAG2_BIGTIME | XFS_DIFLAG2_FORCEALIGN)
+ XFS_DIFLAG2_BIGTIME | XFS_DIFLAG2_FORCEALIGN | XFS_DIFLAG2_ATOMICWRITES)
static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
{
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 1253ece..5169255 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -70,6 +70,7 @@ enum {
D_EXTSZINHERIT,
D_COWEXTSIZE,
D_DAXINHERIT,
+ D_ATOMICWRITES,
D_MAX_OPTS,
};
@@ -306,6 +307,7 @@ static struct opt_params dopts = {
[D_EXTSZINHERIT] = "extszinherit",
[D_COWEXTSIZE] = "cowextsize",
[D_DAXINHERIT] = "daxinherit",
+ [D_ATOMICWRITES] = "atomic-writes",
[D_MAX_OPTS] = NULL,
},
.subopt_params = {
@@ -437,6 +439,12 @@ static struct opt_params dopts = {
.maxval = 1,
.defaultval = 1,
},
+ { .index = D_ATOMICWRITES,
+ .conflicts = { { NULL, LAST_CONFLICT } },
+ .minval = 0,
+ .maxval = 1,
+ .defaultval = 1,
+ },
},
};
@@ -838,6 +846,7 @@ struct sb_feat_args {
bool nodalign;
bool nortalign;
bool forcealign; /* XFS_SB_FEAT_RO_COMPAT_FORCEALIGN */
+ bool atomicwrites; /* XFS_SB_FEAT_RO_COMPAT_ATOMICWRITES */
};
struct cli_params {
@@ -1598,6 +1607,13 @@ data_opts_parser(
else
cli->fsx.fsx_xflags &= ~FS_XFLAG_DAX;
break;
+ case D_ATOMICWRITES:
+ if (getnum(value, opts, subopt) == 1) {
+ cli->sb_feat.atomicwrites = true;
+ } else {
+ cli->sb_feat.atomicwrites = false;
+ }
+ break;
default:
return -EINVAL;
}
@@ -2557,6 +2573,12 @@ validate_forcealign(
if (!(cli->fsx.fsx_xflags & FS_XFLAG_FORCEALIGN))
return;
+ if (cli->fsx.fsx_xflags & (FS_XFLAG_REALTIME | FS_XFLAG_RTINHERIT)) {
+ fprintf(stderr,
+_("cannot set forcealign and realtime flags.\n"));
+ usage();
+ }
+
if (cli->fsx.fsx_cowextsize != 0) {
fprintf(stderr,
_("cannot set CoW extent size hint when forcealign is set.\n"));
@@ -2576,6 +2598,30 @@ _("cannot set forcealign and realtime flags.\n"));
}
}
+/* Validate the incoming forcealign flag. */
+static void
+validate_atomicwrites(
+ struct mkfs_params *cfg,
+ struct xfs_mount *mp,
+ struct cli_params *cli,
+ char *dfile
+ )
+{
+ if (!cli->sb_feat.atomicwrites)
+ return;
+
+ if (!(cli->fsx.fsx_xflags & FS_XFLAG_FORCEALIGN)) {
+ fprintf(stderr,
+_("cannot set atomicwrites without forcealign.\n"));
+ usage();
+ }
+
+ /*
+ * TODO: Add a check to see if the dfile can support atomic writes of
+ * extsize.
+ */
+}
+
/*
* Validate the configured stripe geometry, or is none is specified, pull
* the configuration from the underlying device.
@@ -3321,6 +3367,8 @@ sb_set_features(
sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
if (fp->forcealign)
sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_FORCEALIGN;
+ if (fp->atomicwrites)
+ sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_ATOMICWRITES;
if (fp->bigtime)
sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_BIGTIME;
@@ -4307,6 +4355,7 @@ main(
validate_extsize_hint(mp, &cli);
validate_cowextsize_hint(mp, &cli);
validate_forcealign(mp, &cli);
+ validate_atomicwrites(&cfg, mp, &cli, dfile);
/* Print the intended geometry of the fs. */
if (!quiet || dry_run) {
--
2.33.0