diff options
author | Li Lingfeng <lilingfeng3@huawei.com> | 2024-01-04 16:36:29 +0300 |
---|---|---|
committer | Song Liu <song@kernel.org> | 2024-02-06 02:23:59 +0300 |
commit | 570b9147deb6b07b955b55e06c714ca12a5f3e16 (patch) | |
tree | b1e07d0656496a157ed6cb9083f8acf6639bd3b1 /drivers/md/md.c | |
parent | 9cfcf99e7ed613e6b3697e1c1034a24487ec3154 (diff) | |
download | linux-570b9147deb6b07b955b55e06c714ca12a5f3e16.tar.xz |
md: use RCU lock to protect traversal in md_spares_need_change()
Since md_start_sync() will be called without the protect of mddev_lock,
and it can run concurrently with array reconfiguration, traversal of rdev
in it should be protected by RCU lock.
Commit bc08041b32ab ("md: suspend array in md_start_sync() if array need
reconfiguration") added md_spares_need_change() to md_start_sync(),
casusing use of rdev without any protection.
Fix this by adding RCU lock in md_spares_need_change().
Fixes: bc08041b32ab ("md: suspend array in md_start_sync() if array need reconfiguration")
Cc: stable@vger.kernel.org # 6.7+
Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com>
Signed-off-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20240104133629.1277517-1-lilingfeng@huaweicloud.com
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 5eff8e84cddf..45bb387d69c4 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -9240,9 +9240,14 @@ static bool md_spares_need_change(struct mddev *mddev) { struct md_rdev *rdev; - rdev_for_each(rdev, mddev) - if (rdev_removeable(rdev) || rdev_addable(rdev)) + rcu_read_lock(); + rdev_for_each_rcu(rdev, mddev) { + if (rdev_removeable(rdev) || rdev_addable(rdev)) { + rcu_read_unlock(); return true; + } + } + rcu_read_unlock(); return false; } |