Merge Linus master into drm-next
[linux-2.6-microblaze.git] / drivers / md / raid5.c
index e75d48c..cd2f96b 100644 (file)
@@ -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);