aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/raid5.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 659151e5eda4..2dc35b4c20ac 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3999,6 +3999,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
3999 return 0; 3999 return 0;
4000 } 4000 }
4001 4001
4002 /* Allow raid5_quiesce to complete */
4003 wait_event(conf->wait_for_overlap, conf->quiesce != 2);
4004
4002 if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) 4005 if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
4003 return reshape_request(mddev, sector_nr, skipped); 4006 return reshape_request(mddev, sector_nr, skipped);
4004 4007
@@ -5104,12 +5107,18 @@ static void raid5_quiesce(mddev_t *mddev, int state)
5104 5107
5105 case 1: /* stop all writes */ 5108 case 1: /* stop all writes */
5106 spin_lock_irq(&conf->device_lock); 5109 spin_lock_irq(&conf->device_lock);
5107 conf->quiesce = 1; 5110 /* '2' tells resync/reshape to pause so that all
5111 * active stripes can drain
5112 */
5113 conf->quiesce = 2;
5108 wait_event_lock_irq(conf->wait_for_stripe, 5114 wait_event_lock_irq(conf->wait_for_stripe,
5109 atomic_read(&conf->active_stripes) == 0 && 5115 atomic_read(&conf->active_stripes) == 0 &&
5110 atomic_read(&conf->active_aligned_reads) == 0, 5116 atomic_read(&conf->active_aligned_reads) == 0,
5111 conf->device_lock, /* nothing */); 5117 conf->device_lock, /* nothing */);
5118 conf->quiesce = 1;
5112 spin_unlock_irq(&conf->device_lock); 5119 spin_unlock_irq(&conf->device_lock);
5120 /* allow reshape to continue */
5121 wake_up(&conf->wait_for_overlap);
5113 break; 5122 break;
5114 5123
5115 case 0: /* re-enable writes */ 5124 case 0: /* re-enable writes */