aboutsummaryrefslogtreecommitdiff
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorLinus Torvalds2015-03-02 14:03:27 -0800
committerLinus Torvalds2015-03-02 14:03:27 -0800
commit1a6f77ab08d41ef0ec543fa29bf5040c10b5651a (patch)
treeab364ff196fa661a450dc054d354a75bba157ac0 /drivers/md/raid5.c
parent49db1f0ef2df10de1dfd40c8d66e4379d953640f (diff)
parent750f199ee8b578062341e6ddfe36c59ac8ff2dcb (diff)
Merge tag 'md/4.0-fixes' of git://neil.brown.name/md
Pull md fixes from Neil Brown: "Three md fixes: - fix a read-balance problem that was reported 2 years ago, but that I never noticed the report :-( - fix for rare RAID6 problem causing incorrect bitmap updates when two devices fail. - add __ATTR_PREALLOC annotation now that it is possible" * tag 'md/4.0-fixes' of git://neil.brown.name/md: md: mark some attributes as pre-alloc raid5: check faulty flag for array status during recovery. md/raid1: fix read balance when a drive is write-mostly.
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index e75d48c0421a..cd2f96b2c572 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -5121,12 +5121,17 @@ static inline sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int
schedule_timeout_uninterruptible(1);
}
/* Need to check if array will still be degraded after recovery/resync
- * We don't need to check the 'failed' flag as when that gets set,
- * recovery aborts.
+ * Note in case of > 1 drive failures it's possible we're rebuilding
+ * one drive while leaving another faulty drive in array.
*/
- for (i = 0; i < conf->raid_disks; i++)
- if (conf->disks[i].rdev == NULL)
+ rcu_read_lock();
+ for (i = 0; i < conf->raid_disks; i++) {
+ struct md_rdev *rdev = ACCESS_ONCE(conf->disks[i].rdev);
+
+ if (rdev == NULL || test_bit(Faulty, &rdev->flags))
still_degraded = 1;
+ }
+ rcu_read_unlock();
bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded);