lkml.org 
[lkml]   [2015]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.19.y-ckt 131/251] dm space map metadata: fix occasional leak of a metadata block on resize
    Date
    3.19.8-ckt4 -stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Joe Thornber <ejt@redhat.com>

    commit 6096d91af0b65a3967139b32d5adbb3647858a26 upstream.

    The metadata space map has a simplified 'bootstrap' mode that is
    operational when extending the space maps. Whilst in this mode it's
    possible for some refcount decrement operations to become queued (eg, as
    a result of shadowing one of the bitmap indexes). These decrements were
    not being applied when switching out of bootstrap mode.

    The effect of this bug was the leaking of a 4k metadata block. This is
    detected by the latest version of thin_check as a non fatal error.

    Signed-off-by: Joe Thornber <ejt@redhat.com>
    Signed-off-by: Mike Snitzer <snitzer@redhat.com>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    drivers/md/persistent-data/dm-space-map-metadata.c | 50 +++++++++++++++-------
    1 file changed, 35 insertions(+), 15 deletions(-)

    diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c
    index e8a9042..5309129 100644
    --- a/drivers/md/persistent-data/dm-space-map-metadata.c
    +++ b/drivers/md/persistent-data/dm-space-map-metadata.c
    @@ -204,6 +204,27 @@ static void in(struct sm_metadata *smm)
    smm->recursion_count++;
    }

    +static int apply_bops(struct sm_metadata *smm)
    +{
    + int r = 0;
    +
    + while (!brb_empty(&smm->uncommitted)) {
    + struct block_op bop;
    +
    + r = brb_pop(&smm->uncommitted, &bop);
    + if (r) {
    + DMERR("bug in bop ring buffer");
    + break;
    + }
    +
    + r = commit_bop(smm, &bop);
    + if (r)
    + break;
    + }
    +
    + return r;
    +}
    +
    static int out(struct sm_metadata *smm)
    {
    int r = 0;
    @@ -216,21 +237,8 @@ static int out(struct sm_metadata *smm)
    return -ENOMEM;
    }

    - if (smm->recursion_count == 1) {
    - while (!brb_empty(&smm->uncommitted)) {
    - struct block_op bop;
    -
    - r = brb_pop(&smm->uncommitted, &bop);
    - if (r) {
    - DMERR("bug in bop ring buffer");
    - break;
    - }
    -
    - r = commit_bop(smm, &bop);
    - if (r)
    - break;
    - }
    - }
    + if (smm->recursion_count == 1)
    + apply_bops(smm);

    smm->recursion_count--;

    @@ -704,6 +712,12 @@ static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
    }
    old_len = smm->begin;

    + r = apply_bops(smm);
    + if (r) {
    + DMERR("%s: apply_bops failed", __func__);
    + goto out;
    + }
    +
    r = sm_ll_commit(&smm->ll);
    if (r)
    goto out;
    @@ -773,6 +787,12 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
    if (r)
    return r;

    + r = apply_bops(smm);
    + if (r) {
    + DMERR("%s: apply_bops failed", __func__);
    + return r;
    + }
    +
    return sm_metadata_commit(sm);
    }

    --
    1.9.1


    \
     
     \ /
      Last update: 2015-07-16 04:21    [W:3.069 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site