Commit 19d5f834 authored by NeilBrown's avatar NeilBrown

md/raid10: unify handling of write completion.

A write can complete at two different places:
1/ when the last member-device write completes, through
   raid10_end_write_request
2/ in make_request() when we remove the initial bias from ->remaining.

These two should do exactly the same thing and the comment says they
do, but they don't.

So factor the correct code out into a function and call it in both
places.  This makes the code much more similar to RAID1.

The difference is only significant if there is an error, and they
usually take a while, so it is unlikely that there will be an error
already when make_request is completing, so this is unlikely to cause
real problems.
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 94007751
...@@ -337,6 +337,21 @@ static void close_write(r10bio_t *r10_bio) ...@@ -337,6 +337,21 @@ static void close_write(r10bio_t *r10_bio)
md_write_end(r10_bio->mddev); md_write_end(r10_bio->mddev);
} }
static void one_write_done(r10bio_t *r10_bio)
{
if (atomic_dec_and_test(&r10_bio->remaining)) {
if (test_bit(R10BIO_WriteError, &r10_bio->state))
reschedule_retry(r10_bio);
else {
close_write(r10_bio);
if (test_bit(R10BIO_MadeGood, &r10_bio->state))
reschedule_retry(r10_bio);
else
raid_end_bio_io(r10_bio);
}
}
}
static void raid10_end_write_request(struct bio *bio, int error) static void raid10_end_write_request(struct bio *bio, int error)
{ {
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
...@@ -387,17 +402,7 @@ static void raid10_end_write_request(struct bio *bio, int error) ...@@ -387,17 +402,7 @@ static void raid10_end_write_request(struct bio *bio, int error)
* Let's see if all mirrored write operations have finished * Let's see if all mirrored write operations have finished
* already. * already.
*/ */
if (atomic_dec_and_test(&r10_bio->remaining)) { one_write_done(r10_bio);
if (test_bit(R10BIO_WriteError, &r10_bio->state))
reschedule_retry(r10_bio);
else {
close_write(r10_bio);
if (test_bit(R10BIO_MadeGood, &r10_bio->state))
reschedule_retry(r10_bio);
else
raid_end_bio_io(r10_bio);
}
}
if (dec_rdev) if (dec_rdev)
rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev); rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev);
} }
...@@ -1127,15 +1132,8 @@ static int make_request(mddev_t *mddev, struct bio * bio) ...@@ -1127,15 +1132,8 @@ static int make_request(mddev_t *mddev, struct bio * bio)
spin_unlock_irqrestore(&conf->device_lock, flags); spin_unlock_irqrestore(&conf->device_lock, flags);
} }
if (atomic_dec_and_test(&r10_bio->remaining)) { /* Remove the bias on 'remaining' */
/* This matches the end of raid10_end_write_request() */ one_write_done(r10_bio);
bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector,
r10_bio->sectors,
!test_bit(R10BIO_Degraded, &r10_bio->state),
0);
md_write_end(mddev);
raid_end_bio_io(r10_bio);
}
/* In case raid10d snuck in to freeze_array */ /* In case raid10d snuck in to freeze_array */
wake_up(&conf->wait_barrier); wake_up(&conf->wait_barrier);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment