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.
Unified · Split
| @@ -1414,6 +1414,33 @@ static bool dm_table_all_devices_attribute(struct dm_table *t, · 1413 unmodified lines | ||
| 1414 | 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 | 1444 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, |
| 1418 | 1445 | struct queue_limits *limits) |
| 1419 | 1446 | { |
| @@ -1445,7 +1472,8 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, · 25 unmodified lines | ||
| 1445 | 1472 | else |
| 1446 | 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 | 1478 | dm_table_set_integrity(t); |
| 1451 | 1479 | |
| @@ -205,6 +205,11 @@ struct dm_target { · 204 unmodified lines | ||
| 205 | 205 | */ |
| 206 | 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 | 213 | /* target specific data */ |
| 209 | 214 | void *private; |
| 210 | 215 | |