aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-21 20:08:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-21 20:08:06 -0500
commitb49249d10324d0fd6fb29725c2807dfd80d0edbc (patch)
tree9a8fa724e6c9f9283530979c6e32a311c74999d5 /include/linux
parent10532b560bacf23766f9c7dc09778b31b198ff45 (diff)
parent45e621d45e24ffc4cb2b2935e8438987b860063a (diff)
Merge tag 'dm-3.8-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm
Pull dm update from Alasdair G Kergon: "Miscellaneous device-mapper fixes, cleanups and performance improvements. Of particular note: - Disable broken WRITE SAME support in all targets except linear and striped. Use it when kcopyd is zeroing blocks. - Remove several mempools from targets by moving the data into the bio's new front_pad area(which dm calls 'per_bio_data'). - Fix a race in thin provisioning if discards are misused. - Prevent userspace from interfering with the ioctl parameters and use kmalloc for the data buffer if it's small instead of vmalloc. - Throttle some annoying error messages when I/O fails." * tag 'dm-3.8-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm: (36 commits) dm stripe: add WRITE SAME support dm: remove map_info dm snapshot: do not use map_context dm thin: dont use map_context dm raid1: dont use map_context dm flakey: dont use map_context dm raid1: rename read_record to bio_record dm: move target request nr to dm_target_io dm snapshot: use per_bio_data dm verity: use per_bio_data dm raid1: use per_bio_data dm: introduce per_bio_data dm kcopyd: add WRITE SAME support to dm_kcopyd_zero dm linear: add WRITE SAME support dm: add WRITE SAME support dm: prepare to support WRITE SAME dm ioctl: use kmalloc if possible dm ioctl: remove PF_MEMALLOC dm persistent data: improve improve space map block alloc failure message dm thin: use DMERR_LIMIT for errors ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/device-mapper.h55
1 files changed, 47 insertions, 8 deletions
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 38d27a10aa5..bf6afa2fc43 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -23,7 +23,6 @@ typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE } status_type_t;
23union map_info { 23union map_info {
24 void *ptr; 24 void *ptr;
25 unsigned long long ll; 25 unsigned long long ll;
26 unsigned target_request_nr;
27}; 26};
28 27
29/* 28/*
@@ -46,8 +45,7 @@ typedef void (*dm_dtr_fn) (struct dm_target *ti);
46 * = 1: simple remap complete 45 * = 1: simple remap complete
47 * = 2: The target wants to push back the io 46 * = 2: The target wants to push back the io
48 */ 47 */
49typedef int (*dm_map_fn) (struct dm_target *ti, struct bio *bio, 48typedef int (*dm_map_fn) (struct dm_target *ti, struct bio *bio);
50 union map_info *map_context);
51typedef int (*dm_map_request_fn) (struct dm_target *ti, struct request *clone, 49typedef int (*dm_map_request_fn) (struct dm_target *ti, struct request *clone,
52 union map_info *map_context); 50 union map_info *map_context);
53 51
@@ -60,8 +58,7 @@ typedef int (*dm_map_request_fn) (struct dm_target *ti, struct request *clone,
60 * 2 : The target wants to push back the io 58 * 2 : The target wants to push back the io
61 */ 59 */
62typedef int (*dm_endio_fn) (struct dm_target *ti, 60typedef int (*dm_endio_fn) (struct dm_target *ti,
63 struct bio *bio, int error, 61 struct bio *bio, int error);
64 union map_info *map_context);
65typedef int (*dm_request_endio_fn) (struct dm_target *ti, 62typedef int (*dm_request_endio_fn) (struct dm_target *ti,
66 struct request *clone, int error, 63 struct request *clone, int error,
67 union map_info *map_context); 64 union map_info *map_context);
@@ -193,18 +190,30 @@ struct dm_target {
193 * A number of zero-length barrier requests that will be submitted 190 * A number of zero-length barrier requests that will be submitted
194 * to the target for the purpose of flushing cache. 191 * to the target for the purpose of flushing cache.
195 * 192 *
196 * The request number will be placed in union map_info->target_request_nr. 193 * The request number can be accessed with dm_bio_get_target_request_nr.
197 * It is a responsibility of the target driver to remap these requests 194 * It is a responsibility of the target driver to remap these requests
198 * to the real underlying devices. 195 * to the real underlying devices.
199 */ 196 */
200 unsigned num_flush_requests; 197 unsigned num_flush_requests;
201 198
202 /* 199 /*
203 * The number of discard requests that will be submitted to the 200 * The number of discard requests that will be submitted to the target.
204 * target. map_info->request_nr is used just like num_flush_requests. 201 * The request number can be accessed with dm_bio_get_target_request_nr.
205 */ 202 */
206 unsigned num_discard_requests; 203 unsigned num_discard_requests;
207 204
205 /*
206 * The number of WRITE SAME requests that will be submitted to the target.
207 * The request number can be accessed with dm_bio_get_target_request_nr.
208 */
209 unsigned num_write_same_requests;
210
211 /*
212 * The minimum number of extra bytes allocated in each bio for the
213 * target to use. dm_per_bio_data returns the data location.
214 */
215 unsigned per_bio_data_size;
216
208 /* target specific data */ 217 /* target specific data */
209 void *private; 218 void *private;
210 219
@@ -241,6 +250,36 @@ struct dm_target_callbacks {
241 int (*congested_fn) (struct dm_target_callbacks *, int); 250 int (*congested_fn) (struct dm_target_callbacks *, int);
242}; 251};
243 252
253/*
254 * For bio-based dm.
255 * One of these is allocated for each bio.
256 * This structure shouldn't be touched directly by target drivers.
257 * It is here so that we can inline dm_per_bio_data and
258 * dm_bio_from_per_bio_data
259 */
260struct dm_target_io {
261 struct dm_io *io;
262 struct dm_target *ti;
263 union map_info info;
264 unsigned target_request_nr;
265 struct bio clone;
266};
267
268static inline void *dm_per_bio_data(struct bio *bio, size_t data_size)
269{
270 return (char *)bio - offsetof(struct dm_target_io, clone) - data_size;
271}
272
273static inline struct bio *dm_bio_from_per_bio_data(void *data, size_t data_size)
274{
275 return (struct bio *)((char *)data + data_size + offsetof(struct dm_target_io, clone));
276}
277
278static inline unsigned dm_bio_get_target_request_nr(const struct bio *bio)
279{
280 return container_of(bio, struct dm_target_io, clone)->target_request_nr;
281}
282
244int dm_register_target(struct target_type *t); 283int dm_register_target(struct target_type *t);
245void dm_unregister_target(struct target_type *t); 284void dm_unregister_target(struct target_type *t);
246 285