diff options
-rw-r--r-- | drivers/md/dm.c | 22 | ||||
-rw-r--r-- | include/linux/device-mapper.h | 15 |
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 | ||
1166 | typedef unsigned (*get_num_bios_fn)(struct dm_target *ti); | 1174 | typedef 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 | */ | ||
184 | typedef unsigned (*dm_num_write_bios_fn) (struct dm_target *ti, struct bio *bio); | ||
185 | |||
178 | struct dm_target { | 186 | struct 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 | ||