aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid10.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-07-27 21:39:25 -0400
committerNeilBrown <neilb@suse.de>2011-07-27 21:39:25 -0400
commit1a0b7cd82657a590f163b090bd9123a3a6b9aae4 (patch)
tree0dc3ccf6ad6ad88283e6d7924c38524865866cba /drivers/md/raid10.c
parentf84ee364dd15af11cada1e673f94128f62db189e (diff)
md/raid10: record bad blocks due to write errors during resync/recovery.
If we get a write error during resync/recovery don't fail the device but instead record a bad block. If that fails we can then fail the device. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r--drivers/md/raid10.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 10415ddfcb42..e54ff3274eda 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1452,9 +1452,10 @@ static void end_sync_write(struct bio *bio, int error)
1452 1452
1453 d = find_bio_disk(conf, r10_bio, bio, &slot); 1453 d = find_bio_disk(conf, r10_bio, bio, &slot);
1454 1454
1455 if (!uptodate) 1455 if (!uptodate) {
1456 md_error(mddev, conf->mirrors[d].rdev); 1456 set_bit(WriteErrorSeen, &conf->mirrors[d].rdev->flags);
1457 else if (is_badblock(conf->mirrors[d].rdev, 1457 set_bit(R10BIO_WriteError, &r10_bio->state);
1458 } else if (is_badblock(conf->mirrors[d].rdev,
1458 r10_bio->devs[slot].addr, 1459 r10_bio->devs[slot].addr,
1459 r10_bio->sectors, 1460 r10_bio->sectors,
1460 &first_bad, &bad_sectors)) 1461 &first_bad, &bad_sectors))
@@ -1465,7 +1466,8 @@ static void end_sync_write(struct bio *bio, int error)
1465 if (r10_bio->master_bio == NULL) { 1466 if (r10_bio->master_bio == NULL) {
1466 /* the primary of several recovery bios */ 1467 /* the primary of several recovery bios */
1467 sector_t s = r10_bio->sectors; 1468 sector_t s = r10_bio->sectors;
1468 if (test_bit(R10BIO_MadeGood, &r10_bio->state)) 1469 if (test_bit(R10BIO_MadeGood, &r10_bio->state) ||
1470 test_bit(R10BIO_WriteError, &r10_bio->state))
1469 reschedule_retry(r10_bio); 1471 reschedule_retry(r10_bio);
1470 else 1472 else
1471 put_buf(r10_bio); 1473 put_buf(r10_bio);
@@ -1473,7 +1475,8 @@ static void end_sync_write(struct bio *bio, int error)
1473 break; 1475 break;
1474 } else { 1476 } else {
1475 r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio; 1477 r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio;
1476 if (test_bit(R10BIO_MadeGood, &r10_bio->state)) 1478 if (test_bit(R10BIO_MadeGood, &r10_bio->state) ||
1479 test_bit(R10BIO_WriteError, &r10_bio->state))
1477 reschedule_retry(r10_bio); 1480 reschedule_retry(r10_bio);
1478 else 1481 else
1479 put_buf(r10_bio); 1482 put_buf(r10_bio);
@@ -2029,23 +2032,33 @@ static void handle_write_completed(conf_t *conf, r10bio_t *r10_bio)
2029 /* Some sort of write request has finished and it 2032 /* Some sort of write request has finished and it
2030 * succeeded in writing where we thought there was a 2033 * succeeded in writing where we thought there was a
2031 * bad block. So forget the bad block. 2034 * bad block. So forget the bad block.
2035 * Or possibly if failed and we need to record
2036 * a bad block.
2032 */ 2037 */
2033 int m; 2038 int m;
2034 mdk_rdev_t *rdev; 2039 mdk_rdev_t *rdev;
2035 2040
2036 if (test_bit(R10BIO_IsSync, &r10_bio->state) || 2041 if (test_bit(R10BIO_IsSync, &r10_bio->state) ||
2037 test_bit(R10BIO_IsRecover, &r10_bio->state)) { 2042 test_bit(R10BIO_IsRecover, &r10_bio->state)) {
2038 for (m = 0; m < conf->copies; m++) 2043 for (m = 0; m < conf->copies; m++) {
2039 if (r10_bio->devs[m].bio && 2044 int dev = r10_bio->devs[m].devnum;
2040 test_bit(BIO_UPTODATE, 2045 rdev = conf->mirrors[dev].rdev;
2046 if (r10_bio->devs[m].bio == NULL)
2047 continue;
2048 if (test_bit(BIO_UPTODATE,
2041 &r10_bio->devs[m].bio->bi_flags)) { 2049 &r10_bio->devs[m].bio->bi_flags)) {
2042 int dev = r10_bio->devs[m].devnum;
2043 rdev = conf->mirrors[dev].rdev;
2044 rdev_clear_badblocks( 2050 rdev_clear_badblocks(
2045 rdev, 2051 rdev,
2046 r10_bio->devs[m].addr, 2052 r10_bio->devs[m].addr,
2047 r10_bio->sectors); 2053 r10_bio->sectors);
2054 } else {
2055 if (!rdev_set_badblocks(
2056 rdev,
2057 r10_bio->devs[m].addr,
2058 r10_bio->sectors, 0))
2059 md_error(conf->mddev, rdev);
2048 } 2060 }
2061 }
2049 put_buf(r10_bio); 2062 put_buf(r10_bio);
2050 } else { 2063 } else {
2051 for (m = 0; m < conf->copies; m++) { 2064 for (m = 0; m < conf->copies; m++) {