Skip to content

Commit b3143b9

Browse files
NeilBrownshligit
authored andcommitted
md: move suspend_hi/lo handling into core md code
responding to ->suspend_lo and ->suspend_hi is similar to responding to ->suspended. It is best to wait in the common core code without incrementing ->active_io. This allows mddev_suspend()/mddev_resume() to work while requests are waiting for suspend_lo/hi to change. This is will be important after a subsequent patch which uses mddev_suspend() to synchronize updating for suspend_lo/hi. So move the code for testing suspend_lo/hi out of raid1.c and raid5.c, and place it in md.c Signed-off-by: NeilBrown <[email protected]> Signed-off-by: Shaohua Li <[email protected]>
1 parent 52a0d49 commit b3143b9

File tree

3 files changed

+28
-37
lines changed

3 files changed

+28
-37
lines changed

drivers/md/md.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,16 +266,31 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
266266
* call has finished, the bio has been linked into some internal structure
267267
* and so is visible to ->quiesce(), so we don't need the refcount any more.
268268
*/
269+
static bool is_suspended(struct mddev *mddev, struct bio *bio)
270+
{
271+
if (mddev->suspended)
272+
return true;
273+
if (bio_data_dir(bio) != WRITE)
274+
return false;
275+
if (mddev->suspend_lo >= mddev->suspend_hi)
276+
return false;
277+
if (bio->bi_iter.bi_sector >= mddev->suspend_hi)
278+
return false;
279+
if (bio_end_sector(bio) < mddev->suspend_lo)
280+
return false;
281+
return true;
282+
}
283+
269284
void md_handle_request(struct mddev *mddev, struct bio *bio)
270285
{
271286
check_suspended:
272287
rcu_read_lock();
273-
if (mddev->suspended) {
288+
if (is_suspended(mddev, bio)) {
274289
DEFINE_WAIT(__wait);
275290
for (;;) {
276291
prepare_to_wait(&mddev->sb_wait, &__wait,
277292
TASK_UNINTERRUPTIBLE);
278-
if (!mddev->suspended)
293+
if (!is_suspended(mddev, bio))
279294
break;
280295
rcu_read_unlock();
281296
schedule();
@@ -4845,10 +4860,11 @@ suspend_lo_store(struct mddev *mddev, const char *buf, size_t len)
48454860
goto unlock;
48464861
old = mddev->suspend_lo;
48474862
mddev->suspend_lo = new;
4848-
if (new >= old)
4863+
if (new >= old) {
48494864
/* Shrinking suspended region */
4865+
wake_up(&mddev->sb_wait);
48504866
mddev->pers->quiesce(mddev, 2);
4851-
else {
4867+
} else {
48524868
/* Expanding suspended region - need to wait */
48534869
mddev->pers->quiesce(mddev, 1);
48544870
mddev->pers->quiesce(mddev, 0);
@@ -4888,10 +4904,11 @@ suspend_hi_store(struct mddev *mddev, const char *buf, size_t len)
48884904
goto unlock;
48894905
old = mddev->suspend_hi;
48904906
mddev->suspend_hi = new;
4891-
if (new <= old)
4907+
if (new <= old) {
48924908
/* Shrinking suspended region */
4909+
wake_up(&mddev->sb_wait);
48934910
mddev->pers->quiesce(mddev, 2);
4894-
else {
4911+
} else {
48954912
/* Expanding suspended region - need to wait */
48964913
mddev->pers->quiesce(mddev, 1);
48974914
mddev->pers->quiesce(mddev, 0);

drivers/md/raid1.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,11 +1310,9 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
13101310
*/
13111311

13121312

1313-
if ((bio_end_sector(bio) > mddev->suspend_lo &&
1314-
bio->bi_iter.bi_sector < mddev->suspend_hi) ||
1315-
(mddev_is_clustered(mddev) &&
1313+
if (mddev_is_clustered(mddev) &&
13161314
md_cluster_ops->area_resyncing(mddev, WRITE,
1317-
bio->bi_iter.bi_sector, bio_end_sector(bio)))) {
1315+
bio->bi_iter.bi_sector, bio_end_sector(bio))) {
13181316

13191317
/*
13201318
* As the suspend_* range is controlled by userspace, we want
@@ -1325,12 +1323,10 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
13251323
sigset_t full, old;
13261324
prepare_to_wait(&conf->wait_barrier,
13271325
&w, TASK_INTERRUPTIBLE);
1328-
if ((bio_end_sector(bio) <= mddev->suspend_lo ||
1329-
bio->bi_iter.bi_sector >= mddev->suspend_hi) &&
1330-
(!mddev_is_clustered(mddev) ||
1331-
!md_cluster_ops->area_resyncing(mddev, WRITE,
1326+
if (!mddev_is_clustered(mddev) ||
1327+
!md_cluster_ops->area_resyncing(mddev, WRITE,
13321328
bio->bi_iter.bi_sector,
1333-
bio_end_sector(bio))))
1329+
bio_end_sector(bio)))
13341330
break;
13351331
sigfillset(&full);
13361332
sigprocmask(SIG_BLOCK, &full, &old);

drivers/md/raid5.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5685,28 +5685,6 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
56855685
goto retry;
56865686
}
56875687

5688-
if (rw == WRITE &&
5689-
logical_sector >= mddev->suspend_lo &&
5690-
logical_sector < mddev->suspend_hi) {
5691-
raid5_release_stripe(sh);
5692-
/* As the suspend_* range is controlled by
5693-
* userspace, we want an interruptible
5694-
* wait.
5695-
*/
5696-
prepare_to_wait(&conf->wait_for_overlap,
5697-
&w, TASK_INTERRUPTIBLE);
5698-
if (logical_sector >= mddev->suspend_lo &&
5699-
logical_sector < mddev->suspend_hi) {
5700-
sigset_t full, old;
5701-
sigfillset(&full);
5702-
sigprocmask(SIG_BLOCK, &full, &old);
5703-
schedule();
5704-
sigprocmask(SIG_SETMASK, &old, NULL);
5705-
do_prepare = true;
5706-
}
5707-
goto retry;
5708-
}
5709-
57105688
if (test_bit(STRIPE_EXPANDING, &sh->state) ||
57115689
!add_stripe_bio(sh, bi, dd_idx, rw, previous)) {
57125690
/* Stripe is busy expanding or

0 commit comments

Comments
 (0)