raid1/raid10: slow down resync if there is non-resync activity pending
[sfrench/cifs-2.6.git] / drivers / md / raid10.c
index e3fd725d5c4da0c462538f6398981ad048aba352..3578d3aa9ee3a9626dc14481fb8cfdd0f066589c 100644 (file)
@@ -1102,8 +1102,8 @@ static void __make_request(struct mddev *mddev, struct bio *bio)
                bio->bi_iter.bi_sector < conf->reshape_progress))) {
                /* Need to update reshape_position in metadata */
                mddev->reshape_position = conf->reshape_progress;
-               set_bit(MD_CHANGE_DEVS, &mddev->flags);
-               set_bit(MD_CHANGE_PENDING, &mddev->flags);
+               set_mask_bits(&mddev->flags, 0,
+                             BIT(MD_CHANGE_DEVS) | BIT(MD_CHANGE_PENDING));
                md_wakeup_thread(mddev->thread);
                wait_event(mddev->sb_wait,
                           !test_bit(MD_CHANGE_PENDING, &mddev->flags));
@@ -1591,8 +1591,8 @@ static void raid10_error(struct mddev *mddev, struct md_rdev *rdev)
        set_bit(MD_RECOVERY_INTR, &mddev->recovery);
        set_bit(Blocked, &rdev->flags);
        set_bit(Faulty, &rdev->flags);
-       set_bit(MD_CHANGE_DEVS, &mddev->flags);
-       set_bit(MD_CHANGE_PENDING, &mddev->flags);
+       set_mask_bits(&mddev->flags, 0,
+                     BIT(MD_CHANGE_DEVS) | BIT(MD_CHANGE_PENDING));
        spin_unlock_irqrestore(&conf->device_lock, flags);
        printk(KERN_ALERT
               "md/raid10:%s: Disk failure on %s, disabling device.\n"
@@ -2912,6 +2912,13 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
            max_sector > (sector_nr | chunk_mask))
                max_sector = (sector_nr | chunk_mask) + 1;
 
+       /*
+        * If there is non-resync activity waiting for a turn, then let it
+        * though before starting on this new sync request.
+        */
+       if (conf->nr_waiting)
+               schedule_timeout_uninterruptible(1);
+
        /* Again, very different code for resync and recovery.
         * Both must result in an r10bio with a list of bios that
         * have bi_end_io, bi_sector, bi_bdev set,
@@ -3782,8 +3789,10 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors)
                        return ret;
        }
        md_set_array_sectors(mddev, size);
-       set_capacity(mddev->gendisk, mddev->array_sectors);
-       revalidate_disk(mddev->gendisk);
+       if (mddev->queue) {
+               set_capacity(mddev->gendisk, mddev->array_sectors);
+               revalidate_disk(mddev->gendisk);
+       }
        if (sectors > mddev->dev_sectors &&
            mddev->recovery_cp > oldsize) {
                mddev->recovery_cp = oldsize;
@@ -4593,8 +4602,10 @@ static void raid10_finish_reshape(struct mddev *mddev)
                        set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                }
                mddev->resync_max_sectors = size;
-               set_capacity(mddev->gendisk, mddev->array_sectors);
-               revalidate_disk(mddev->gendisk);
+               if (mddev->queue) {
+                       set_capacity(mddev->gendisk, mddev->array_sectors);
+                       revalidate_disk(mddev->gendisk);
+               }
        } else {
                int d;
                for (d = conf->geo.raid_disks ;