dm thin: fix discard corruption
authorJoe Thornber <ejt@redhat.com>
Wed, 20 Mar 2013 17:21:24 +0000 (17:21 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 7 Jun 2014 23:02:05 +0000 (16:02 -0700)
commit87dba703d0d9eb4352506dbd8f8878e3e2ee92f0
tree0c82b8672fee4d91c2df7ff267115fd8f8fff23a
parent5e301eba0a521b3682aec467eb13a94dd6c4027a
dm thin: fix discard corruption

commit f046f89a99ccfd9408b94c653374ff3065c7edb3 upstream.

Fix a bug in dm_btree_remove that could leave leaf values with incorrect
reference counts.  The effect of this was that removal of a shared block
could result in the space maps thinking the block was no longer used.
More concretely, if you have a thin device and a snapshot of it, sending
a discard to a shared region of the thin could corrupt the snapshot.

Thinp uses a 2-level nested btree to store it's mappings.  This first
level is indexed by thin device, and the second level by logical
block.

Often when we're removing an entry in this mapping tree we need to
rebalance nodes, which can involve shadowing them, possibly creating a
copy if the block is shared.  If we do create a copy then children of
that node need to have their reference counts incremented.  In this
way reference counts percolate down the tree as shared trees diverge.

The rebalance functions were incrementing the children at the
appropriate time, but they were always assuming the children were
internal nodes.  This meant the leaf values (in our case packed
block/flags entries) were not being incremented.

Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
[bwh: Backported to 3.2: bump target version numbers from 1.0.1 to 1.0.2]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
[xr: Backported to 3.4: bump target version numbers to 1.1.1]
Signed-off-by: Rui Xiang <rui.xiang@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/md/dm-thin.c
drivers/md/persistent-data/dm-btree-remove.c