There are a number of places in device_add_disk that can fail, and even more to come as we extend it. Switch the return type of the function, and return the error code when error happens. The WARN_ON is kept because callers are not updated to check the error yet. Signed-off-by: Fam Zheng <famz@xxxxxxxxxx> --- block/genhd.c | 49 ++++++++++++++++++++++++++++++++++--------------- include/linux/genhd.h | 2 +- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index 4316d2d..ffb3929 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -595,9 +595,10 @@ exit: * This function registers the partitioning information in @disk * with the kernel. * - * FIXME: error handling + * RETURNS: + * 0 on success, -errno on failure. */ -void device_add_disk(struct device *parent, struct gendisk *disk) +int device_add_disk(struct device *parent, struct gendisk *disk) { struct backing_dev_info *bdi; dev_t devt; @@ -613,10 +614,8 @@ void device_add_disk(struct device *parent, struct gendisk *disk) disk->flags |= GENHD_FL_UP; retval = blk_alloc_devt(&disk->part0, &devt); - if (retval) { - WARN_ON(1); - return; - } + if (retval) + goto fail; disk_to_dev(disk)->devt = devt; /* ->major and ->first_minor aren't supposed to be @@ -625,16 +624,26 @@ void device_add_disk(struct device *parent, struct gendisk *disk) disk->major = MAJOR(devt); disk->first_minor = MINOR(devt); - disk_alloc_events(disk); + retval = disk_alloc_events(disk); + if (retval) + goto fail; /* Register BDI before referencing it from bdev */ bdi = &disk->queue->backing_dev_info; - bdi_register_owner(bdi, disk_to_dev(disk)); + retval = bdi_register_owner(bdi, disk_to_dev(disk)); + if (retval) + goto fail; - blk_register_region(disk_devt(disk), disk->minors, NULL, - exact_match, exact_lock, disk); - register_disk(parent, disk); - blk_register_queue(disk); + retval = blk_register_region(disk_devt(disk), disk->minors, NULL, + exact_match, exact_lock, disk); + if (retval) + goto fail; + retval = register_disk(parent, disk); + if (retval) + goto fail; + retval = blk_register_queue(disk); + if (retval) + goto fail; /* * Take an extra ref on queue which will be put on disk_release() @@ -644,10 +653,20 @@ void device_add_disk(struct device *parent, struct gendisk *disk) retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj, "bdi"); + if (retval) + goto fail; + + retval = disk_add_events(disk); + if (retval) + goto fail; + + retval = blk_integrity_add(disk); + if (retval) + goto fail; + return 0; +fail: WARN_ON(retval); - - disk_add_events(disk); - blk_integrity_add(disk); + return retval; } EXPORT_SYMBOL(device_add_disk); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 85ce560..991b5ff 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -413,7 +413,7 @@ static inline void free_part_info(struct hd_struct *part) extern void part_round_stats(int cpu, struct hd_struct *part); /* block/genhd.c */ -extern void device_add_disk(struct device *parent, struct gendisk *disk); +extern int device_add_disk(struct device *parent, struct gendisk *disk); extern void del_gendisk(struct gendisk *gp); extern struct gendisk *get_gendisk(dev_t dev, int *partno); -- 2.7.4 _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization