[lkml]   [2011]   [Jan]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[23/49] md: fix bug with re-adding of partially recovered device.
    2.6.32-longterm review patch.  If anyone has any objections, please let us know.


    From: NeilBrown <>

    commit 1a855a0606653d2d82506281e2c686bacb4b2f45 upstream.

    With v0.90 metadata, a hot-spare does not become a full member of the
    array until recovery is complete. So if we re-add such a device to
    the array, we know that all of it is as up-to-date as the event count
    would suggest, and so it a bitmap-based recovery is possible.

    However with v1.x metadata, the hot-spare immediately becomes a full
    member of the array, but it record how much of the device has been
    recovered. If the array is stopped and re-assembled recovery starts
    from this point.

    When such a device is hot-added to an array we currently lose the 'how
    much is recovered' information and incorrectly included it as a full
    in-sync member (after bitmap-based fixup).
    This is wrong and unsafe and could corrupt data.

    So be more careful about setting saved_raid_disk - which is what
    guides the re-adding of devices back into an array.
    The new code matches the code in slot_store which does a similar
    thing, which is encouraging.

    This is suitable for any -stable kernel.

    Reported-by: "Dailey, Nate" <>
    Signed-off-by: NeilBrown <>
    Signed-off-by: Greg Kroah-Hartman <>

    drivers/md/md.c | 7 +++++--
    1 file changed, 5 insertions(+), 2 deletions(-)

    --- a/drivers/md/md.c
    +++ b/drivers/md/md.c
    @@ -4802,7 +4802,7 @@ static int add_new_disk(mddev_t * mddev,
    return PTR_ERR(rdev);
    - /* set save_raid_disk if appropriate */
    + /* set saved_raid_disk if appropriate */
    if (!mddev->persistent) {
    if (info->state & (1<<MD_DISK_SYNC) &&
    info->raid_disk < mddev->raid_disks)
    @@ -4812,7 +4812,10 @@ static int add_new_disk(mddev_t * mddev,
    } else
    validate_super(mddev, rdev);
    - rdev->saved_raid_disk = rdev->raid_disk;
    + if (test_bit(In_sync, &rdev->flags))
    + rdev->saved_raid_disk = rdev->raid_disk;
    + else
    + rdev->saved_raid_disk = -1;

    clear_bit(In_sync, &rdev->flags); /* just to be sure */
    if (info->state & (1<<MD_DISK_WRITEMOSTLY))

     \ /
      Last update: 2011-01-06 00:11    [W:0.021 / U:3.528 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site