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 /drivers/md/dm-table.c | |
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
...
Diffstat (limited to 'drivers/md/dm-table.c')
-rw-r--r-- | drivers/md/dm-table.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 100368eb7991..daf25d0890b3 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -967,13 +967,22 @@ bool dm_table_request_based(struct dm_table *t) | |||
967 | int dm_table_alloc_md_mempools(struct dm_table *t) | 967 | int dm_table_alloc_md_mempools(struct dm_table *t) |
968 | { | 968 | { |
969 | unsigned type = dm_table_get_type(t); | 969 | unsigned type = dm_table_get_type(t); |
970 | unsigned per_bio_data_size = 0; | ||
971 | struct dm_target *tgt; | ||
972 | unsigned i; | ||
970 | 973 | ||
971 | if (unlikely(type == DM_TYPE_NONE)) { | 974 | if (unlikely(type == DM_TYPE_NONE)) { |
972 | DMWARN("no table type is set, can't allocate mempools"); | 975 | DMWARN("no table type is set, can't allocate mempools"); |
973 | return -EINVAL; | 976 | return -EINVAL; |
974 | } | 977 | } |
975 | 978 | ||
976 | t->mempools = dm_alloc_md_mempools(type, t->integrity_supported); | 979 | if (type == DM_TYPE_BIO_BASED) |
980 | for (i = 0; i < t->num_targets; i++) { | ||
981 | tgt = t->targets + i; | ||
982 | per_bio_data_size = max(per_bio_data_size, tgt->per_bio_data_size); | ||
983 | } | ||
984 | |||
985 | t->mempools = dm_alloc_md_mempools(type, t->integrity_supported, per_bio_data_size); | ||
977 | if (!t->mempools) | 986 | if (!t->mempools) |
978 | return -ENOMEM; | 987 | return -ENOMEM; |
979 | 988 | ||
@@ -1414,6 +1423,33 @@ static bool dm_table_all_devices_attribute(struct dm_table *t, | |||
1414 | return 1; | 1423 | return 1; |
1415 | } | 1424 | } |
1416 | 1425 | ||
1426 | static int device_not_write_same_capable(struct dm_target *ti, struct dm_dev *dev, | ||
1427 | sector_t start, sector_t len, void *data) | ||
1428 | { | ||
1429 | struct request_queue *q = bdev_get_queue(dev->bdev); | ||
1430 | |||
1431 | return q && !q->limits.max_write_same_sectors; | ||
1432 | } | ||
1433 | |||
1434 | static bool dm_table_supports_write_same(struct dm_table *t) | ||
1435 | { | ||
1436 | struct dm_target *ti; | ||
1437 | unsigned i = 0; | ||
1438 | |||
1439 | while (i < dm_table_get_num_targets(t)) { | ||
1440 | ti = dm_table_get_target(t, i++); | ||
1441 | |||
1442 | if (!ti->num_write_same_requests) | ||
1443 | return false; | ||
1444 | |||
1445 | if (!ti->type->iterate_devices || | ||
1446 | !ti->type->iterate_devices(ti, device_not_write_same_capable, NULL)) | ||
1447 | return false; | ||
1448 | } | ||
1449 | |||
1450 | return true; | ||
1451 | } | ||
1452 | |||
1417 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | 1453 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, |
1418 | struct queue_limits *limits) | 1454 | struct queue_limits *limits) |
1419 | { | 1455 | { |
@@ -1445,6 +1481,9 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | |||
1445 | else | 1481 | else |
1446 | queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q); | 1482 | queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q); |
1447 | 1483 | ||
1484 | if (!dm_table_supports_write_same(t)) | ||
1485 | q->limits.max_write_same_sectors = 0; | ||
1486 | |||
1448 | dm_table_set_integrity(t); | 1487 | dm_table_set_integrity(t); |
1449 | 1488 | ||
1450 | /* | 1489 | /* |