lkml.org 
[lkml]   [2017]   [Mar]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.10 060/167] dm raid: fix data corruption on reshape request
    Date
    4.10-stable review patch.  If anyone has any objections, please let me know.

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

    From: Heinz Mauelshagen <heinzm@redhat.com>

    commit d36a19541fe8f392778ac137d60f9be8dfdd8f9d upstream.

    The lvm2 sequence to manage dm-raid constructor flags that trigger a
    rebuild or a reshape is defined as:

    1) load table with flags (e.g. rebuild/delta_disks/data_offset)
    2) clear out the flags in lvm2 metadata
    3) store the lvm2 metadata, reload the table to reset the flags
    previously established during the initial load (1) -- in order to
    prevent repeatedly requesting a rebuild or a reshape on activation

    Currently, loading an inactive table with rebuild/reshape flags
    specified will cause dm-raid to rebuild/reshape on resume and thus start
    updating the raid metadata (about the progress). When the second table
    reload, to reset the flags, occurs the constructor accesses the volatile
    progress state kept in the raid superblocks. Because the active mapping
    is still processing the rebuild/reshape, that position will be stale by
    the time the device is resumed.

    In the reshape case, this causes data corruption by processing already
    reshaped stripes again. In the rebuild case, it does _not_ cause data
    corruption but instead involves superfluous rebuilds.

    Fix by keeping the raid set frozen during the first resume and then
    allow the rebuild/reshape during the second resume.

    Fixes: 9dbd1aa3a ("dm raid: add reshaping support to the target")
    Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com>
    Signed-off-by: Mike Snitzer <snitzer@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/md/dm-raid.c | 12 +++++++++++-
    1 file changed, 11 insertions(+), 1 deletion(-)

    --- a/drivers/md/dm-raid.c
    +++ b/drivers/md/dm-raid.c
    @@ -3626,6 +3626,8 @@ static int raid_preresume(struct dm_targ
    return r;
    }

    +#define RESUME_STAY_FROZEN_FLAGS (CTR_FLAG_DELTA_DISKS | CTR_FLAG_DATA_OFFSET)
    +
    static void raid_resume(struct dm_target *ti)
    {
    struct raid_set *rs = ti->private;
    @@ -3643,7 +3645,15 @@ static void raid_resume(struct dm_target
    mddev->ro = 0;
    mddev->in_sync = 0;

    - clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
    + /*
    + * Keep the RAID set frozen if reshape/rebuild flags are set.
    + * The RAID set is unfrozen once the next table load/resume,
    + * which clears the reshape/rebuild flags, occurs.
    + * This ensures that the constructor for the inactive table
    + * retrieves an up-to-date reshape_position.
    + */
    + if (!(rs->ctr_flags & RESUME_STAY_FROZEN_FLAGS))
    + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);

    if (mddev->suspended)
    mddev_resume(mddev);

    \
     
     \ /
      Last update: 2017-03-10 11:03    [W:4.116 / U:0.504 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site