• Joe Thornber's avatar
    dm thin: fix discard corruption · f046f89a
    Joe Thornber authored
    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.
    
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarJoe Thornber <ejt@redhat.com>
    Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
    f046f89a
dm-thin.c 70 KB