lkml.org 
[lkml]   [2021]   [May]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 031/244] md: split mddev_find
    Date
    From: Christoph Hellwig <hch@lst.de>

    commit 65aa97c4d2bfd76677c211b9d03ef05a98c6d68e upstream.

    Split mddev_find into a simple mddev_find that just finds an existing
    mddev by the unit number, and a more complicated mddev_find that deals
    with find or allocating a mddev.

    This turns out to fix this bug reported by Zhao Heming.

    ----------------------------- snip ------------------------------
    commit d3374825ce57 ("md: make devices disappear when they are no longer
    needed.") introduced protection between mddev creating & removing. The
    md_open shouldn't create mddev when all_mddevs list doesn't contain
    mddev. With currently code logic, there will be very easy to trigger
    soft lockup in non-preempt env.

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

    --- a/drivers/md/md.c
    +++ b/drivers/md/md.c
    @@ -649,6 +649,22 @@ EXPORT_SYMBOL_GPL(mddev_init);

    static struct mddev *mddev_find(dev_t unit)
    {
    + struct mddev *mddev;
    +
    + if (MAJOR(unit) != MD_MAJOR)
    + unit &= ~((1 << MdpMinorShift) - 1);
    +
    + spin_lock(&all_mddevs_lock);
    + mddev = mddev_find_locked(unit);
    + if (mddev)
    + mddev_get(mddev);
    + spin_unlock(&all_mddevs_lock);
    +
    + return mddev;
    +}
    +
    +static struct mddev *mddev_find_or_alloc(dev_t unit)
    +{
    struct mddev *mddev, *new = NULL;

    if (unit && MAJOR(unit) != MD_MAJOR)
    @@ -5436,7 +5452,7 @@ static int md_alloc(dev_t dev, char *nam
    * writing to /sys/module/md_mod/parameters/new_array.
    */
    static DEFINE_MUTEX(disks_mutex);
    - struct mddev *mddev = mddev_find(dev);
    + struct mddev *mddev = mddev_find_or_alloc(dev);
    struct gendisk *disk;
    int partitioned;
    int shift;
    @@ -6312,11 +6328,9 @@ static void autorun_devices(int part)

    md_probe(dev, NULL, NULL);
    mddev = mddev_find(dev);
    - if (!mddev || !mddev->gendisk) {
    - if (mddev)
    - mddev_put(mddev);
    + if (!mddev)
    break;
    - }
    +
    if (mddev_lock(mddev))
    pr_warn("md: %s locked, cannot run\n", mdname(mddev));
    else if (mddev->raid_disks || mddev->major_version

    \
     
     \ /
      Last update: 2021-05-12 17:01    [W:4.170 / U:0.432 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site