diff options
| author | Mike Snitzer <snitzer@redhat.com> | 2012-12-21 15:23:36 -0500 |
|---|---|---|
| committer | Alasdair G Kergon <agk@redhat.com> | 2012-12-21 15:23:36 -0500 |
| commit | d54eaa5a0fde0a202e4e91f200f818edcef15bee (patch) | |
| tree | bb40893166dc8cd1d0f84c8087d021b66774a007 | |
| parent | 9c5091f2eeeffe5eca2ffe8a1bc28d312c8a5083 (diff) | |
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 fa295579003..6be58b69637 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, | |||
| 1414 | return 1; | 1414 | return 1; |
| 1415 | } | 1415 | } |
| 1416 | 1416 | ||
| 1417 | static int device_not_write_same_capable(struct dm_target *ti, struct dm_dev *dev, | ||
| 1418 | sector_t start, sector_t len, void *data) | ||
| 1419 | { | ||
| 1420 | struct request_queue *q = bdev_get_queue(dev->bdev); | ||
| 1421 | |||
| 1422 | return q && !q->limits.max_write_same_sectors; | ||
| 1423 | } | ||
| 1424 | |||
| 1425 | static bool dm_table_supports_write_same(struct dm_table *t) | ||
| 1426 | { | ||
| 1427 | struct dm_target *ti; | ||
| 1428 | unsigned i = 0; | ||
| 1429 | |||
| 1430 | while (i < dm_table_get_num_targets(t)) { | ||
| 1431 | ti = dm_table_get_target(t, i++); | ||
| 1432 | |||
| 1433 | if (!ti->num_write_same_requests) | ||
| 1434 | return false; | ||
| 1435 | |||
| 1436 | if (!ti->type->iterate_devices || | ||
| 1437 | !ti->type->iterate_devices(ti, device_not_write_same_capable, NULL)) | ||
| 1438 | return false; | ||
| 1439 | } | ||
| 1440 | |||
| 1441 | return true; | ||
| 1442 | } | ||
| 1443 | |||
| 1417 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | 1444 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, |
| 1418 | struct queue_limits *limits) | 1445 | struct queue_limits *limits) |
| 1419 | { | 1446 | { |
| @@ -1445,7 +1472,8 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | |||
| 1445 | else | 1472 | else |
| 1446 | queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q); | 1473 | queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q); |
| 1447 | 1474 | ||
| 1448 | q->limits.max_write_same_sectors = 0; | 1475 | if (!dm_table_supports_write_same(t)) |
| 1476 | q->limits.max_write_same_sectors = 0; | ||
| 1449 | 1477 | ||
| 1450 | dm_table_set_integrity(t); | 1478 | dm_table_set_integrity(t); |
| 1451 | 1479 | ||
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 38d27a10aa5..d1f6cd8486f 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h | |||
| @@ -205,6 +205,11 @@ struct dm_target { | |||
| 205 | */ | 205 | */ |
| 206 | unsigned num_discard_requests; | 206 | unsigned num_discard_requests; |
| 207 | 207 | ||
| 208 | /* | ||
| 209 | * The number of WRITE SAME requests that will be submitted to the target. | ||
| 210 | */ | ||
| 211 | unsigned num_write_same_requests; | ||
| 212 | |||
| 208 | /* target specific data */ | 213 | /* target specific data */ |
| 209 | void *private; | 214 | void *private; |
| 210 | 215 | ||
