diff options
| -rw-r--r-- | drivers/md/dm-snap.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 59d9ef6f5051..23e3396e43b9 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
| @@ -709,7 +709,8 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 709 | int i; | 709 | int i; |
| 710 | int r = -EINVAL; | 710 | int r = -EINVAL; |
| 711 | char *origin_path, *cow_path; | 711 | char *origin_path, *cow_path; |
| 712 | unsigned args_used; | 712 | unsigned args_used, num_flush_requests = 1; |
| 713 | fmode_t origin_mode = FMODE_READ; | ||
| 713 | 714 | ||
| 714 | if (argc != 4) { | 715 | if (argc != 4) { |
| 715 | ti->error = "requires exactly 4 arguments"; | 716 | ti->error = "requires exactly 4 arguments"; |
| @@ -717,6 +718,11 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 717 | goto bad; | 718 | goto bad; |
| 718 | } | 719 | } |
| 719 | 720 | ||
| 721 | if (dm_target_is_snapshot_merge(ti)) { | ||
| 722 | num_flush_requests = 2; | ||
| 723 | origin_mode = FMODE_WRITE; | ||
| 724 | } | ||
| 725 | |||
| 720 | origin_path = argv[0]; | 726 | origin_path = argv[0]; |
| 721 | argv++; | 727 | argv++; |
| 722 | argc--; | 728 | argc--; |
| @@ -750,7 +756,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 750 | argv += args_used; | 756 | argv += args_used; |
| 751 | argc -= args_used; | 757 | argc -= args_used; |
| 752 | 758 | ||
| 753 | r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin); | 759 | r = dm_get_device(ti, origin_path, 0, ti->len, origin_mode, &s->origin); |
| 754 | if (r) { | 760 | if (r) { |
| 755 | ti->error = "Cannot get origin device"; | 761 | ti->error = "Cannot get origin device"; |
| 756 | goto bad_origin; | 762 | goto bad_origin; |
| @@ -801,7 +807,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 801 | INIT_WORK(&s->queued_bios_work, flush_queued_bios); | 807 | INIT_WORK(&s->queued_bios_work, flush_queued_bios); |
| 802 | 808 | ||
| 803 | ti->private = s; | 809 | ti->private = s; |
| 804 | ti->num_flush_requests = 1; | 810 | ti->num_flush_requests = num_flush_requests; |
| 805 | 811 | ||
| 806 | /* Add snapshot to the list of snapshots for this origin */ | 812 | /* Add snapshot to the list of snapshots for this origin */ |
| 807 | /* Exceptions aren't triggered till snapshot_resume() is called */ | 813 | /* Exceptions aren't triggered till snapshot_resume() is called */ |
| @@ -1326,6 +1332,15 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, | |||
| 1326 | int r = DM_MAPIO_REMAPPED; | 1332 | int r = DM_MAPIO_REMAPPED; |
| 1327 | chunk_t chunk; | 1333 | chunk_t chunk; |
| 1328 | 1334 | ||
| 1335 | if (unlikely(bio_empty_barrier(bio))) { | ||
| 1336 | if (!map_context->flush_request) | ||
| 1337 | bio->bi_bdev = s->origin->bdev; | ||
| 1338 | else | ||
| 1339 | bio->bi_bdev = s->cow->bdev; | ||
| 1340 | map_context->ptr = NULL; | ||
| 1341 | return DM_MAPIO_REMAPPED; | ||
| 1342 | } | ||
| 1343 | |||
| 1329 | chunk = sector_to_chunk(s->store, bio->bi_sector); | 1344 | chunk = sector_to_chunk(s->store, bio->bi_sector); |
| 1330 | 1345 | ||
| 1331 | down_read(&s->lock); | 1346 | down_read(&s->lock); |
