From: sashiko-bot@kernel.org
To: "Jack Wang" <jinpu.wang@ionos.com>
Cc: yukuai@fygo.io, linux-raid@vger.kernel.org
Subject: Re: [PATCH v2 5/8] md: take q->limits_lock before locking and suspending the array
Date: Thu, 10 Sep 2026 08:51:12 +0000 [thread overview]
Message-ID: <20260910085112.E46F11F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260910081114.1605746-6-jinpu.wang@ionos.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [High] Missing rollback when `queue_limits_commit_update()` fails, leaving the array mutated with rejected and potentially dangerous block limits.
Pre-existing issues:
- [High] The patch leaves an ABBA deadlock unresolved in `action_store()` when triggering `ACTION_RESHAPE`.
- [High] Writing 'remove' to a spare disk's state attribute in a degraded array incorrectly hot-adds the disk to the array instead of removing it.
--
commit 7025b63183a90cd4ea9de7b41e69a4702b7c8d13
Author: Jack Wang <jinpu.wang@cloud.ionos.com>
md: take q->limits_lock before locking and suspending the array
This commit modifies block limit handling during MD array reconfigurations
to acquire q->limits_lock before locking and suspending the array. This
fixes an ABBA deadlock between the limits lock, reconfig_mutex, and the
array suspend state.
> Two callers still take the lock inside reconfig_mutex with the array
> suspended: ->start_reshape() from action_store(), which suspends before
> flushing sync_work so the update cannot be held across it, and
> raid*_run() from level_store(), which a later patch converts.
[Severity: High]
This is a pre-existing issue, but by leaving the action_store() path
unresolved here, does this leave the system vulnerable to the same ABBA
deadlock if a user writes 'reshape' to sync_action? Concurrent I/O could
still park in the block layer, and a sysfs write to queue limits could
still wait in blk_mq_freeze_queue for q_usage_counter to drain while
mddev_stack_new_rdev attempts to acquire q->limits_lock.
[ ... ]
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index 87e17ba86d93a..0668a048db716 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
[ ... ]
> @@ -3119,7 +3119,7 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len,
> } else if (cmd_match(buf, "remove")) {
> if (rdev->mddev->pers) {
> clear_bit(Blocked, &rdev->flags);
> - remove_and_add_spares(rdev->mddev, rdev, NULL);
> + remove_and_add_spares(rdev->mddev, rdev, lim);
> }
> if (rdev->raid_disk >= 0)
> err = -EBUSY;
[Severity: High]
This isn't a bug introduced by this patch, but if an admin tries to remove
a spare from a degraded array by writing "remove" to the state attribute,
could this unintentionally hot-add the spare instead? Looking at
remove_and_add_spares(), rdev_removeable() would skip spares because they
have raid_disk < 0. Then rdev_addable() might return true, causing
hot_add_disk() to be called and returning -EBUSY.
[ ... ]
> @@ -3782,15 +3785,41 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr,
[ ... ]
> rv = suspend ? mddev_suspend_and_lock(mddev) : mddev_lock(mddev);
> if (!rv) {
> if (rdev->mddev == NULL)
> rv = -ENODEV;
> else
> - rv = entry->store(rdev, page, length, NULL);
> + rv = entry->store(rdev, page, length, limp);
> + /* apply the limits before the array takes I/O again */
> + if (limp) {
> + int err = queue_limits_commit_update(q, limp);
> +
> + limp = NULL;
> + if (err && rv >= 0)
> + rv = err;
> + }
[Severity: High]
If queue_limits_commit_update() fails and rejects the stacked limits, the
error is bubbled up, but is it possible that the array has already been
mutated by entry->store() (such as structurally binding a new disk)? This
might leave the disk actively bound to the array configuration with
stale/rejected block limits.
[ ... ]
> @@ -8618,6 +8677,9 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
> err != -EINVAL)
> mddev->hold_active = 0;
>
> + if (limp)
> + err = queue_limits_commit_update(q, limp) ?: err;
> +
[Severity: High]
Similar to the rdev_attr_store() path above, if the limit commit fails
here, are the array mutations (such as ADD_NEW_DISK) reverted?
[ ... ]
> @@ -10419,6 +10501,8 @@ static void md_start_sync(struct work_struct *ws)
[ ... ]
> * https://bugzilla.kernel.org/show_bug.cgi?id=218200
> * Therefore, use __mddev_resume(mddev, false).
> */
> + if (limp && queue_limits_commit_update(q, limp))
> + pr_err("%s: could not apply queue limits\n", mdname(mddev));
[Severity: High]
If the limit commit fails, this merely logs an error. Will any spares
recently added via remove_and_add_spares() remain fully active with
stale limits, potentially causing data corruption or crashing lower-level
drivers?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260910081114.1605746-1-jinpu.wang@ionos.com?part=5
next prev parent reply other threads:[~2026-09-10 8:51 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-10 8:11 [PATCH v2 0/8] md: don't wait for q->limits_lock while md holds back I/O Jack Wang
2026-09-10 8:11 ` [PATCH v2 1/8] md: pass a queue_limits down to ->hot_add_disk() Jack Wang
2026-09-10 8:31 ` sashiko-bot
2026-09-11 10:46 ` Nilay Shroff
2026-09-10 8:11 ` [PATCH v2 2/8] md: don't wait for q->limits_lock in check_sb_changes() Jack Wang
2026-09-10 8:36 ` sashiko-bot
2026-09-10 8:11 ` [PATCH v2 3/8] md: pass a queue_limits through the rdev sysfs stores Jack Wang
2026-09-10 8:11 ` [PATCH v2 4/8] md: defer the io_opt update out of the sync thread Jack Wang
2026-09-10 8:37 ` sashiko-bot
2026-09-10 8:11 ` [PATCH v2 5/8] md: take q->limits_lock before locking and suspending the array Jack Wang
2026-09-10 8:51 ` sashiko-bot [this message]
2026-09-10 8:11 ` [PATCH v2 6/8] md: pass a queue_limits through ->run() Jack Wang
2026-09-10 8:49 ` sashiko-bot
2026-09-11 10:54 ` Nilay Shroff
2026-09-10 8:11 ` [PATCH v2 7/8] md: open new legs before locking the array Jack Wang
2026-09-10 8:48 ` sashiko-bot
2026-09-10 8:11 ` [PATCH v2 8/8] md: link a new leg's holder " Jack 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=20260910085112.E46F11F00893@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=jinpu.wang@ionos.com \
--cc=linux-raid@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.