diff options
author | Mike Snitzer <snitzer@redhat.com> | 2009-12-11 00:52:31 +0100 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-12-11 00:52:31 +0100 |
commit | 10b8106a70433e14153469ebbdd189776500e238 (patch) | |
tree | 5d46ee65e40d165494ef1d4342e03f2fcfaa0492 /drivers/md/dm-snap.c | |
parent | dm snapshot: avoid allocating exceptions in merge (diff) | |
download | linux-10b8106a70433e14153469ebbdd189776500e238.tar.xz linux-10b8106a70433e14153469ebbdd189776500e238.zip |
dm snapshot: support barriers in snapshot merge target
Sets num_flush_requests=2 to support flushing both the origin and cow
devices used by the snapshot-merge target.
Also, snapshot_ctr() now gets the origin device using FMODE_WRITE if the
target is snapshot-merge (which writes to the origin device).
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-snap.c')
-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) int i; int r = -EINVAL; char *origin_path, *cow_path; - unsigned args_used; + unsigned args_used, num_flush_requests = 1; + fmode_t origin_mode = FMODE_READ; if (argc != 4) { ti->error = "requires exactly 4 arguments"; @@ -717,6 +718,11 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad; } + if (dm_target_is_snapshot_merge(ti)) { + num_flush_requests = 2; + origin_mode = FMODE_WRITE; + } + origin_path = argv[0]; argv++; argc--; @@ -750,7 +756,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) argv += args_used; argc -= args_used; - r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin); + r = dm_get_device(ti, origin_path, 0, ti->len, origin_mode, &s->origin); if (r) { ti->error = "Cannot get origin device"; goto bad_origin; @@ -801,7 +807,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) INIT_WORK(&s->queued_bios_work, flush_queued_bios); ti->private = s; - ti->num_flush_requests = 1; + ti->num_flush_requests = num_flush_requests; /* Add snapshot to the list of snapshots for this origin */ /* 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, int r = DM_MAPIO_REMAPPED; chunk_t chunk; + if (unlikely(bio_empty_barrier(bio))) { + if (!map_context->flush_request) + bio->bi_bdev = s->origin->bdev; + else + bio->bi_bdev = s->cow->bdev; + map_context->ptr = NULL; + return DM_MAPIO_REMAPPED; + } + chunk = sector_to_chunk(s->store, bio->bi_sector); down_read(&s->lock); |