From: "Darrick J. Wong" <djwong@kernel.org>
To: aalbersh@kernel.org, djwong@kernel.org
Cc: john.g.garry@oracle.com, catherine.hoang@oracle.com,
john.g.garry@oracle.com, linux-xfs@vger.kernel.org
Subject: [PATCH 6/6] xfs: allow sysadmins to specify a maximum atomic write limit at mount time
Date: Mon, 14 Jul 2025 22:17:56 -0700 [thread overview]
Message-ID: <175255652222.1830720.7476448038808234165.stgit@frogsfrogsfrogs> (raw)
In-Reply-To: <175255652087.1830720.17606543077660806130.stgit@frogsfrogsfrogs>
From: Darrick J. Wong <djwong@kernel.org>
Source kernel commit: 4528b9052731f14c1a9be16b98e33c9401e6d1bc
Introduce a mount option to allow sysadmins to specify the maximum size
of an atomic write. If the filesystem can work with the supplied value,
that becomes the new guaranteed maximum.
The value mustn't be too big for the existing filesystem geometry (max
write size, max AG/rtgroup size). We dynamically recompute the
tr_atomic_write transaction reservation based on the given block size,
check that the current log size isn't less than the new minimum log size
constraints, and set a new maximum.
The actual software atomic write max is still computed based off of
tr_atomic_ioend the same way it has for the past few commits. Note also
that xfs_calc_atomic_write_log_geometry is non-static because mkfs will
need that.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: John Garry <john.g.garry@oracle.com>
Reviewed-by: John Garry <john.g.garry@oracle.com>
---
include/platform_defs.h | 14 ++++++++++
include/xfs_trace.h | 1 +
libxfs/xfs_trans_resv.h | 4 +++
libxfs/xfs_trans_resv.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 88 insertions(+)
diff --git a/include/platform_defs.h b/include/platform_defs.h
index 9af7b4318f8917..74a00583ebd6cb 100644
--- a/include/platform_defs.h
+++ b/include/platform_defs.h
@@ -261,6 +261,20 @@ static inline bool __must_check __must_check_overflow(bool overflow)
__builtin_add_overflow(__a, __b, __d); \
}))
+/**
+ * check_mul_overflow() - Calculate multiplication with overflow checking
+ * @a: first factor
+ * @b: second factor
+ * @d: pointer to store product
+ *
+ * Returns true on wrap-around, false otherwise.
+ *
+ * *@d holds the results of the attempted multiplication, regardless of whether
+ * wrap-around occurred.
+ */
+#define check_mul_overflow(a, b, d) \
+ __must_check_overflow(__builtin_mul_overflow(a, b, d))
+
/**
* abs_diff - return absolute value of the difference between the arguments
* @a: the first argument
diff --git a/include/xfs_trace.h b/include/xfs_trace.h
index 965c109cc1941a..6bbf4007cbbbd9 100644
--- a/include/xfs_trace.h
+++ b/include/xfs_trace.h
@@ -65,6 +65,7 @@
#define trace_xfs_attr_rmtval_remove_return(...) ((void) 0)
#define trace_xfs_calc_max_atomic_write_fsblocks(...) ((void) 0)
+#define trace_xfs_calc_max_atomic_write_log_geometry(...) ((void) 0)
#define trace_xfs_log_recover_item_add_cont(a,b,c,d) ((void) 0)
#define trace_xfs_log_recover_item_add(a,b,c,d) ((void) 0)
diff --git a/libxfs/xfs_trans_resv.h b/libxfs/xfs_trans_resv.h
index a6d303b836883f..336279e0fc6137 100644
--- a/libxfs/xfs_trans_resv.h
+++ b/libxfs/xfs_trans_resv.h
@@ -122,5 +122,9 @@ unsigned int xfs_calc_write_reservation_minlogsize(struct xfs_mount *mp);
unsigned int xfs_calc_qm_dqalloc_reservation_minlogsize(struct xfs_mount *mp);
xfs_extlen_t xfs_calc_max_atomic_write_fsblocks(struct xfs_mount *mp);
+xfs_extlen_t xfs_calc_atomic_write_log_geometry(struct xfs_mount *mp,
+ xfs_extlen_t blockcount, unsigned int *new_logres);
+int xfs_calc_atomic_write_reservation(struct xfs_mount *mp,
+ xfs_extlen_t blockcount);
#endif /* __XFS_TRANS_RESV_H__ */
diff --git a/libxfs/xfs_trans_resv.c b/libxfs/xfs_trans_resv.c
index ec61ddfba44601..b3b9d22b54515d 100644
--- a/libxfs/xfs_trans_resv.c
+++ b/libxfs/xfs_trans_resv.c
@@ -1481,3 +1481,72 @@ xfs_calc_max_atomic_write_fsblocks(
return ret;
}
+
+/*
+ * Compute the log blocks and transaction reservation needed to complete an
+ * atomic write of a given number of blocks. Worst case, each block requires
+ * separate handling. A return value of 0 means something went wrong.
+ */
+xfs_extlen_t
+xfs_calc_atomic_write_log_geometry(
+ struct xfs_mount *mp,
+ xfs_extlen_t blockcount,
+ unsigned int *new_logres)
+{
+ struct xfs_trans_res *curr_res = &M_RES(mp)->tr_atomic_ioend;
+ uint old_logres = curr_res->tr_logres;
+ unsigned int per_intent, step_size;
+ unsigned int logres;
+ xfs_extlen_t min_logblocks;
+
+ ASSERT(blockcount > 0);
+
+ xfs_calc_default_atomic_ioend_reservation(mp, M_RES(mp));
+
+ per_intent = xfs_calc_atomic_write_ioend_geometry(mp, &step_size);
+
+ /* Check for overflows */
+ if (check_mul_overflow(blockcount, per_intent, &logres) ||
+ check_add_overflow(logres, step_size, &logres))
+ return 0;
+
+ curr_res->tr_logres = logres;
+ min_logblocks = xfs_log_calc_minimum_size(mp);
+ curr_res->tr_logres = old_logres;
+
+ trace_xfs_calc_max_atomic_write_log_geometry(mp, per_intent, step_size,
+ blockcount, min_logblocks, logres);
+
+ *new_logres = logres;
+ return min_logblocks;
+}
+
+/*
+ * Compute the transaction reservation needed to complete an out of place
+ * atomic write of a given number of blocks.
+ */
+int
+xfs_calc_atomic_write_reservation(
+ struct xfs_mount *mp,
+ xfs_extlen_t blockcount)
+{
+ unsigned int new_logres;
+ xfs_extlen_t min_logblocks;
+
+ /*
+ * If the caller doesn't ask for a specific atomic write size, then
+ * use the defaults.
+ */
+ if (blockcount == 0) {
+ xfs_calc_default_atomic_ioend_reservation(mp, M_RES(mp));
+ return 0;
+ }
+
+ min_logblocks = xfs_calc_atomic_write_log_geometry(mp, blockcount,
+ &new_logres);
+ if (!min_logblocks || min_logblocks > mp->m_sb.sb_logblocks)
+ return -EINVAL;
+
+ M_RES(mp)->tr_atomic_ioend.tr_logres = new_logres;
+ return 0;
+}
next prev parent reply other threads:[~2025-07-15 5:17 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-15 5:13 [PATCHBOMB v2] xfsprogs: ports and new code for 6.16 Darrick J. Wong
2025-07-15 5:15 ` [PATCHSET 1/3] xfsprogs: new libxfs code from kernel 6.16 Darrick J. Wong
2025-07-15 5:16 ` [PATCH 1/6] xfs: add helpers to compute transaction reservation for finishing intent items Darrick J. Wong
2025-07-15 5:16 ` [PATCH 2/6] xfs: allow block allocator to take an alignment hint Darrick J. Wong
2025-07-15 5:17 ` [PATCH 3/6] xfs: commit CoW-based atomic writes atomically Darrick J. Wong
2025-07-15 5:17 ` [PATCH 4/6] libxfs: add helpers to compute log item overhead Darrick J. Wong
2025-07-18 14:03 ` Andrey Albershteyn
2025-07-15 5:17 ` [PATCH 5/6] xfs: add xfs_calc_atomic_write_unit_max() Darrick J. Wong
2025-07-15 5:17 ` Darrick J. Wong [this message]
2025-07-15 5:16 ` [PATCHSET 2/3] xfsprogs: atomic writes Darrick J. Wong
2025-07-15 5:18 ` [PATCH 1/7] libfrog: move statx.h from io/ to libfrog/ Darrick J. Wong
2025-07-15 5:18 ` [PATCH 2/7] xfs_db: create an untorn_max subcommand Darrick J. Wong
2025-07-15 5:18 ` [PATCH 3/7] xfs_io: dump new atomic_write_unit_max_opt statx field Darrick J. Wong
2025-07-15 5:18 ` [PATCH 4/7] mkfs: don't complain about overly large auto-detected log stripe units Darrick J. Wong
2025-07-15 5:19 ` [PATCH 5/7] mkfs: autodetect log stripe unit for external log devices Darrick J. Wong
2025-07-15 5:19 ` [PATCH 6/7] mkfs: try to align AG size based on atomic write capabilities Darrick J. Wong
2025-07-15 5:19 ` [PATCH 7/7] mkfs: allow users to configure the desired maximum atomic write size Darrick J. Wong
2025-07-15 5:16 ` [PATCHSET 3/3] xfs_scrub: drop EXPERIMENTAL warning Darrick J. Wong
2025-07-15 5:20 ` [PATCH 1/1] xfs_scrub: remove EXPERIMENTAL warnings Darrick J. Wong
-- strict thread matches above, loose matches on Subject: below --
2025-07-01 18:04 [PATCHSET 1/3] xfsprogs: new libxfs code from kernel 6.16 Darrick J. Wong
2025-07-01 18:06 ` [PATCH 6/6] xfs: allow sysadmins to specify a maximum atomic write limit at mount time Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=175255652222.1830720.7476448038808234165.stgit@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=aalbersh@kernel.org \
--cc=catherine.hoang@oracle.com \
--cc=john.g.garry@oracle.com \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox