aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2009-12-10 23:52:28 +0000
committerAlasdair G Kergon <agk@redhat.com>2009-12-10 23:52:28 +0000
commit9eaae8ffbc340fc034fed1e5d0dc9ca0e943f817 (patch)
treeb40361de2cde4ecd14f569a82b18df87f7f9cbc7
parentc2f3d24b783fda20618b73d65678eb5dfae31a5d (diff)
downloadkernel_samsung_smdk4412-9eaae8ffbc340fc034fed1e5d0dc9ca0e943f817.zip
kernel_samsung_smdk4412-9eaae8ffbc340fc034fed1e5d0dc9ca0e943f817.tar.gz
kernel_samsung_smdk4412-9eaae8ffbc340fc034fed1e5d0dc9ca0e943f817.tar.bz2
dm snapshot: make bio optional in __origin_write
To support the merging of snapshots back into their origin we need to trigger exceptions in other snapshots not being merged without any incoming bio on the origin device. The bio parameter to __origin_write() becomes optional and the sector needs supplying separately. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
-rw-r--r--drivers/md/dm-snap.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index b5b9118..5e553c5 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1467,7 +1467,19 @@ static int snapshot_iterate_devices(struct dm_target *ti,
/*-----------------------------------------------------------------
* Origin methods
*---------------------------------------------------------------*/
-static int __origin_write(struct list_head *snapshots, struct bio *bio)
+
+/*
+ * If no exceptions need creating, DM_MAPIO_REMAPPED is returned and any
+ * supplied bio was ignored. The caller may submit it immediately.
+ * (No remapping actually occurs as the origin is always a direct linear
+ * map.)
+ *
+ * If further exceptions are required, DM_MAPIO_SUBMITTED is returned
+ * and any supplied bio is added to a list to be submitted once all
+ * the necessary exceptions exist.
+ */
+static int __origin_write(struct list_head *snapshots, sector_t sector,
+ struct bio *bio)
{
int r = DM_MAPIO_REMAPPED, first = 0;
struct dm_snapshot *snap;
@@ -1486,14 +1498,14 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
goto next_snapshot;
/* Nothing to do if writing beyond end of snapshot */
- if (bio->bi_sector >= dm_table_get_size(snap->ti->table))
+ if (sector >= dm_table_get_size(snap->ti->table))
goto next_snapshot;
/*
* Remember, different snapshots can have
* different chunk sizes.
*/
- chunk = sector_to_chunk(snap->store, bio->bi_sector);
+ chunk = sector_to_chunk(snap->store, sector);
/*
* Check exception table to see if block
@@ -1543,7 +1555,8 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
first = 1;
}
- bio_list_add(&primary_pe->origin_bios, bio);
+ if (bio)
+ bio_list_add(&primary_pe->origin_bios, bio);
r = DM_MAPIO_SUBMITTED;
}
@@ -1599,7 +1612,7 @@ static int do_origin(struct dm_dev *origin, struct bio *bio)
down_read(&_origins_lock);
o = __lookup_origin(origin->bdev);
if (o)
- r = __origin_write(&o->snapshots, bio);
+ r = __origin_write(&o->snapshots, bio->bi_sector, bio);
up_read(&_origins_lock);
return r;