diff options
| -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,  	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 38d27a10aa5..d1f6cd8486f 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;  |