dm thin: fix passdown_double_checking_shared_status()
Commit00a0ea33b4
("dm thin: do not queue freed thin mapping for next stage processing") changed process_prepared_discard_passdown_pt1() to increment all the blocks being discarded until after the passdown had completed to avoid them being prematurely reused. IO issued to a thin device that breaks sharing with a snapshot, followed by a discard issued to snapshot(s) that previously shared the block(s), results in passdown_double_checking_shared_status() being called to iterate through the blocks double checking their reference count is zero and issuing the passdown if so. So a side effect of commit00a0ea33b4
is passdown_double_checking_shared_status() was broken. Fix this by checking if the block reference count is greater than 1. Also, rename dm_pool_block_is_used() to dm_pool_block_is_shared(). Fixes:00a0ea33b4
("dm thin: do not queue freed thin mapping for next stage processing") Cc: stable@vger.kernel.org # 4.9+ Reported-by: ryan.p.norwood@gmail.com Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:

committed by
Mike Snitzer

parent
1856b9f7bc
commit
d445bd9cec
@@ -1048,7 +1048,7 @@ static void passdown_double_checking_shared_status(struct dm_thin_new_mapping *m
|
||||
* passdown we have to check that these blocks are now unused.
|
||||
*/
|
||||
int r = 0;
|
||||
bool used = true;
|
||||
bool shared = true;
|
||||
struct thin_c *tc = m->tc;
|
||||
struct pool *pool = tc->pool;
|
||||
dm_block_t b = m->data_block, e, end = m->data_block + m->virt_end - m->virt_begin;
|
||||
@@ -1058,11 +1058,11 @@ static void passdown_double_checking_shared_status(struct dm_thin_new_mapping *m
|
||||
while (b != end) {
|
||||
/* find start of unmapped run */
|
||||
for (; b < end; b++) {
|
||||
r = dm_pool_block_is_used(pool->pmd, b, &used);
|
||||
r = dm_pool_block_is_shared(pool->pmd, b, &shared);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
if (!used)
|
||||
if (!shared)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1071,11 +1071,11 @@ static void passdown_double_checking_shared_status(struct dm_thin_new_mapping *m
|
||||
|
||||
/* find end of run */
|
||||
for (e = b + 1; e != end; e++) {
|
||||
r = dm_pool_block_is_used(pool->pmd, e, &used);
|
||||
r = dm_pool_block_is_shared(pool->pmd, e, &shared);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
if (used)
|
||||
if (shared)
|
||||
break;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user