|
@@ -512,6 +512,7 @@ struct dm_thin_new_mapping {
|
|
unsigned quiesced:1;
|
|
unsigned quiesced:1;
|
|
unsigned prepared:1;
|
|
unsigned prepared:1;
|
|
unsigned pass_discard:1;
|
|
unsigned pass_discard:1;
|
|
|
|
+ unsigned definitely_not_shared:1;
|
|
|
|
|
|
struct thin_c *tc;
|
|
struct thin_c *tc;
|
|
dm_block_t virt_block;
|
|
dm_block_t virt_block;
|
|
@@ -683,7 +684,15 @@ static void process_prepared_discard_passdown(struct dm_thin_new_mapping *m)
|
|
cell_defer_no_holder(tc, m->cell2);
|
|
cell_defer_no_holder(tc, m->cell2);
|
|
|
|
|
|
if (m->pass_discard)
|
|
if (m->pass_discard)
|
|
- remap_and_issue(tc, m->bio, m->data_block);
|
|
|
|
|
|
+ if (m->definitely_not_shared)
|
|
|
|
+ remap_and_issue(tc, m->bio, m->data_block);
|
|
|
|
+ else {
|
|
|
|
+ bool used = false;
|
|
|
|
+ if (dm_pool_block_is_used(tc->pool->pmd, m->data_block, &used) || used)
|
|
|
|
+ bio_endio(m->bio, 0);
|
|
|
|
+ else
|
|
|
|
+ remap_and_issue(tc, m->bio, m->data_block);
|
|
|
|
+ }
|
|
else
|
|
else
|
|
bio_endio(m->bio, 0);
|
|
bio_endio(m->bio, 0);
|
|
|
|
|
|
@@ -1036,7 +1045,8 @@ static void process_discard(struct thin_c *tc, struct bio *bio)
|
|
*/
|
|
*/
|
|
m = get_next_mapping(pool);
|
|
m = get_next_mapping(pool);
|
|
m->tc = tc;
|
|
m->tc = tc;
|
|
- m->pass_discard = (!lookup_result.shared) && pool->pf.discard_passdown;
|
|
|
|
|
|
+ m->pass_discard = pool->pf.discard_passdown;
|
|
|
|
+ m->definitely_not_shared = !lookup_result.shared;
|
|
m->virt_block = block;
|
|
m->virt_block = block;
|
|
m->data_block = lookup_result.block;
|
|
m->data_block = lookup_result.block;
|
|
m->cell = cell;
|
|
m->cell = cell;
|