From 8abea79da85def035ac69f5665683323cfad7289 Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Fri, 1 Mar 2013 22:45:49 +0000 Subject: [PATCH] --- yaml --- r: 360327 b: refs/heads/master c: b0d8ed4d96a26ef3ac54a4aa8911c9413070662e h: refs/heads/master i: 360325: 3b83f2c7ed4061c03a808f1e19b8bb221bc776d7 360323: eaceeba1b13a33e7ab68e3e535df38269aa91b95 360319: 0e137718f537d00c505f76efa40afc3471dfd8ff v: v3 --- [refs] | 2 +- trunk/drivers/md/dm.c | 22 +++++++++++++++------- trunk/include/linux/device-mapper.h | 15 +++++++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index db732c9477de..0e45a970d7d1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: df5d2e9089c7d5b8c46f767e4278610ea3e815b9 +refs/heads/master: b0d8ed4d96a26ef3ac54a4aa8911c9413070662e diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index e417cf0a69ef..7e469260fe5e 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -1152,15 +1152,23 @@ static void __clone_and_map_data_bio(struct clone_info *ci, struct dm_target *ti { struct bio *bio = ci->bio; struct dm_target_io *tio; + unsigned target_bio_nr; + unsigned num_target_bios = 1; - tio = alloc_tio(ci, ti, nr_iovecs, 0); - - if (split_bvec) - clone_split_bio(tio, bio, sector, idx, offset, len); - else - clone_bio(tio, bio, sector, idx, bv_count, len); + /* + * Does the target want to receive duplicate copies of the bio? + */ + if (bio_data_dir(bio) == WRITE && ti->num_write_bios) + num_target_bios = ti->num_write_bios(ti, bio); - __map_bio(tio); + for (target_bio_nr = 0; target_bio_nr < num_target_bios; target_bio_nr++) { + tio = alloc_tio(ci, ti, nr_iovecs, target_bio_nr); + if (split_bvec) + clone_split_bio(tio, bio, sector, idx, offset, len); + else + clone_bio(tio, bio, sector, idx, bv_count, len); + __map_bio(tio); + } } typedef unsigned (*get_num_bios_fn)(struct dm_target *ti); diff --git a/trunk/include/linux/device-mapper.h b/trunk/include/linux/device-mapper.h index d5f984b07466..1e483fa7afb4 100644 --- a/trunk/include/linux/device-mapper.h +++ b/trunk/include/linux/device-mapper.h @@ -175,6 +175,14 @@ struct target_type { #define DM_TARGET_IMMUTABLE 0x00000004 #define dm_target_is_immutable(type) ((type)->features & DM_TARGET_IMMUTABLE) +/* + * Some targets need to be sent the same WRITE bio severals times so + * that they can send copies of it to different devices. This function + * examines any supplied bio and returns the number of copies of it the + * target requires. + */ +typedef unsigned (*dm_num_write_bios_fn) (struct dm_target *ti, struct bio *bio); + struct dm_target { struct dm_table *table; struct target_type *type; @@ -214,6 +222,13 @@ struct dm_target { */ unsigned per_bio_data_size; + /* + * If defined, this function is called to find out how many + * duplicate bios should be sent to the target when writing + * data. + */ + dm_num_write_bios_fn num_write_bios; + /* target specific data */ void *private;