Skip to content

Commit 486f605

Browse files
lsgunthaxboe
authored andcommitted
md/raid5: Check all disks in a stripe_head for reshape progress
When testing if a previous stripe has had reshape expand past it, use the earliest or latest logical sector in all the disks for that stripe head. This will allow adding multiple disks at a time in a subesquent patch. To do this cleaner, refactor the check into a helper function called stripe_ahead_of_reshape(). Signed-off-by: Logan Gunthorpe <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Song Liu <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 4ad1d98 commit 486f605

File tree

1 file changed

+39
-14
lines changed

1 file changed

+39
-14
lines changed

drivers/md/raid5.c

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5819,6 +5819,40 @@ static bool ahead_of_reshape(struct mddev *mddev, sector_t sector,
58195819
sector >= reshape_sector;
58205820
}
58215821

5822+
static bool range_ahead_of_reshape(struct mddev *mddev, sector_t min,
5823+
sector_t max, sector_t reshape_sector)
5824+
{
5825+
return mddev->reshape_backwards ? max < reshape_sector :
5826+
min >= reshape_sector;
5827+
}
5828+
5829+
static bool stripe_ahead_of_reshape(struct mddev *mddev, struct r5conf *conf,
5830+
struct stripe_head *sh)
5831+
{
5832+
sector_t max_sector = 0, min_sector = MaxSector;
5833+
bool ret = false;
5834+
int dd_idx;
5835+
5836+
for (dd_idx = 0; dd_idx < sh->disks; dd_idx++) {
5837+
if (dd_idx == sh->pd_idx)
5838+
continue;
5839+
5840+
min_sector = min(min_sector, sh->dev[dd_idx].sector);
5841+
max_sector = min(max_sector, sh->dev[dd_idx].sector);
5842+
}
5843+
5844+
spin_lock_irq(&conf->device_lock);
5845+
5846+
if (!range_ahead_of_reshape(mddev, min_sector, max_sector,
5847+
conf->reshape_progress))
5848+
/* mismatch, need to try again */
5849+
ret = true;
5850+
5851+
spin_unlock_irq(&conf->device_lock);
5852+
5853+
return ret;
5854+
}
5855+
58225856
enum stripe_result {
58235857
STRIPE_SUCCESS = 0,
58245858
STRIPE_RETRY,
@@ -5883,27 +5917,18 @@ static enum stripe_result make_stripe_request(struct mddev *mddev,
58835917
return STRIPE_FAIL;
58845918
}
58855919

5886-
if (unlikely(previous)) {
5920+
if (unlikely(previous) &&
5921+
stripe_ahead_of_reshape(mddev, conf, sh)) {
58875922
/*
5888-
* Expansion might have moved on while waiting for a
5889-
* stripe, so we must do the range check again.
5923+
* Expansion moved on while waiting for a stripe.
58905924
* Expansion could still move past after this
58915925
* test, but as we are holding a reference to
58925926
* 'sh', we know that if that happens,
58935927
* STRIPE_EXPANDING will get set and the expansion
58945928
* won't proceed until we finish with the stripe.
58955929
*/
5896-
int must_retry = 0;
5897-
spin_lock_irq(&conf->device_lock);
5898-
if (!ahead_of_reshape(mddev, logical_sector,
5899-
conf->reshape_progress))
5900-
/* mismatch, need to try again */
5901-
must_retry = 1;
5902-
spin_unlock_irq(&conf->device_lock);
5903-
if (must_retry) {
5904-
ret = STRIPE_SCHEDULE_AND_RETRY;
5905-
goto out_release;
5906-
}
5930+
ret = STRIPE_SCHEDULE_AND_RETRY;
5931+
goto out_release;
59075932
}
59085933

59095934
if (read_seqcount_retry(&conf->gen_lock, seq)) {

0 commit comments

Comments
 (0)