From: NeilBrown Date: Thu, 2 Jun 2016 06:19:52 +0000 (+1000) Subject: md/raid5: add rcu protection to rdev accesses in handle_failed_sync. X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=e50d3992328320acf2454c1e7301a094cd90aebc;p=linux-beck.git md/raid5: add rcu protection to rdev accesses in handle_failed_sync. The rdev could be freed while handle_failed_sync is running, so rcu protection is needed. Signed-off-by: NeilBrown Signed-off-by: Shaohua Li --- diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index ad9e15a3ef51..e56c7e0627fa 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3210,15 +3210,16 @@ handle_failed_sync(struct r5conf *conf, struct stripe_head *sh, /* During recovery devices cannot be removed, so * locking and refcounting of rdevs is not needed */ + rcu_read_lock(); for (i = 0; i < conf->raid_disks; i++) { - struct md_rdev *rdev = conf->disks[i].rdev; + struct md_rdev *rdev = rcu_dereference(conf->disks[i].rdev); if (rdev && !test_bit(Faulty, &rdev->flags) && !test_bit(In_sync, &rdev->flags) && !rdev_set_badblocks(rdev, sh->sector, STRIPE_SECTORS, 0)) abort = 1; - rdev = conf->disks[i].replacement; + rdev = rcu_dereference(conf->disks[i].replacement); if (rdev && !test_bit(Faulty, &rdev->flags) && !test_bit(In_sync, &rdev->flags) @@ -3226,6 +3227,7 @@ handle_failed_sync(struct r5conf *conf, struct stripe_head *sh, STRIPE_SECTORS, 0)) abort = 1; } + rcu_read_unlock(); if (abort) conf->recovery_disabled = conf->mddev->recovery_disabled;