diff options
author | Mike Snitzer <snitzer@redhat.com> | 2012-12-21 21:23:36 +0100 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2012-12-21 21:23:36 +0100 |
commit | d54eaa5a0fde0a202e4e91f200f818edcef15bee (patch) | |
tree | bb40893166dc8cd1d0f84c8087d021b66774a007 | |
parent | dm ioctl: use kmalloc if possible (diff) | |
download | linux-d54eaa5a0fde0a202e4e91f200f818edcef15bee.tar.xz linux-d54eaa5a0fde0a202e4e91f200f818edcef15bee.zip |
dm: prepare to support WRITE SAME
Allow targets to opt in to WRITE SAME support by setting
'num_write_same_requests' in the dm_target structure.
A dm device will only advertise WRITE SAME support if all its
targets and all its underlying devices support it.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
-rw-r--r-- | drivers/md/dm-table.c | 30 | ||||
-rw-r--r-- | include/linux/device-mapper.h | 5 |
2 files changed, 34 insertions, 1 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index fa2955790031..6be58b696377 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1414,6 +1414,33 @@ static bool dm_table_all_devices_attribute(struct dm_table *t, return 1; } +static int device_not_write_same_capable(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) +{ + struct request_queue *q = bdev_get_queue(dev->bdev); + + return q && !q->limits.max_write_same_sectors; +} + +static bool dm_table_supports_write_same(struct dm_table *t) +{ + struct dm_target *ti; + unsigned i = 0; + + while (i < dm_table_get_num_targets(t)) { + ti = dm_table_get_target(t, i++); + + if (!ti->num_write_same_requests) + return false; + + if (!ti->type->iterate_devices || + !ti->type->iterate_devices(ti, device_not_write_same_capable, NULL)) + return false; + } + + return true; +} + void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, struct queue_limits *limits) { @@ -1445,7 +1472,8 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, else queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q); - q->limits.max_write_same_sectors = 0; + if (!dm_table_supports_write_same(t)) + q->limits.max_write_same_sectors = 0; dm_table_set_integrity(t); diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 38d27a10aa5d..d1f6cd8486f2 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -205,6 +205,11 @@ struct dm_target { */ unsigned num_discard_requests; + /* + * The number of WRITE SAME requests that will be submitted to the target. + */ + unsigned num_write_same_requests; + /* target specific data */ void *private; |