[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 07/10] nvdimm/blk: avoid calling del_gendisk() on early failures



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@xxxxxxxxxx>
---
 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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.