dm array: fix a reference counting bug in shadow_ablock
An old array block could have its reference count decremented below zero when it is being replaced in the btree by a new array block. The fix is to increment the old ablock's reference count just before inserting a new ablock into the btree. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Cc: stable@vger.kernel.org # 3.9+
This commit is contained in:
committed by
Mike Snitzer
parent
5b564d80f8
commit
ed9571f0cf
@@ -317,8 +317,16 @@ static int shadow_ablock(struct dm_array_info *info, dm_block_t *root,
|
|||||||
* The shadow op will often be a noop. Only insert if it really
|
* The shadow op will often be a noop. Only insert if it really
|
||||||
* copied data.
|
* copied data.
|
||||||
*/
|
*/
|
||||||
if (dm_block_location(*block) != b)
|
if (dm_block_location(*block) != b) {
|
||||||
|
/*
|
||||||
|
* dm_tm_shadow_block will have already decremented the old
|
||||||
|
* block, but it is still referenced by the btree. We
|
||||||
|
* increment to stop the insert decrementing it below zero
|
||||||
|
* when overwriting the old value.
|
||||||
|
*/
|
||||||
|
dm_tm_inc(info->btree_info.tm, b);
|
||||||
r = insert_ablock(info, index, *block, root);
|
r = insert_ablock(info, index, *block, root);
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user