aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Lingfeng <[email protected]>2024-01-04 21:36:29 +0800
committerSong Liu <[email protected]>2024-02-05 15:23:59 -0800
commit570b9147deb6b07b955b55e06c714ca12a5f3e16 (patch)
treeb1e07d0656496a157ed6cb9083f8acf6639bd3b1
parent9cfcf99e7ed613e6b3697e1c1034a24487ec3154 (diff)
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: [email protected] # 6.7+ Signed-off-by: Li Lingfeng <[email protected]> Signed-off-by: Song Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected]
-rw-r--r--drivers/md/md.c9
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;
}