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 ...
This commit is contained in:
@@ -23,7 +23,6 @@ typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE } status_type_t;
|
||||
union map_info {
|
||||
void *ptr;
|
||||
unsigned long long ll;
|
||||
unsigned target_request_nr;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -46,8 +45,7 @@ typedef void (*dm_dtr_fn) (struct dm_target *ti);
|
||||
* = 1: simple remap complete
|
||||
* = 2: The target wants to push back the io
|
||||
*/
|
||||
typedef int (*dm_map_fn) (struct dm_target *ti, struct bio *bio,
|
||||
union map_info *map_context);
|
||||
typedef int (*dm_map_fn) (struct dm_target *ti, struct bio *bio);
|
||||
typedef int (*dm_map_request_fn) (struct dm_target *ti, struct request *clone,
|
||||
union map_info *map_context);
|
||||
|
||||
@@ -60,8 +58,7 @@ typedef int (*dm_map_request_fn) (struct dm_target *ti, struct request *clone,
|
||||
* 2 : The target wants to push back the io
|
||||
*/
|
||||
typedef int (*dm_endio_fn) (struct dm_target *ti,
|
||||
struct bio *bio, int error,
|
||||
union map_info *map_context);
|
||||
struct bio *bio, int error);
|
||||
typedef int (*dm_request_endio_fn) (struct dm_target *ti,
|
||||
struct request *clone, int error,
|
||||
union map_info *map_context);
|
||||
@@ -193,18 +190,30 @@ struct dm_target {
|
||||
* A number of zero-length barrier requests that will be submitted
|
||||
* to the target for the purpose of flushing cache.
|
||||
*
|
||||
* The request number will be placed in union map_info->target_request_nr.
|
||||
* The request number can be accessed with dm_bio_get_target_request_nr.
|
||||
* It is a responsibility of the target driver to remap these requests
|
||||
* to the real underlying devices.
|
||||
*/
|
||||
unsigned num_flush_requests;
|
||||
|
||||
/*
|
||||
* The number of discard requests that will be submitted to the
|
||||
* target. map_info->request_nr is used just like num_flush_requests.
|
||||
* The number of discard requests that will be submitted to the target.
|
||||
* The request number can be accessed with dm_bio_get_target_request_nr.
|
||||
*/
|
||||
unsigned num_discard_requests;
|
||||
|
||||
/*
|
||||
* The number of WRITE SAME requests that will be submitted to the target.
|
||||
* The request number can be accessed with dm_bio_get_target_request_nr.
|
||||
*/
|
||||
unsigned num_write_same_requests;
|
||||
|
||||
/*
|
||||
* The minimum number of extra bytes allocated in each bio for the
|
||||
* target to use. dm_per_bio_data returns the data location.
|
||||
*/
|
||||
unsigned per_bio_data_size;
|
||||
|
||||
/* target specific data */
|
||||
void *private;
|
||||
|
||||
@@ -241,6 +250,36 @@ struct dm_target_callbacks {
|
||||
int (*congested_fn) (struct dm_target_callbacks *, int);
|
||||
};
|
||||
|
||||
/*
|
||||
* For bio-based dm.
|
||||
* One of these is allocated for each bio.
|
||||
* This structure shouldn't be touched directly by target drivers.
|
||||
* It is here so that we can inline dm_per_bio_data and
|
||||
* dm_bio_from_per_bio_data
|
||||
*/
|
||||
struct dm_target_io {
|
||||
struct dm_io *io;
|
||||
struct dm_target *ti;
|
||||
union map_info info;
|
||||
unsigned target_request_nr;
|
||||
struct bio clone;
|
||||
};
|
||||
|
||||
static inline void *dm_per_bio_data(struct bio *bio, size_t data_size)
|
||||
{
|
||||
return (char *)bio - offsetof(struct dm_target_io, clone) - data_size;
|
||||
}
|
||||
|
||||
static inline struct bio *dm_bio_from_per_bio_data(void *data, size_t data_size)
|
||||
{
|
||||
return (struct bio *)((char *)data + data_size + offsetof(struct dm_target_io, clone));
|
||||
}
|
||||
|
||||
static inline unsigned dm_bio_get_target_request_nr(const struct bio *bio)
|
||||
{
|
||||
return container_of(bio, struct dm_target_io, clone)->target_request_nr;
|
||||
}
|
||||
|
||||
int dm_register_target(struct target_type *t);
|
||||
void dm_unregister_target(struct target_type *t);
|
||||
|
||||
|
Reference in New Issue
Block a user