aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid10.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r--drivers/md/raid10.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index cd066b63bdaf..df7b0a06b0ea 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2097,11 +2097,17 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
2097 * both 'first' and 'i', so we just compare them. 2097 * both 'first' and 'i', so we just compare them.
2098 * All vec entries are PAGE_SIZE; 2098 * All vec entries are PAGE_SIZE;
2099 */ 2099 */
2100 for (j = 0; j < vcnt; j++) 2100 int sectors = r10_bio->sectors;
2101 for (j = 0; j < vcnt; j++) {
2102 int len = PAGE_SIZE;
2103 if (sectors < (len / 512))
2104 len = sectors * 512;
2101 if (memcmp(page_address(fbio->bi_io_vec[j].bv_page), 2105 if (memcmp(page_address(fbio->bi_io_vec[j].bv_page),
2102 page_address(tbio->bi_io_vec[j].bv_page), 2106 page_address(tbio->bi_io_vec[j].bv_page),
2103 fbio->bi_io_vec[j].bv_len)) 2107 len))
2104 break; 2108 break;
2109 sectors -= len/512;
2110 }
2105 if (j == vcnt) 2111 if (j == vcnt)
2106 continue; 2112 continue;
2107 atomic64_add(r10_bio->sectors, &mddev->resync_mismatches); 2113 atomic64_add(r10_bio->sectors, &mddev->resync_mismatches);
@@ -2284,12 +2290,18 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio)
2284 d = r10_bio->devs[1].devnum; 2290 d = r10_bio->devs[1].devnum;
2285 wbio = r10_bio->devs[1].bio; 2291 wbio = r10_bio->devs[1].bio;
2286 wbio2 = r10_bio->devs[1].repl_bio; 2292 wbio2 = r10_bio->devs[1].repl_bio;
2293 /* Need to test wbio2->bi_end_io before we call
2294 * generic_make_request as if the former is NULL,
2295 * the latter is free to free wbio2.
2296 */
2297 if (wbio2 && !wbio2->bi_end_io)
2298 wbio2 = NULL;
2287 if (wbio->bi_end_io) { 2299 if (wbio->bi_end_io) {
2288 atomic_inc(&conf->mirrors[d].rdev->nr_pending); 2300 atomic_inc(&conf->mirrors[d].rdev->nr_pending);
2289 md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio)); 2301 md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio));
2290 generic_make_request(wbio); 2302 generic_make_request(wbio);
2291 } 2303 }
2292 if (wbio2 && wbio2->bi_end_io) { 2304 if (wbio2) {
2293 atomic_inc(&conf->mirrors[d].replacement->nr_pending); 2305 atomic_inc(&conf->mirrors[d].replacement->nr_pending);
2294 md_sync_acct(conf->mirrors[d].replacement->bdev, 2306 md_sync_acct(conf->mirrors[d].replacement->bdev,
2295 bio_sectors(wbio2)); 2307 bio_sectors(wbio2));
@@ -3407,6 +3419,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
3407 3419
3408 if (bio->bi_end_io == end_sync_read) { 3420 if (bio->bi_end_io == end_sync_read) {
3409 md_sync_acct(bio->bi_bdev, nr_sectors); 3421 md_sync_acct(bio->bi_bdev, nr_sectors);
3422 set_bit(BIO_UPTODATE, &bio->bi_flags);
3410 generic_make_request(bio); 3423 generic_make_request(bio);
3411 } 3424 }
3412 } 3425 }