diff options
Diffstat (limited to 'drivers/md/dm-kcopyd.c')
-rw-r--r-- | drivers/md/dm-kcopyd.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index bed444c93d8d..68c02673263b 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c | |||
@@ -349,7 +349,7 @@ static void complete_io(unsigned long error, void *context) | |||
349 | struct dm_kcopyd_client *kc = job->kc; | 349 | struct dm_kcopyd_client *kc = job->kc; |
350 | 350 | ||
351 | if (error) { | 351 | if (error) { |
352 | if (job->rw == WRITE) | 352 | if (job->rw & WRITE) |
353 | job->write_err |= error; | 353 | job->write_err |= error; |
354 | else | 354 | else |
355 | job->read_err = 1; | 355 | job->read_err = 1; |
@@ -361,7 +361,7 @@ static void complete_io(unsigned long error, void *context) | |||
361 | } | 361 | } |
362 | } | 362 | } |
363 | 363 | ||
364 | if (job->rw == WRITE) | 364 | if (job->rw & WRITE) |
365 | push(&kc->complete_jobs, job); | 365 | push(&kc->complete_jobs, job); |
366 | 366 | ||
367 | else { | 367 | else { |
@@ -432,7 +432,7 @@ static int process_jobs(struct list_head *jobs, struct dm_kcopyd_client *kc, | |||
432 | 432 | ||
433 | if (r < 0) { | 433 | if (r < 0) { |
434 | /* error this rogue job */ | 434 | /* error this rogue job */ |
435 | if (job->rw == WRITE) | 435 | if (job->rw & WRITE) |
436 | job->write_err = (unsigned long) -1L; | 436 | job->write_err = (unsigned long) -1L; |
437 | else | 437 | else |
438 | job->read_err = 1; | 438 | job->read_err = 1; |
@@ -585,6 +585,7 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, | |||
585 | unsigned int flags, dm_kcopyd_notify_fn fn, void *context) | 585 | unsigned int flags, dm_kcopyd_notify_fn fn, void *context) |
586 | { | 586 | { |
587 | struct kcopyd_job *job; | 587 | struct kcopyd_job *job; |
588 | int i; | ||
588 | 589 | ||
589 | /* | 590 | /* |
590 | * Allocate an array of jobs consisting of one master job | 591 | * Allocate an array of jobs consisting of one master job |
@@ -611,7 +612,16 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, | |||
611 | memset(&job->source, 0, sizeof job->source); | 612 | memset(&job->source, 0, sizeof job->source); |
612 | job->source.count = job->dests[0].count; | 613 | job->source.count = job->dests[0].count; |
613 | job->pages = &zero_page_list; | 614 | job->pages = &zero_page_list; |
614 | job->rw = WRITE; | 615 | |
616 | /* | ||
617 | * Use WRITE SAME to optimize zeroing if all dests support it. | ||
618 | */ | ||
619 | job->rw = WRITE | REQ_WRITE_SAME; | ||
620 | for (i = 0; i < job->num_dests; i++) | ||
621 | if (!bdev_write_same(job->dests[i].bdev)) { | ||
622 | job->rw = WRITE; | ||
623 | break; | ||
624 | } | ||
615 | } | 625 | } |
616 | 626 | ||
617 | job->fn = fn; | 627 | job->fn = fn; |