lkml.org 
[lkml]   [2021]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.13 068/266] dm space maps: dont reset space map allocation cursor when committing
    Date
    From: Joe Thornber <ejt@redhat.com>

    [ Upstream commit 5faafc77f7de69147d1e818026b9a0cbf036a7b2 ]

    Current commit code resets the place where the search for free blocks
    will begin back to the start of the metadata device. There are a couple
    of repercussions to this:

    - The first allocation after the commit is likely to take longer than
    normal as it searches for a free block in an area that is likely to
    have very few free blocks (if any).

    - Any free blocks it finds will have been recently freed. Reusing them
    means we have fewer old copies of the metadata to aid recovery from
    hardware error.

    Fix these issues by leaving the cursor alone, only resetting when the
    search hits the end of the metadata device.

    Signed-off-by: Joe Thornber <ejt@redhat.com>
    Signed-off-by: Mike Snitzer <snitzer@redhat.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/md/persistent-data/dm-space-map-disk.c | 9 ++++++++-
    drivers/md/persistent-data/dm-space-map-metadata.c | 9 ++++++++-
    2 files changed, 16 insertions(+), 2 deletions(-)

    diff --git a/drivers/md/persistent-data/dm-space-map-disk.c b/drivers/md/persistent-data/dm-space-map-disk.c
    index 61f56909e00b..4f8069bb0481 100644
    --- a/drivers/md/persistent-data/dm-space-map-disk.c
    +++ b/drivers/md/persistent-data/dm-space-map-disk.c
    @@ -171,6 +171,14 @@ static int sm_disk_new_block(struct dm_space_map *sm, dm_block_t *b)
    * Any block we allocate has to be free in both the old and current ll.
    */
    r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, smd->begin, smd->ll.nr_blocks, b);
    + if (r == -ENOSPC) {
    + /*
    + * There's no free block between smd->begin and the end of the metadata device.
    + * We search before smd->begin in case something has been freed.
    + */
    + r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, 0, smd->begin, b);
    + }
    +
    if (r)
    return r;

    @@ -194,7 +202,6 @@ static int sm_disk_commit(struct dm_space_map *sm)
    return r;

    memcpy(&smd->old_ll, &smd->ll, sizeof(smd->old_ll));
    - smd->begin = 0;
    smd->nr_allocated_this_transaction = 0;

    return 0;
    diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c
    index 9e3c64ec2026..da439ac85796 100644
    --- a/drivers/md/persistent-data/dm-space-map-metadata.c
    +++ b/drivers/md/persistent-data/dm-space-map-metadata.c
    @@ -452,6 +452,14 @@ static int sm_metadata_new_block_(struct dm_space_map *sm, dm_block_t *b)
    * Any block we allocate has to be free in both the old and current ll.
    */
    r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, smm->begin, smm->ll.nr_blocks, b);
    + if (r == -ENOSPC) {
    + /*
    + * There's no free block between smm->begin and the end of the metadata device.
    + * We search before smm->begin in case something has been freed.
    + */
    + r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, 0, smm->begin, b);
    + }
    +
    if (r)
    return r;

    @@ -503,7 +511,6 @@ static int sm_metadata_commit(struct dm_space_map *sm)
    return r;

    memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll));
    - smm->begin = 0;
    smm->allocated_this_transaction = 0;

    return 0;
    --
    2.30.2


    \
     
     \ /
      Last update: 2021-07-15 21:26    [W:4.099 / U:0.288 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site