aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-snap.c21
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);