diff options
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r-- | drivers/md/raid10.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 3c37be6423d7..62ebb1bc72be 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -700,6 +700,8 @@ static int make_request(request_queue_t *q, struct bio * bio) | |||
700 | return 0; | 700 | return 0; |
701 | } | 701 | } |
702 | 702 | ||
703 | md_write_start(mddev, bio); | ||
704 | |||
703 | /* | 705 | /* |
704 | * Register the new request and wait if the reconstruction | 706 | * Register the new request and wait if the reconstruction |
705 | * thread has put up a bar for new requests. | 707 | * thread has put up a bar for new requests. |
@@ -774,7 +776,7 @@ static int make_request(request_queue_t *q, struct bio * bio) | |||
774 | rcu_read_unlock(); | 776 | rcu_read_unlock(); |
775 | 777 | ||
776 | atomic_set(&r10_bio->remaining, 1); | 778 | atomic_set(&r10_bio->remaining, 1); |
777 | md_write_start(mddev); | 779 | |
778 | for (i = 0; i < conf->copies; i++) { | 780 | for (i = 0; i < conf->copies; i++) { |
779 | struct bio *mbio; | 781 | struct bio *mbio; |
780 | int d = r10_bio->devs[i].devnum; | 782 | int d = r10_bio->devs[i].devnum; |
@@ -1216,7 +1218,6 @@ static void raid10d(mddev_t *mddev) | |||
1216 | mdk_rdev_t *rdev; | 1218 | mdk_rdev_t *rdev; |
1217 | 1219 | ||
1218 | md_check_recovery(mddev); | 1220 | md_check_recovery(mddev); |
1219 | md_handle_safemode(mddev); | ||
1220 | 1221 | ||
1221 | for (;;) { | 1222 | for (;;) { |
1222 | char b[BDEVNAME_SIZE]; | 1223 | char b[BDEVNAME_SIZE]; |
@@ -1319,7 +1320,7 @@ static int init_resync(conf_t *conf) | |||
1319 | * | 1320 | * |
1320 | */ | 1321 | */ |
1321 | 1322 | ||
1322 | static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) | 1323 | static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster) |
1323 | { | 1324 | { |
1324 | conf_t *conf = mddev_to_conf(mddev); | 1325 | conf_t *conf = mddev_to_conf(mddev); |
1325 | r10bio_t *r10_bio; | 1326 | r10bio_t *r10_bio; |
@@ -1333,7 +1334,7 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) | |||
1333 | 1334 | ||
1334 | if (!conf->r10buf_pool) | 1335 | if (!conf->r10buf_pool) |
1335 | if (init_resync(conf)) | 1336 | if (init_resync(conf)) |
1336 | return -ENOMEM; | 1337 | return 0; |
1337 | 1338 | ||
1338 | skipped: | 1339 | skipped: |
1339 | max_sector = mddev->size << 1; | 1340 | max_sector = mddev->size << 1; |
@@ -1341,15 +1342,15 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) | |||
1341 | max_sector = mddev->resync_max_sectors; | 1342 | max_sector = mddev->resync_max_sectors; |
1342 | if (sector_nr >= max_sector) { | 1343 | if (sector_nr >= max_sector) { |
1343 | close_sync(conf); | 1344 | close_sync(conf); |
1345 | *skipped = 1; | ||
1344 | return sectors_skipped; | 1346 | return sectors_skipped; |
1345 | } | 1347 | } |
1346 | if (chunks_skipped >= conf->raid_disks) { | 1348 | if (chunks_skipped >= conf->raid_disks) { |
1347 | /* if there has been nothing to do on any drive, | 1349 | /* if there has been nothing to do on any drive, |
1348 | * then there is nothing to do at all.. | 1350 | * then there is nothing to do at all.. |
1349 | */ | 1351 | */ |
1350 | sector_t sec = max_sector - sector_nr; | 1352 | *skipped = 1; |
1351 | md_done_sync(mddev, sec, 1); | 1353 | return (max_sector - sector_nr) + sectors_skipped; |
1352 | return sec + sectors_skipped; | ||
1353 | } | 1354 | } |
1354 | 1355 | ||
1355 | /* make sure whole request will fit in a chunk - if chunks | 1356 | /* make sure whole request will fit in a chunk - if chunks |
@@ -1563,17 +1564,22 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) | |||
1563 | } | 1564 | } |
1564 | } | 1565 | } |
1565 | 1566 | ||
1567 | if (sectors_skipped) | ||
1568 | /* pretend they weren't skipped, it makes | ||
1569 | * no important difference in this case | ||
1570 | */ | ||
1571 | md_done_sync(mddev, sectors_skipped, 1); | ||
1572 | |||
1566 | return sectors_skipped + nr_sectors; | 1573 | return sectors_skipped + nr_sectors; |
1567 | giveup: | 1574 | giveup: |
1568 | /* There is nowhere to write, so all non-sync | 1575 | /* There is nowhere to write, so all non-sync |
1569 | * drives must be failed, so try the next chunk... | 1576 | * drives must be failed, so try the next chunk... |
1570 | */ | 1577 | */ |
1571 | { | 1578 | { |
1572 | int sec = max_sector - sector_nr; | 1579 | sector_t sec = max_sector - sector_nr; |
1573 | sectors_skipped += sec; | 1580 | sectors_skipped += sec; |
1574 | chunks_skipped ++; | 1581 | chunks_skipped ++; |
1575 | sector_nr = max_sector; | 1582 | sector_nr = max_sector; |
1576 | md_done_sync(mddev, sec, 1); | ||
1577 | goto skipped; | 1583 | goto skipped; |
1578 | } | 1584 | } |
1579 | } | 1585 | } |
@@ -1731,8 +1737,7 @@ static int run(mddev_t *mddev) | |||
1731 | out_free_conf: | 1737 | out_free_conf: |
1732 | if (conf->r10bio_pool) | 1738 | if (conf->r10bio_pool) |
1733 | mempool_destroy(conf->r10bio_pool); | 1739 | mempool_destroy(conf->r10bio_pool); |
1734 | if (conf->mirrors) | 1740 | kfree(conf->mirrors); |
1735 | kfree(conf->mirrors); | ||
1736 | kfree(conf); | 1741 | kfree(conf); |
1737 | mddev->private = NULL; | 1742 | mddev->private = NULL; |
1738 | out: | 1743 | out: |
@@ -1748,8 +1753,7 @@ static int stop(mddev_t *mddev) | |||
1748 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ | 1753 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ |
1749 | if (conf->r10bio_pool) | 1754 | if (conf->r10bio_pool) |
1750 | mempool_destroy(conf->r10bio_pool); | 1755 | mempool_destroy(conf->r10bio_pool); |
1751 | if (conf->mirrors) | 1756 | kfree(conf->mirrors); |
1752 | kfree(conf->mirrors); | ||
1753 | kfree(conf); | 1757 | kfree(conf); |
1754 | mddev->private = NULL; | 1758 | mddev->private = NULL; |
1755 | return 0; | 1759 | return 0; |