Linux RAID subsystem development
 help / color / mirror / Atom feed
From: Jack Wang <jinpu.wang@ionos.com>
To: Song Liu <song@kernel.org>, Yu Kuai <yukuai@fygo.io>
Cc: Li Nan <magiclinan@didiglobal.com>, Xiao Ni <xiao@kernel.org>,
	linux-raid@vger.kernel.org, linux-kernel@vger.kernel.org,
	Jack Wang <jinpu.wang@cloud.ionos.com>,
	Florian-Ewald Mueller <florian-ewald.mueller@ionos.com>
Subject: [PATCH] md: allow growing logical_block_size on a running array
Date: Wed, 14 Oct 2026 13:48:23 +0200	[thread overview]
Message-ID: <20261014114830.615589-1-jinpu.wang@ionos.com> (raw)

From: Jack Wang <jinpu.wang@cloud.ionos.com>

Growing logical_block_size on a running array required stopping it
first. Handle it directly in lbs_store(), similar to
mddev_set_closing_and_sync_blockdev(): under open_mutex, refuse with
-EBUSY if the array is closing or has openers, otherwise apply the
bigger LBS.

mddev_lock() is not taken on this path, to avoid holding reconfig_mutex
while blocking on the queue limits lock.

md_release() drops openers without open_mutex, so a bio of a just-closed
opener may not yet be accounted in active_io. Commit the limits with
queue_limits_commit_update_frozen() to drain it. Also take open_mutex
around the existing "enable LBS" branch so it cannot race with the grow
path on mddev->logical_block_size.

Suggested-by: Florian-Ewald Mueller <florian-ewald.mueller@ionos.com>
Signed-off-by: Jack Wang <jinpu.wang@cloud.ionos.com>
---
 drivers/md/md.c | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 03e35386a802..cd9c73f46786 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -6013,12 +6013,12 @@ static int mddev_set_logical_block_size(struct mddev *mddev,
 	lim.logical_block_size = lbs;
 	pr_info("%s: logical_block_size is changed, data may be lost\n",
 		mdname(mddev));
-	err = queue_limits_commit_update(mddev->gendisk->queue, &lim);
+	err = queue_limits_commit_update_frozen(mddev->gendisk->queue, &lim);
 	if (err)
 		return err;
 
 	mddev->logical_block_size = lbs;
-	/* New lbs will be written to superblock after array is running */
+	/* New lbs will be written to superblock on the next update */
 	set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
 	return 0;
 }
@@ -6046,8 +6046,36 @@ lbs_store(struct mddev *mddev, const char *buf, size_t len)
 	if (mddev->pers) {
 		unsigned int curr_lbs;
 
-		if (mddev->logical_block_size)
+		/*
+		 * open_mutex serialises both paths below on
+		 * mddev->logical_block_size and keeps new openers out.
+		 * MD_CLOSING means a stop is under way. mddev_lock() is not
+		 * taken, to avoid holding reconfig_mutex while blocking on
+		 * the queue limits lock.
+		 */
+		mutex_lock(&mddev->open_mutex);
+		curr_lbs = queue_logical_block_size(mddev->gendisk->queue);
+		if (lbs > curr_lbs) {
+			/*
+			 * A bigger LBS can be applied to a running array if
+			 * nobody has it open, as there is no I/O through the
+			 * MD gendisk queue without openers. The queue is
+			 * still frozen for the limits update to drain a bio
+			 * of an opener that has just closed.
+			 */
+			if (test_bit(MD_CLOSING, &mddev->flags) ||
+			    atomic_read(&mddev->openers) > 0)
+				err = -EBUSY;
+			else
+				err = mddev_set_logical_block_size(mddev, lbs);
+			mutex_unlock(&mddev->open_mutex);
+			return err ?: len;
+		}
+
+		if (mddev->logical_block_size) {
+			mutex_unlock(&mddev->open_mutex);
 			return -EBUSY;
+		}
 		/*
 		 * To fix forward compatibility issues, LBS is not
 		 * configured for arrays from old kernels (<=6.18) by default.
@@ -6055,12 +6083,14 @@ lbs_store(struct mddev *mddev, const char *buf, size_t len)
 		 * enable LBS by writing current LBS — to prevent data
 		 * loss from LBS changes.
 		 */
-		curr_lbs = queue_logical_block_size(mddev->gendisk->queue);
-		if (lbs != curr_lbs)
+		if (lbs != curr_lbs) {
+			mutex_unlock(&mddev->open_mutex);
 			return -EINVAL;
+		}
 
 		mddev->logical_block_size = curr_lbs;
 		set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
+		mutex_unlock(&mddev->open_mutex);
 		pr_info("%s: logical block size configured successfully, array will not be assembled in old kernels (<= 6.18)\n",
 			mdname(mddev));
 		return len;
-- 
2.43.0


             reply	other threads:[~2026-10-14 11:48 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-14 11:48 Jack Wang [this message]
2026-10-14 12:00 ` [PATCH] md: allow growing logical_block_size on a running array sashiko-bot
2026-10-14 12:33   ` Jinpu Wang

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=20261014114830.615589-1-jinpu.wang@ionos.com \
    --to=jinpu.wang@ionos.com \
    --cc=florian-ewald.mueller@ionos.com \
    --cc=jinpu.wang@cloud.ionos.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=magiclinan@didiglobal.com \
    --cc=song@kernel.org \
    --cc=xiao@kernel.org \
    --cc=yukuai@fygo.io \
    /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