diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-21 20:08:06 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-21 20:08:06 -0500 |
| commit | b49249d10324d0fd6fb29725c2807dfd80d0edbc (patch) | |
| tree | 9a8fa724e6c9f9283530979c6e32a311c74999d5 | |
| parent | 10532b560bacf23766f9c7dc09778b31b198ff45 (diff) | |
| parent | 45e621d45e24ffc4cb2b2935e8438987b860063a (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
...
30 files changed, 522 insertions, 443 deletions
diff --git a/drivers/md/dm-bio-prison.c b/drivers/md/dm-bio-prison.c index e4e841567459..aefb78e3cbf9 100644 --- a/drivers/md/dm-bio-prison.c +++ b/drivers/md/dm-bio-prison.c | |||
| @@ -208,31 +208,6 @@ void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios) | |||
| 208 | EXPORT_SYMBOL_GPL(dm_cell_release); | 208 | EXPORT_SYMBOL_GPL(dm_cell_release); |
| 209 | 209 | ||
| 210 | /* | 210 | /* |
| 211 | * There are a couple of places where we put a bio into a cell briefly | ||
| 212 | * before taking it out again. In these situations we know that no other | ||
| 213 | * bio may be in the cell. This function releases the cell, and also does | ||
| 214 | * a sanity check. | ||
| 215 | */ | ||
| 216 | static void __cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio) | ||
| 217 | { | ||
| 218 | BUG_ON(cell->holder != bio); | ||
| 219 | BUG_ON(!bio_list_empty(&cell->bios)); | ||
| 220 | |||
| 221 | __cell_release(cell, NULL); | ||
| 222 | } | ||
| 223 | |||
| 224 | void dm_cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio) | ||
| 225 | { | ||
| 226 | unsigned long flags; | ||
| 227 | struct dm_bio_prison *prison = cell->prison; | ||
| 228 | |||
| 229 | spin_lock_irqsave(&prison->lock, flags); | ||
| 230 | __cell_release_singleton(cell, bio); | ||
| 231 | spin_unlock_irqrestore(&prison->lock, flags); | ||
| 232 | } | ||
| 233 | EXPORT_SYMBOL_GPL(dm_cell_release_singleton); | ||
| 234 | |||
| 235 | /* | ||
| 236 | * Sometimes we don't want the holder, just the additional bios. | 211 | * Sometimes we don't want the holder, just the additional bios. |
| 237 | */ | 212 | */ |
| 238 | static void __cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates) | 213 | static void __cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates) |
diff --git a/drivers/md/dm-bio-prison.h b/drivers/md/dm-bio-prison.h index 4e0ac376700a..53d1a7a84e2f 100644 --- a/drivers/md/dm-bio-prison.h +++ b/drivers/md/dm-bio-prison.h | |||
| @@ -44,7 +44,6 @@ int dm_bio_detain(struct dm_bio_prison *prison, struct dm_cell_key *key, | |||
| 44 | struct bio *inmate, struct dm_bio_prison_cell **ref); | 44 | struct bio *inmate, struct dm_bio_prison_cell **ref); |
| 45 | 45 | ||
| 46 | void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios); | 46 | void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios); |
| 47 | void dm_cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio); // FIXME: bio arg not needed | ||
| 48 | void dm_cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates); | 47 | void dm_cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates); |
| 49 | void dm_cell_error(struct dm_bio_prison_cell *cell); | 48 | void dm_cell_error(struct dm_bio_prison_cell *cell); |
| 50 | 49 | ||
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index bbf459bca61d..f7369f9d8595 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
| @@ -1689,8 +1689,7 @@ bad: | |||
| 1689 | return ret; | 1689 | return ret; |
| 1690 | } | 1690 | } |
| 1691 | 1691 | ||
| 1692 | static int crypt_map(struct dm_target *ti, struct bio *bio, | 1692 | static int crypt_map(struct dm_target *ti, struct bio *bio) |
| 1693 | union map_info *map_context) | ||
| 1694 | { | 1693 | { |
| 1695 | struct dm_crypt_io *io; | 1694 | struct dm_crypt_io *io; |
| 1696 | struct crypt_config *cc = ti->private; | 1695 | struct crypt_config *cc = ti->private; |
| @@ -1846,7 +1845,7 @@ static int crypt_iterate_devices(struct dm_target *ti, | |||
| 1846 | 1845 | ||
| 1847 | static struct target_type crypt_target = { | 1846 | static struct target_type crypt_target = { |
| 1848 | .name = "crypt", | 1847 | .name = "crypt", |
| 1849 | .version = {1, 11, 0}, | 1848 | .version = {1, 12, 0}, |
| 1850 | .module = THIS_MODULE, | 1849 | .module = THIS_MODULE, |
| 1851 | .ctr = crypt_ctr, | 1850 | .ctr = crypt_ctr, |
| 1852 | .dtr = crypt_dtr, | 1851 | .dtr = crypt_dtr, |
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c index f53846f9ab50..cc1bd048acb2 100644 --- a/drivers/md/dm-delay.c +++ b/drivers/md/dm-delay.c | |||
| @@ -274,8 +274,7 @@ static void delay_resume(struct dm_target *ti) | |||
| 274 | atomic_set(&dc->may_delay, 1); | 274 | atomic_set(&dc->may_delay, 1); |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | static int delay_map(struct dm_target *ti, struct bio *bio, | 277 | static int delay_map(struct dm_target *ti, struct bio *bio) |
| 278 | union map_info *map_context) | ||
| 279 | { | 278 | { |
| 280 | struct delay_c *dc = ti->private; | 279 | struct delay_c *dc = ti->private; |
| 281 | 280 | ||
| @@ -338,7 +337,7 @@ out: | |||
| 338 | 337 | ||
| 339 | static struct target_type delay_target = { | 338 | static struct target_type delay_target = { |
| 340 | .name = "delay", | 339 | .name = "delay", |
| 341 | .version = {1, 1, 0}, | 340 | .version = {1, 2, 0}, |
| 342 | .module = THIS_MODULE, | 341 | .module = THIS_MODULE, |
| 343 | .ctr = delay_ctr, | 342 | .ctr = delay_ctr, |
| 344 | .dtr = delay_dtr, | 343 | .dtr = delay_dtr, |
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index cc15543a6ad7..9721f2ffb1a2 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c | |||
| @@ -39,6 +39,10 @@ enum feature_flag_bits { | |||
| 39 | DROP_WRITES | 39 | DROP_WRITES |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | struct per_bio_data { | ||
| 43 | bool bio_submitted; | ||
| 44 | }; | ||
| 45 | |||
| 42 | static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, | 46 | static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, |
| 43 | struct dm_target *ti) | 47 | struct dm_target *ti) |
| 44 | { | 48 | { |
| @@ -214,6 +218,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 214 | 218 | ||
| 215 | ti->num_flush_requests = 1; | 219 | ti->num_flush_requests = 1; |
| 216 | ti->num_discard_requests = 1; | 220 | ti->num_discard_requests = 1; |
| 221 | ti->per_bio_data_size = sizeof(struct per_bio_data); | ||
| 217 | ti->private = fc; | 222 | ti->private = fc; |
| 218 | return 0; | 223 | return 0; |
| 219 | 224 | ||
| @@ -265,11 +270,12 @@ static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc) | |||
| 265 | } | 270 | } |
| 266 | } | 271 | } |
| 267 | 272 | ||
| 268 | static int flakey_map(struct dm_target *ti, struct bio *bio, | 273 | static int flakey_map(struct dm_target *ti, struct bio *bio) |
| 269 | union map_info *map_context) | ||
| 270 | { | 274 | { |
| 271 | struct flakey_c *fc = ti->private; | 275 | struct flakey_c *fc = ti->private; |
| 272 | unsigned elapsed; | 276 | unsigned elapsed; |
| 277 | struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); | ||
| 278 | pb->bio_submitted = false; | ||
| 273 | 279 | ||
| 274 | /* Are we alive ? */ | 280 | /* Are we alive ? */ |
| 275 | elapsed = (jiffies - fc->start_time) / HZ; | 281 | elapsed = (jiffies - fc->start_time) / HZ; |
| @@ -277,7 +283,7 @@ static int flakey_map(struct dm_target *ti, struct bio *bio, | |||
| 277 | |||
