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); |