From patchwork Fri Nov 6 12:22:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vishnu Pratap Singh X-Patchwork-Id: 540940 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 549B9140778 for ; Fri, 6 Nov 2015 23:24:56 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161198AbbKFMYm (ORCPT ); Fri, 6 Nov 2015 07:24:42 -0500 Received: from mailout2.samsung.com ([203.254.224.25]:47229 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1031995AbbKFMYj (ORCPT ); Fri, 6 Nov 2015 07:24:39 -0500 Received: from epcpsbgr5.samsung.com (u145.gpu120.samsung.co.kr [203.254.230.145]) by mailout2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0NXE022PY7T1SQ30@mailout2.samsung.com>; Fri, 06 Nov 2015 21:24:37 +0900 (KST) Received: from epcpsbgm1new.samsung.com ( [172.20.52.124]) by epcpsbgr5.samsung.com (EPCPMTA) with SMTP id 72.9B.05385.40C9C365; Fri, 6 Nov 2015 21:24:37 +0900 (KST) X-AuditID: cbfee691-f79d66d000001509-b7-563c9c044aef Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1new.samsung.com (EPCPMTA) with SMTP id ED.EA.23663.40C9C365; Fri, 6 Nov 2015 21:24:36 +0900 (KST) Received: from vishnu-ubuntu.sisodomain.com ([107.108.218.62]) by mmp1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0NXE00BOR7P5LC40@mmp1.samsung.com>; Fri, 06 Nov 2015 21:24:36 +0900 (KST) From: Vishnu Pratap Singh To: axboe@kernel.dk, akpm@linux-foundation.org, linux-kernel@vger.kernel.org, jmoyer@redhat.com, minchan@kernel.org, ngupta@vflare.org, sergey.senozhatsky.work@gmail.com, davem@davemloft.net, neilb@suse.com, ulf.hansson@linaro.org, tiwai@suse.de, hare@suse.de, ming.lei@canonical.com, jarod@redhat.com, viro@zeniv.linux.org.uk, tj@kernel.org, adrian.hunter@intel.com, jonathanh@nvidia.com, grundler@chromium.org, linux-ide@vger.kernel.org, linux-raid@vger.kernel.org, linux-mmc@vger.kernel.org Cc: cpgs@samsung.com, vishu13285@gmail.com, pintu.k@samsung.com, rohit.kr@samsung.com, Vishnu Pratap Singh Subject: [PATCH 1/8] block/genhd.c: Add error handling Date: Fri, 06 Nov 2015 17:52:08 +0530 Message-id: <1446812535-10567-1-git-send-email-vishnu.ps@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <437969438-9181-1-git-send-email-vishnu.ps@samsung.com> References: <437969438-9181-1-git-send-email-vishnu.ps@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrMIsWRmVeSWpSXmKPExsWyRsSkRpd1jk2YwfKVbBYnn6xhs5izHkis vtvPZvHykKbFnPMtLBavjvxgstizaBKTxbSeS4wWZ39dZbFombWIxeLYjkdMFpd3zWGzOPK/ n9Giff4uRotlX9+zW+x6+J3d4tPGWIsNLbPYLfq+H2a3eN7cymLxaALQkJeb3zBZ/Fp+lNHi +Npwi/N/j7NaTOm7y2ixZcVDVgdpj1kNvWwesxsusnhsWXmTyWPnrLvsHov3vGTyuHy21GPT qk42jzvX9rB5nJjxm8Wjt/kdm8f7fVfZPPq2rGL0WL/lKovH5tPVHjs/bWb1+LxJLkAwissm JTUnsyy1SN8ugSuj7VUvW8FJ64ruZ9NZGxjvGXQxcnJICJhI/P77hBHCFpO4cG89WxcjF4eQ wApGiUPP/zDBFG35MIcFIrGUUeL0xPXMEE4Tk8SflevYQarYBAwlNsw+wg6SEBH4zSwxY0E/ mMMs0MIoMfX0OqBZHBzCAmYSmx4IgzSwCKhK3OmYzQZi8wq4Sqx4/5gZYp2cxMljk1lBbE4B F4kZ84+CxYUEnCUudH9gApkpIdDMKXHi1EtWiEECEt8mH2IBmS8hICux6QDUHEmJgytusExg FF7AyLCKUTS1ILmgOCm9yFSvODG3uDQvXS85P3cTIzAtnP73bOIOxvsHrA8xCnAwKvHwGiy3 DhNiTSwrrsw9xGgKtGEis5Rocj4w+eSVxBsamxlZmJqYGhuZW5opifPqSP8MFhJITyxJzU5N LUgtii8qzUktPsTIxMEp1cAo2jdx0ieRLGXRpXslllol2Cg6iHBcT+YL3FJWPXPhqe1LJ202 Ocn4+ZHrt9Vmdx1k6mbEN77WP3IzpOsmm8r+56ev7fLxWrfioO73kLbe0KvpS25es86tvfwp o7R342WrlhPS0y3swo/O5PD9v+Du61jtyvh6q1K3LysDXzuumcGtmZ8dbayhxFKckWioxVxU nAgAyonaeAYDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrAKsWRmVeSWpSXmKPExsVy+t9jAV2WOTZhBruPGVucfLKGzWLOeiCx +m4/m8XLQ5oWc863sFi8OvKDyWLPoklMFtN6LjFanP11lcWiZdYiFotjOx4xWVzeNYfN4sj/ fkaL9vm7GC2WfX3PbrHr4Xd2i08bYy02tMxit+j7fpjd4nlzK4vFowlAQ15ufsNk8Wv5UUaL 42vDLc7/Pc5qMaXvLqPFlhUPWR2kPWY19LJ5zG64yOKxZeVNJo+ds+6yeyze85LJ4/LZUo9N qzrZPO5c28PmcWLGbxaP3uZ3bB7v911l8+jbsorRY/2Wqywem09Xe+z8tJnV4/MmuQDBqAZG m4zUxJTUIoXUvOT8lMy8dFsl7+B453hTMwNDXUNLC3MlhbzE3FRbJRefAF23zBxg6CgplCXm lAKFAhKLi5X07TBNCA1x07WAaYzQ9Q0JgusxMkADCWsYM9pe9bIVnLSu6H42nbWB8Z5BFyMn h4SAicSWD3NYIGwxiQv31rN1MXJxCAksZZQ4PXE9M4TTxCTxZ+U6dpAqNgFDiQ2zj7CDJEQE fjNLzFjQD+YwC7QwSkw9vY6pi5GDQ1jATGLTA2GQBhYBVYk7HbPZQGxeAVeJFe8fM0Osk5M4 eWwyK4jNKeAiMWP+UbC4kICzxIXuD0wTGHkXMDKsYpRILUguKE5KzzXMSy3XK07MLS7NS9dL zs/dxAhOPc+kdjAe3OV+iFGAg1GJh9dguXWYEGtiWXFl7iFGCQ5mJRFeOWabMCHelMTKqtSi /Pii0pzU4kOMpkCHTWSWEk3OB6bFvJJ4Q2MTc1NjU0sTCxMzSyVxXn1PozAhgfTEktTs1NSC 1CKYPiYOTqkGRm4BvvUXdL9Nkp6isViFIeux9spUr89aNWaHF8u39efx1E+3epKx49SPl1GV t6ebVJ0/IbP0+9d3qysNa/Z+FeFjZtMUDFlsyST6/M/H1yv3nn+0all87uaz5cprNz1bknHr X2e1mrV9duJ6BqHudzE/Km5Jtq8PbjRad4ht8aQVlx1+zN/YPFGJpTgj0VCLuag4EQBFt8VL UwMAAA== DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-ide-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ide@vger.kernel.org This patch adds error handling for blk_register_region(), register_disk(), add_disk(), disk_alloc_events() & disk_add_events(). add_disk() & register_disk() functions error handling is very much needed as this is used mainly by many modules like mmc, zram, mtd, scsi etc. But there is no error handling and it may cause stability issues also. Verfied on X86 based ubuntu machine. Signed-off-by: Vishnu Pratap Singh --- block/genhd.c | 89 +++++++++++++++++++++++++++++++++++---------------- include/linux/genhd.h | 4 +-- 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index 3213b66..a63ebd6 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -39,8 +39,8 @@ static struct device_type disk_type; static void disk_check_events(struct disk_events *ev, unsigned int *clearing_ptr); -static void disk_alloc_events(struct gendisk *disk); -static void disk_add_events(struct gendisk *disk); +static int disk_alloc_events(struct gendisk *disk); +static int disk_add_events(struct gendisk *disk); static void disk_del_events(struct gendisk *disk); static void disk_release_events(struct gendisk *disk); @@ -473,11 +473,11 @@ static char *bdevt_str(dev_t devt, char *buf) * range must be nonzero * The hash chain is sorted on range, so that subranges can override. */ -void blk_register_region(dev_t devt, unsigned long range, struct module *module, +int blk_register_region(dev_t devt, unsigned long range, struct module *module, struct kobject *(*probe)(dev_t, int *, void *), int (*lock)(dev_t, void *), void *data) { - kobj_map(bdev_map, devt, range, module, probe, lock, data); + return kobj_map(bdev_map, devt, range, module, probe, lock, data); } EXPORT_SYMBOL(blk_register_region); @@ -505,7 +505,7 @@ static int exact_lock(dev_t devt, void *data) return 0; } -static void register_disk(struct gendisk *disk) +static int register_disk(struct gendisk *disk) { struct device *ddev = disk_to_dev(disk); struct block_device *bdev; @@ -520,14 +520,15 @@ static void register_disk(struct gendisk *disk) /* delay uevents, until we scanned partition table */ dev_set_uevent_suppress(ddev, 1); - if (device_add(ddev)) - return; + err = device_add(ddev); + if (err) + return err; if (!sysfs_deprecated) { err = sysfs_create_link(block_depr, &ddev->kobj, kobject_name(&ddev->kobj)); if (err) { device_del(ddev); - return; + return err; } } @@ -569,6 +570,7 @@ exit: while ((part = disk_part_iter_next(&piter))) kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD); disk_part_iter_exit(&piter); + return err; } /** @@ -577,10 +579,8 @@ exit: * * This function registers the partitioning information in @disk * with the kernel. - * - * FIXME: error handling */ -void add_disk(struct gendisk *disk) +int add_disk(struct gendisk *disk) { struct backing_dev_info *bdi; dev_t devt; @@ -598,7 +598,7 @@ void add_disk(struct gendisk *disk) retval = blk_alloc_devt(&disk->part0, &devt); if (retval) { WARN_ON(1); - return; + return retval; } disk_to_dev(disk)->devt = devt; @@ -608,17 +608,27 @@ void add_disk(struct gendisk *disk) disk->major = MAJOR(devt); disk->first_minor = MINOR(devt); - disk_alloc_events(disk); - + retval = disk_alloc_events(disk); + if (retval) + goto err_blk_devt; /* Register BDI before referencing it from bdev */ bdi = &disk->queue->backing_dev_info; - bdi_register_dev(bdi, disk_devt(disk)); + retval = bdi_register_dev(bdi, disk_devt(disk)); + if (retval) + goto err_alloc_event; - blk_register_region(disk_devt(disk), disk->minors, NULL, + retval = blk_register_region(disk_devt(disk), disk->minors, NULL, exact_match, exact_lock, disk); - register_disk(disk); - blk_register_queue(disk); + if (retval) + goto err_alloc_event; + + retval = register_disk(disk); + if (retval) + goto err_reg_region; + retval = blk_register_queue(disk); + if (retval) + goto err_reg_disk; /* * Take an extra ref on queue which will be put on disk_release() * so that it sticks around as long as @disk is there. @@ -627,9 +637,28 @@ void add_disk(struct gendisk *disk) retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj, "bdi"); - WARN_ON(retval); + if (retval) + goto err_blk_reg_queue; + + retval = disk_add_events(disk); + if (retval) + goto err_sysfs; - disk_add_events(disk); + return 0; + +err_blk_devt: + blk_free_devt(devt); +err_alloc_event: + disk_del_events(disk); +err_reg_region: + blk_unregister_region(disk_devt(disk), disk->minors); +err_reg_disk: + del_gendisk(disk); +err_blk_reg_queue: + blk_unregister_queue(disk); +err_sysfs: + sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); + return retval; } EXPORT_SYMBOL(add_disk); @@ -1782,17 +1811,17 @@ module_param_cb(events_dfl_poll_msecs, &disk_events_dfl_poll_msecs_param_ops, /* * disk_{alloc|add|del|release}_events - initialize and destroy disk_events. */ -static void disk_alloc_events(struct gendisk *disk) +static int disk_alloc_events(struct gendisk *disk) { struct disk_events *ev; if (!disk->fops->check_events) - return; + return 0; ev = kzalloc(sizeof(*ev), GFP_KERNEL); if (!ev) { pr_warn("%s: failed to initialize events\n", disk->disk_name); - return; + return -ENOMEM; } INIT_LIST_HEAD(&ev->node); @@ -1804,17 +1833,22 @@ static void disk_alloc_events(struct gendisk *disk) INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn); disk->ev = ev; + return 0; } -static void disk_add_events(struct gendisk *disk) +static int disk_add_events(struct gendisk *disk) { + int ret = 0; + if (!disk->ev) - return; + return ret; - /* FIXME: error handling */ - if (sysfs_create_files(&disk_to_dev(disk)->kobj, disk_events_attrs) < 0) + ret = sysfs_create_files(&disk_to_dev(disk)->kobj, disk_events_attrs); + if (ret) { pr_warn("%s: failed to create sysfs files for events\n", disk->disk_name); + return ret; + } mutex_lock(&disk_events_mutex); list_add_tail(&disk->ev->node, &disk_events); @@ -1825,6 +1859,7 @@ static void disk_add_events(struct gendisk *disk) * unblock kicks it into action. */ __disk_unblock_events(disk, true); + return ret; } static void disk_del_events(struct gendisk *disk) diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 2adbfa6..dae3160 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -417,7 +417,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 add_disk(struct gendisk *disk); +extern int add_disk(struct gendisk *disk); extern void del_gendisk(struct gendisk *gp); extern struct gendisk *get_gendisk(dev_t dev, int *partno); extern struct block_device *bdget_disk(struct gendisk *disk, int partno); @@ -620,7 +620,7 @@ extern struct gendisk *alloc_disk_node(int minors, int node_id); extern struct gendisk *alloc_disk(int minors); extern struct kobject *get_disk(struct gendisk *disk); extern void put_disk(struct gendisk *disk); -extern void blk_register_region(dev_t devt, unsigned long range, +extern int blk_register_region(dev_t devt, unsigned long range, struct module *module, struct kobject *(*probe)(dev_t, int *, void *), int (*lock)(dev_t, void *),