block: fix add_partition() error path
PATCH 1/3 block: fix add_partition() error path
Partition stats structure was not freed on devt allocation failure path. Fix it.
Signed-off-by Tejun Heo <[email protected]>
--- fs/partitions/check.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/partitions/check.c +3 -1
@@ -395,7 +395,7 @@ int add_partition(struct gendisk *disk, err =blk_alloc_devt (p, &devt);if (err) - goto out_free; + goto out_free_stats; pdev->devt = devt;/* delay uevent until 'holders' subdir is created */
@@ -426,6 +426,8 @@ int add_partition(struct gendisk *disk,return 0 ; +out_free_stats: +free_part_stats (p); out_free:kfree (p);return err;
PATCH 1/1 block: make add_partition() return pointer to hd_struct
Make add_partition() return pointer to the new hd_struct on success and ERR_PTR() value on failure. This change will be used to fix md autodetection bug.
Signed-off-by Tejun Heo <[email protected]>
Cc Neil Brown <[email protected]>
--- block/ioctl.c | 7 +++---- fs/partitions/check.c | 25 +++++++++++++------------ include/linux/genhd.h | 4 +++- 3 files changed, 19 insertions(+), 17 deletions(-)
fs/partitions/check.c +13 -12
@@ -348,8 +348,8 @@ static ssize_t whole_disk_show(struct de static DEVICE_ATTR(whole_disk, S_IRUSR | S_IRGRP | S_IROTH, whole_disk_show, NULL); -int add_partition (struct gendisk *disk,int partno, -sector_t start,sector_t len,int flags) +struct hd_struct *add_partition (struct gendisk *disk,int partno, +sector_t start,sector_t len,int flags) {struct hd_struct *p;dev_t devt =MKDEV (0 ,0 );
@@ -361,15 +361,15 @@ int add_partition(struct gendisk *disk, err =disk_expand_part_tbl (disk, partno);if (err) -return err; +return ERR_PTR (err); ptbl = disk->part_tbl;if (ptbl->part[partno]) -return -EBUSY ; +return ERR_PTR (-EBUSY ); p =kzalloc (sizeof (*p),GFP_KERNEL );if (!p) -return -ENOMEM ; +return ERR_PTR (-EBUSY );if (!init_part_stats (p)) { err = -ENOMEM ;
@@ -424,20 +424,20 @@ int add_partition(struct gendisk *disk,if (!ddev->uevent_suppress)kobject_uevent (&pdev->kobj,KOBJ_ADD ); -return 0 ; +return p; out_free_stats:free_part_stats (p); out_free:kfree (p); -return err; +return ERR_PTR (err); out_del:kobject_put (p->holder_dir);device_del (pdev); out_put:put_device (pdev);blk_free_devt (devt); -return err; +return ERR_PTR (err); }/* Not exported, helper to add_disk(). */
@@ -568,10 +568,11 @@ int rescan_partitions(struct gendisk *di disk->disk_name, p, (unsigned long long) size); size =get_capacity (disk) - from; } - res =add_partition (disk, p, from, size, state->parts[p].flags); -if (res) { -printk (KERN_ERR " %s: p%d could not be added: %d\n" , - disk->disk_name, p, -res); + part =add_partition (disk, p, from, size, + state->parts[p].flags); +if (IS_ERR (part)) { +printk (KERN_ERR " %s: p%d could not be added: %ld\n" , + disk->disk_name, p, -PTR_ERR (part));continue ; }#ifdef CONFIG_BLK_DEV_MD
include/linux/genhd.h +3 -1
@@ -522,7 +522,9 @@ extern char *disk_name (struct gendisk *extern int disk_expand_part_tbl (struct gendisk *disk,int target);extern int rescan_partitions (struct gendisk *disk,struct block_device *bdev); -extern int __must_check add_partition (struct gendisk *,int ,sector_t ,sector_t ,int ); +extern struct hd_struct *__must_check add_partition (struct gendisk *disk, +int partno,sector_t start, +sector_t len,int flags);extern void delete_partition (struct gendisk *,int );extern void printk_all_partitions (void );
block/ioctl.c +3 -4
@@ -18,7 +18,6 @@ static int blkpg_ioctl(struct block_devistruct disk_part_iter piter;long long start, length;int partno; -int err;if (!capable (CAP_SYS_ADMIN ))return -EACCES ;
@@ -61,10 +60,10 @@ static int blkpg_ioctl(struct block_devidisk_part_iter_exit (&piter);/* all seems OK */ - err =add_partition (disk, partno, start, length, -ADDPART_FLAG_NONE ); + part =add_partition (disk, partno, start, length, +ADDPART_FLAG_NONE );mutex_unlock (&bdev->bd_mutex); -return err; +return IS_ERR (part) ?PTR_ERR (part) :0 ;case BLKPG_DEL_PARTITION : part =disk_get_part (disk, partno);if (!part)
PATCH 3/3 block/md: fix md autodetection
Block ext devt conversion missed md_autodetect_dev() call in rescan_partitions() leaving md autodetect unable to see partitions. Fix it.
Signed-off-by Tejun Heo <[email protected]>
Cc Neil Brown <[email protected]>
---
Oops, I forgot 2/3 in the subject of the second patch. Sorry.
fs/partitions/check.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/partitions/check.c +1 -1
@@ -577,7 +577,7 @@ int rescan_partitions(struct gendisk *di }#ifdef CONFIG_BLK_DEV_MD if (state->parts[p].flags &ADDPART_FLAG_RAID ) -md_autodetect_dev (bdev->bd_dev+p); +md_autodetect_dev (part_to_dev (part)->devt);#endif }kfree (state);
Jens Axboe
AppliedQuoted 2 lines · Tejun Heo
Partition stats structure was not freed on devt allocation failure path. Fix it.
Thanks, applied 1-3 for 2.6.28
Signature · 1 line
Jens Axboe