lkml.org 
[lkml]   [2021]   [Oct]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 06/13] nvdimm/blk: avoid calling del_gendisk() on early failures
    Date
    If nd_integrity_init() fails we'd get del_gendisk() called,
    but that's not correct as we should only call that if we're
    done with device_add_disk(). Fix this by providing unwinding
    prior to the devm call being registered and moving the devm
    registration to the very end.

    This should fix calling del_gendisk() if nd_integrity_init()
    fails. I only spotted this issue through code inspection. It
    does not fix any real world bug.

    Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
    ---
    drivers/nvdimm/blk.c | 17 ++++++++++++-----
    1 file changed, 12 insertions(+), 5 deletions(-)

    diff --git a/drivers/nvdimm/blk.c b/drivers/nvdimm/blk.c
    index 088d3dd6f6fa..591fa1f86f1e 100644
    --- a/drivers/nvdimm/blk.c
    +++ b/drivers/nvdimm/blk.c
    @@ -240,6 +240,7 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
    resource_size_t available_disk_size;
    struct gendisk *disk;
    u64 internal_nlba;
    + int rc;

    internal_nlba = div_u64(nsblk->size, nsblk_internal_lbasize(nsblk));
    available_disk_size = internal_nlba * nsblk_sector_size(nsblk);
    @@ -256,20 +257,26 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
    blk_queue_logical_block_size(disk->queue, nsblk_sector_size(nsblk));
    blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue);

    - if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk))
    - return -ENOMEM;
    -
    if (nsblk_meta_size(nsblk)) {
    - int rc = nd_integrity_init(disk, nsblk_meta_size(nsblk));
    + rc = nd_integrity_init(disk, nsblk_meta_size(nsblk));

    if (rc)
    - return rc;
    + goto out_before_devm_err;
    }

    set_capacity(disk, available_disk_size >> SECTOR_SHIFT);
    device_add_disk(dev, disk, NULL);
    +
    + /* nd_blk_release_disk() is called if this fails */
    + if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk))
    + return -ENOMEM;
    +
    nvdimm_check_and_set_ro(disk);
    return 0;
    +
    +out_before_devm_err:
    + blk_cleanup_disk(disk);
    + return rc;
    }

    static int nd_blk_probe(struct device *dev)
    --
    2.30.2
    \
     
     \ /
      Last update: 2021-10-16 01:53    [W:4.237 / U:0.144 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site