lkml.org 
[lkml]   [2009]   [Feb]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 08/53] md: Ensure an md array never has too many devices.
    2.6.28-stable review patch.  If anyone has any objections, please let us know.
    ------------------

    From: NeilBrown <neilb@suse.de>

    commit de01dfadf25bf83cfe3d85c163005c4320532658 upstream.

    Each different metadata format supported by md supports a
    different maximum number of devices.
    We really should be enforcing this maximum in the kernel, but
    we aren't quite doing that properly.

    We currently only enforce it at the 'hot_add' point, which is an
    older interface which is not used by current userspace.

    We need to also enforce it at 'add_new_disk' time for active arrays
    and at 'do_md_run' time when starting a new array.

    So move the test from 'hot_add' into 'bind_rdev_to_array' which is
    called from both 'hot_add' and 'add_new_disk, and add a new
    test in 'analyse_sbs' which is called from 'do_md_run'.

    This bug (or missing feature) has been around "forever" and so
    the patch is suitable for any -stable that is currently maintained.

    Signed-off-by: NeilBrown <neilb@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/md/md.c | 24 ++++++++++++++----------
    1 file changed, 14 insertions(+), 10 deletions(-)

    --- a/drivers/md/md.c
    +++ b/drivers/md/md.c
    @@ -1447,6 +1447,11 @@ static int bind_rdev_to_array(mdk_rdev_t
    if (find_rdev_nr(mddev, rdev->desc_nr))
    return -EBUSY;
    }
    + if (mddev->max_disks && rdev->desc_nr >= mddev->max_disks) {
    + printk(KERN_WARNING "md: %s: array is limited to %d devices\n",
    + mdname(mddev), mddev->max_disks);
    + return -EBUSY;
    + }
    bdevname(rdev->bdev,b);
    while ( (s=strchr(b, '/')) != NULL)
    *s = '!';
    @@ -2355,6 +2360,15 @@ static void analyze_sbs(mddev_t * mddev)

    i = 0;
    rdev_for_each(rdev, tmp, mddev) {
    + if (rdev->desc_nr >= mddev->max_disks ||
    + i > mddev->max_disks) {
    + printk(KERN_WARNING
    + "md: %s: %s: only %d devices permitted\n",
    + mdname(mddev), bdevname(rdev->bdev, b),
    + mddev->max_disks);
    + kick_rdev_from_array(rdev);
    + continue;
    + }
    if (rdev != freshest)
    if (super_types[mddev->major_version].
    validate_super(mddev, rdev)) {
    @@ -4448,13 +4462,6 @@ static int hot_add_disk(mddev_t * mddev,
    * noticed in interrupt contexts ...
    */

    - if (rdev->desc_nr == mddev->max_disks) {
    - printk(KERN_WARNING "%s: can not hot-add to full array!\n",
    - mdname(mddev));
    - err = -EBUSY;
    - goto abort_unbind_export;
    - }
    -
    rdev->raid_disk = -1;

    md_update_sb(mddev, 1);
    @@ -4468,9 +4475,6 @@ static int hot_add_disk(mddev_t * mddev,
    md_new_event(mddev);
    return 0;

    -abort_unbind_export:
    - unbind_rdev_from_array(rdev);
    -
    abort_export:
    export_rdev(rdev);
    return err;


    \
     
     \ /
      Last update: 2009-02-10 20:09    [W:2.789 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site