From: cem@kernel.org
To: linux-xfs@vger.kernel.org
Subject: [RFC PATCH] xfs: Fix logbsize validation
Date: Tue, 12 Aug 2025 14:43:41 +0200 [thread overview]
Message-ID: <20250812124350.849381-1-cem@kernel.org> (raw)
From: Carlos Maiolino <cem@kernel.org>
An user reported an inconsistency while mounting a V2 log filesystem
with logbsize equals to the stripe unit being used (192k).
The current validation algorithm for the log buffer size enforces the
user to pass a power_of_2 value between [16k-256k].
The manpage dictates the log buffer size must be a multiple of the log
stripe unit, but doesn't specify it must be a power_of_2. Also, if
logbsize is not specified at mount time, it will be set to
max(32768, log_sunit), where log_sunit not necessarily is a power_of_2.
It does seem to me then that logbsize being a power_of_2 constraint must
be relaxed if there is a configured log stripe unit, so this patch
updates the logbsize validation logic to ensure that:
- It can only be set to a specific range [16k-256k]
- Will be aligned to log stripe unit when the latter is set,
and will be at least the same size as the log stripe unit.
- Enforce it to be power_of_2 aligned when log stripe unit is not set.
This is achieved by factoring out the logbsize validation to a separated
function to avoid a big chain of if conditionals
While at it, update m_logbufs and m_logbsize conditionals in
xfs_fs_validate_params from:
(x != -1 && x != 0) to (x > 0)
Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
---
I am sending this as a RFC because although I did some basic testing,
xfstests is still running, so I can't tell yet if it will fail on some configuration even though I am not expecting it to.
fs/xfs/xfs_super.c | 57 ++++++++++++++++++++++++++++++++--------------
1 file changed, 40 insertions(+), 17 deletions(-)
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index bb0a82635a77..38d3d8a0b026 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1059,6 +1059,29 @@ xfs_fs_unfreeze(
return 0;
}
+STATIC int
+xfs_validate_logbsize(
+ struct xfs_mount *mp)
+{
+ int logbsize = mp->m_logbsize;
+ uint32_t logsunit = mp->m_sb.sb_logsunit;
+
+ if (logsunit > 1) {
+ if (logbsize < logsunit ||
+ logbsize % logsunit) {
+ xfs_warn(mp,
+ "logbuf size must be a multiple of the log stripe unit");
+ return -EINVAL;
+ }
+ } else {
+ if (!is_power_of_2(logbsize)) {
+ xfs_warn(mp,
+ "invalid logbufsize: %d [not a power of 2]", logbsize);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
/*
* This function fills in xfs_mount_t fields based on mount args.
* Note: the superblock _has_ now been read in.
@@ -1067,16 +1090,13 @@ STATIC int
xfs_finish_flags(
struct xfs_mount *mp)
{
- /* Fail a mount where the logbuf is smaller than the log stripe */
if (xfs_has_logv2(mp)) {
- if (mp->m_logbsize <= 0 &&
- mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE) {
- mp->m_logbsize = mp->m_sb.sb_logsunit;
- } else if (mp->m_logbsize > 0 &&
- mp->m_logbsize < mp->m_sb.sb_logsunit) {
- xfs_warn(mp,
- "logbuf size must be greater than or equal to log stripe size");
- return -EINVAL;
+ if (mp->m_logbsize > 0) {
+ if (xfs_validate_logbsize(mp))
+ return -EINVAL;
+ } else {
+ if (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)
+ mp->m_logbsize = mp->m_sb.sb_logsunit;
}
} else {
/* Fail a mount if the logbuf is larger than 32K */
@@ -1628,8 +1648,7 @@ xfs_fs_validate_params(
return -EINVAL;
}
- if (mp->m_logbufs != -1 &&
- mp->m_logbufs != 0 &&
+ if (mp->m_logbufs > 0 &&
(mp->m_logbufs < XLOG_MIN_ICLOGS ||
mp->m_logbufs > XLOG_MAX_ICLOGS)) {
xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]",
@@ -1637,14 +1656,18 @@ xfs_fs_validate_params(
return -EINVAL;
}
- if (mp->m_logbsize != -1 &&
- mp->m_logbsize != 0 &&
+ /*
+ * We have not yet read the superblock, so we can't check against
+ * logsunit here.
+ */
+ if (mp->m_logbsize > 0 &&
(mp->m_logbsize < XLOG_MIN_RECORD_BSIZE ||
- mp->m_logbsize > XLOG_MAX_RECORD_BSIZE ||
- !is_power_of_2(mp->m_logbsize))) {
+ mp->m_logbsize > XLOG_MAX_RECORD_BSIZE)) {
xfs_warn(mp,
- "invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
- mp->m_logbsize);
+ "invalid logbufsize: %d [not in range %dk-%dk]",
+ mp->m_logbsize,
+ (XLOG_MIN_RECORD_BSIZE/1024),
+ (XLOG_MAX_RECORD_BSIZE/1024));
return -EINVAL;
}
--
2.50.1
next reply other threads:[~2025-08-12 12:44 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-12 12:43 cem [this message]
2025-08-13 2:16 ` [RFC PATCH] xfs: Fix logbsize validation Darrick J. Wong
2025-08-13 7:55 ` Carlos Maiolino
2025-08-13 17:58 ` Carlos Maiolino
2025-08-13 22:23 ` Dave Chinner
2025-08-18 11:42 ` Carlos Maiolino
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=20250812124350.849381-1-cem@kernel.org \
--to=cem@kernel.org \
--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;
as well as URLs for NNTP newsgroup(s).