diff options
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r-- | drivers/md/raid10.c | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 8b29cd4f01c8..d7a8468ddeab 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -337,6 +337,21 @@ static void close_write(r10bio_t *r10_bio) | |||
337 | md_write_end(r10_bio->mddev); | 337 | md_write_end(r10_bio->mddev); |
338 | } | 338 | } |
339 | 339 | ||
340 | static void one_write_done(r10bio_t *r10_bio) | ||
341 | { | ||
342 | if (atomic_dec_and_test(&r10_bio->remaining)) { | ||
343 | if (test_bit(R10BIO_WriteError, &r10_bio->state)) | ||
344 | reschedule_retry(r10_bio); | ||
345 | else { | ||
346 | close_write(r10_bio); | ||
347 | if (test_bit(R10BIO_MadeGood, &r10_bio->state)) | ||
348 | reschedule_retry(r10_bio); | ||
349 | else | ||
350 | raid_end_bio_io(r10_bio); | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | |||
340 | static void raid10_end_write_request(struct bio *bio, int error) | 355 | static void raid10_end_write_request(struct bio *bio, int error) |
341 | { | 356 | { |
342 | int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 357 | 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 | * Let's see if all mirrored write operations have finished | 402 | * Let's see if all mirrored write operations have finished |
388 | * already. | 403 | * already. |
389 | */ | 404 | */ |
390 | if (atomic_dec_and_test(&r10_bio->remaining)) { | 405 | one_write_done(r10_bio); |
391 | if (test_bit(R10BIO_WriteError, &r10_bio->state)) | ||
392 | reschedule_retry(r10_bio); | ||
393 | else { | ||
394 | close_write(r10_bio); | ||
395 | if (test_bit(R10BIO_MadeGood, &r10_bio->state)) | ||
396 | reschedule_retry(r10_bio); | ||
397 | else | ||
398 | raid_end_bio_io(r10_bio); | ||
399 | } | ||
400 | } | ||
401 | if (dec_rdev) | 406 | if (dec_rdev) |
402 | rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev); | 407 | rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev); |
403 | } | 408 | } |
@@ -1127,20 +1132,12 @@ retry_write: | |||
1127 | spin_unlock_irqrestore(&conf->device_lock, flags); | 1132 | spin_unlock_irqrestore(&conf->device_lock, flags); |
1128 | } | 1133 | } |
1129 | 1134 | ||
1130 | if (atomic_dec_and_test(&r10_bio->remaining)) { | 1135 | /* Don't remove the bias on 'remaining' (one_write_done) until |
1131 | /* This matches the end of raid10_end_write_request() */ | 1136 | * after checking if we need to go around again. |
1132 | bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector, | 1137 | */ |
1133 | r10_bio->sectors, | ||
1134 | !test_bit(R10BIO_Degraded, &r10_bio->state), | ||
1135 | 0); | ||
1136 | md_write_end(mddev); | ||
1137 | raid_end_bio_io(r10_bio); | ||
1138 | } | ||
1139 | |||
1140 | /* In case raid10d snuck in to freeze_array */ | ||
1141 | wake_up(&conf->wait_barrier); | ||
1142 | 1138 | ||
1143 | if (sectors_handled < (bio->bi_size >> 9)) { | 1139 | if (sectors_handled < (bio->bi_size >> 9)) { |
1140 | one_write_done(r10_bio); | ||
1144 | /* We need another r10_bio. It has already been counted | 1141 | /* We need another r10_bio. It has already been counted |
1145 | * in bio->bi_phys_segments. | 1142 | * in bio->bi_phys_segments. |
1146 | */ | 1143 | */ |
@@ -1154,6 +1151,10 @@ retry_write: | |||
1154 | r10_bio->state = 0; | 1151 | r10_bio->state = 0; |
1155 | goto retry_write; | 1152 | goto retry_write; |
1156 | } | 1153 | } |
1154 | one_write_done(r10_bio); | ||
1155 | |||
1156 | /* In case raid10d snuck in to freeze_array */ | ||
1157 | wake_up(&conf->wait_barrier); | ||
1157 | 1158 | ||
1158 | if (do_sync || !mddev->bitmap || !plugged) | 1159 | if (do_sync || !mddev->bitmap || !plugged) |
1159 | md_wakeup_thread(mddev->thread); | 1160 | md_wakeup_thread(mddev->thread); |