Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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+

authored by

Joe Thornber and committed by
Mike Snitzer
ed9571f0 5b564d80

+9 -1
+9 -1
drivers/md/persistent-data/dm-array.c
··· 317 317 * The shadow op will often be a noop. Only insert if it really 318 318 * copied data. 319 319 */ 320 - if (dm_block_location(*block) != b) 320 + if (dm_block_location(*block) != b) { 321 + /* 322 + * dm_tm_shadow_block will have already decremented the old 323 + * block, but it is still referenced by the btree. We 324 + * increment to stop the insert decrementing it below zero 325 + * when overwriting the old value. 326 + */ 327 + dm_tm_inc(info->btree_info.tm, b); 321 328 r = insert_ablock(info, index, *block, root); 329 + } 322 330 323 331 return r; 324 332 }