diff options
Diffstat (limited to 'drivers/md/raid10.c')
| -rw-r--r-- | drivers/md/raid10.c | 19 |
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 | } |
