aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlasdair G Kergon <agk@redhat.com>2013-03-01 17:45:49 -0500
committerAlasdair G Kergon <agk@redhat.com>2013-03-01 17:45:49 -0500
commitb0d8ed4d96a26ef3ac54a4aa8911c9413070662e (patch)
treeb43cc88d671e85840a625cdb0de75754182043ac
parentdf5d2e9089c7d5b8c46f767e4278610ea3e815b9 (diff)
dm: add target num_write_bios fn
Add a num_write_bios function to struct target. If an instance of a target sets this, it will be queried before the target's mapping function is called on a write bio, and the response controls the number of copies of the write bio that the target will receive. This provides a convenient way for a target to send the same data to more than one device. The new cache target uses this in writethrough mode, to send the data both to the cache and the backing device. Signed-off-by: Alasdair G Kergon <agk@redhat.com>
-rw-r--r--drivers/md/dm.c22
-rw-r--r--include/linux/device-mapper.h15
2 files changed, 30 insertions, 7 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index e417cf0a69ef..7e469260fe5e 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1152,15 +1152,23 @@ static void __clone_and_map_data_bio(struct clone_info *ci, struct dm_target *ti
1152{ 1152{
1153 struct bio *bio = ci->bio; 1153 struct bio *bio = ci->bio;
1154 struct dm_target_io *tio; 1154 struct dm_target_io *tio;
1155 unsigned target_bio_nr;
1156 unsigned num_target_bios = 1;
1155 1157
1156 tio = alloc_tio(ci, ti, nr_iovecs, 0); 1158 /*
1157 1159 * Does the target want to receive duplicate copies of the bio?
1158 if (split_bvec) 1160 */
1159 clone_split_bio(tio, bio, sector, idx, offset, len); 1161 if (bio_data_dir(bio) == WRITE && ti->num_write_bios)
1160 else 1162 num_target_bios = ti->num_write_bios(ti, bio);
1161 clone_bio(tio, bio, sector, idx, bv_count, len);
1162 1163
1163 __map_bio(tio); 1164 for (target_bio_nr = 0; target_bio_nr < num_target_bios; target_bio_nr++) {
1165 tio = alloc_tio(ci, ti, nr_iovecs, target_bio_nr);
1166 if (split_bvec)
1167 clone_split_bio(tio, bio, sector, idx, offset, len);
1168 else
1169 clone_bio(tio, bio, sector, idx, bv_count, len);
1170 __map_bio(tio);
1171 }
1164} 1172}
1165 1173
1166typedef unsigned (*get_num_bios_fn)(struct dm_target *ti); 1174typedef unsigned (*get_num_bios_fn)(struct dm_target *ti);
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index d5f984b07466..1e483fa7afb4 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -175,6 +175,14 @@ struct target_type {
175#define DM_TARGET_IMMUTABLE 0x00000004 175#define DM_TARGET_IMMUTABLE 0x00000004
176#define dm_target_is_immutable(type) ((type)->features & DM_TARGET_IMMUTABLE) 176#define dm_target_is_immutable(type) ((type)->features & DM_TARGET_IMMUTABLE)
177 177
178/*
179 * Some targets need to be sent the same WRITE bio severals times so
180 * that they can send copies of it to different devices. This function
181 * examines any supplied bio and returns the number of copies of it the
182 * target requires.
183 */
184typedef unsigned (*dm_num_write_bios_fn) (struct dm_target *ti, struct bio *bio);
185
178struct dm_target { 186struct dm_target {
179 struct dm_table *table; 187 struct dm_table *table;
180 struct target_type *type; 188 struct target_type *type;
@@ -214,6 +222,13 @@ struct dm_target {
214 */ 222 */
215 unsigned per_bio_data_size; 223 unsigned per_bio_data_size;
216 224
225 /*
226 * If defined, this function is called to find out how many
227 * duplicate bios should be sent to the target when writing
228 * data.
229 */
230 dm_num_write_bios_fn num_write_bios;
231
217 /* target specific data */ 232 /* target specific data */
218 void *private; 233 void *private;
219 234