|
@@ -2095,6 +2095,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
|
|
* them down to the data device. The thin device's discard
|
|
|
* processing will cause mappings to be removed from the btree.
|
|
|
*/
|
|
|
+ ti->discard_zeroes_data_unsupported = true;
|
|
|
if (pf.discard_enabled && pf.discard_passdown) {
|
|
|
ti->num_discard_bios = 1;
|
|
|
|
|
@@ -2104,7 +2105,6 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
|
|
* thin devices' discard limits consistent).
|
|
|
*/
|
|
|
ti->discards_supported = true;
|
|
|
- ti->discard_zeroes_data_unsupported = true;
|
|
|
}
|
|
|
ti->private = pt;
|
|
|
|
|
@@ -2689,8 +2689,16 @@ static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits)
|
|
|
* They get transferred to the live pool in bind_control_target()
|
|
|
* called from pool_preresume().
|
|
|
*/
|
|
|
- if (!pt->adjusted_pf.discard_enabled)
|
|
|
+ if (!pt->adjusted_pf.discard_enabled) {
|
|
|
+ /*
|
|
|
+ * Must explicitly disallow stacking discard limits otherwise the
|
|
|
+ * block layer will stack them if pool's data device has support.
|
|
|
+ * QUEUE_FLAG_DISCARD wouldn't be set but there is no way for the
|
|
|
+ * user to see that, so make sure to set all discard limits to 0.
|
|
|
+ */
|
|
|
+ limits->discard_granularity = 0;
|
|
|
return;
|
|
|
+ }
|
|
|
|
|
|
disable_passdown_if_not_supported(pt);
|
|
|
|
|
@@ -2826,10 +2834,10 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
|
|
ti->per_bio_data_size = sizeof(struct dm_thin_endio_hook);
|
|
|
|
|
|
/* In case the pool supports discards, pass them on. */
|
|
|
+ ti->discard_zeroes_data_unsupported = true;
|
|
|
if (tc->pool->pf.discard_enabled) {
|
|
|
ti->discards_supported = true;
|
|
|
ti->num_discard_bios = 1;
|
|
|
- ti->discard_zeroes_data_unsupported = true;
|
|
|
/* Discard bios must be split on a block boundary */
|
|
|
ti->split_discard_bios = true;
|
|
|
}
|