All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dirk Hohndel <hohndel@linux.intel.com>
To: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Andries Brouwer <aeb@cwi.nl>, Al Viro <viro@ftp.linux.org.uk>,
	Jens Axboe <jens.axboe@oracle.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] add_partition silently ignored errors
Date: Mon, 29 Oct 2007 07:24:27 -0700	[thread overview]
Message-ID: <20071029142427.GA21930@bigserver.hohndel.org> (raw)
In-Reply-To: <20071029140657.09d3a343@gondolin.boeblingen.de.ibm.com>

On Mon, Oct 29, 2007 at 02:06:57PM +0100, Cornelia Huck wrote:
> On Mon, 29 Oct 2007 05:22:11 -0700,
> Dirk Hohndel <hohndel@linux.intel.com> wrote:
> 
> <only commenting on the kobject part...>
> 
> > @@ -390,20 +390,31 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len,
> >  	p->kobj.parent = &disk->kobj;
> >  	p->kobj.ktype = &ktype_part;
> >  	kobject_init(&p->kobj);
> > -	kobject_add(&p->kobj);
> > +	if (kobject_add(&p->kobj)) 
> > +		return -1;
> >  	if (!disk->part_uevent_suppress)
> >  		kobject_uevent(&p->kobj, KOBJ_ADD);
> > -	sysfs_create_link(&p->kobj, &block_subsys.kobj, "subsystem");
> > +	if(sysfs_create_link(&p->kobj, &block_subsys.kobj, "subsystem")) {
> > +		kobject_del(&p->kobj);
> > +		kfree(p);
> > +		return -1;
> > +	}
> 
> 
> - This is missing a KOBJ_DEL uevent if you did a KOBJ_ADD uevent.

Completely missed that one.

> - Calling kfree() after you already registered the kobject via
>   kobject_add() is wrong, since someone else might already have obtained
>   a reference. You must drop your reference after kobject_del() and let
>   the release mechanism take care of it.

Good point. 

> <I think I'm having some kind of deja vu, since it seems I've already
> pointed that out a couple of times to different people :) >
> 
> >  	if (flags & ADDPART_FLAG_WHOLEDISK) {
> >  		static struct attribute addpartattr = {
> >  			.name = "whole_disk",
> >  			.mode = S_IRUSR | S_IRGRP | S_IROTH,
> >  		};
> > 
> > -		sysfs_create_file(&p->kobj, &addpartattr);
> > +		if (sysfs_create_file(&p->kobj, &addpartattr)) {
> > +			kobject_del(&p->kobj);
> > +			kfree(p);
> > +			return -1;
> > +		}
> 
> Same here. You should probably also delete the link you created above.

Yep, fixed that as well.

How about the new patch below?

Signed-off-by: Dirk Hohndel <hohndel@linux.intel.com>

---
 block/ioctl.c         |    5 ++++-
 fs/partitions/check.c |   28 ++++++++++++++++++++++------
 include/linux/genhd.h |    2 +-
 3 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/block/ioctl.c b/block/ioctl.c
index 52d6385..bb3933e 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -61,7 +61,10 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
 				}
 			}
 			/* all seems OK */
-			add_partition(disk, part, start, length, ADDPART_FLAG_NONE);
+			if (add_partition(disk, part, start, length, ADDPART_FLAG_NONE)) {
+				mutex_unlock(&bdev->bd_mutex);
+				return -EBUSY;
+			}
 			mutex_unlock(&bdev->bd_mutex);
 			return 0;
 		case BLKPG_DEL_PARTITION:
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 722e12e..6bdf855 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -368,13 +368,13 @@ void delete_partition(struct gendisk *disk, int part)
 	kobject_put(&p->kobj);
 }
 
-void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags)
+int add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags)
 {
 	struct hd_struct *p;
 
 	p = kzalloc(sizeof(*p), GFP_KERNEL);
 	if (!p)
-		return;
+		return -1;
 	
 	p->start_sect = start;
 	p->nr_sects = len;
@@ -390,20 +390,33 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len,
 	p->kobj.parent = &disk->kobj;
 	p->kobj.ktype = &ktype_part;
 	kobject_init(&p->kobj);
-	kobject_add(&p->kobj);
+	if (kobject_add(&p->kobj)) 
+		return -1;
 	if (!disk->part_uevent_suppress)
 		kobject_uevent(&p->kobj, KOBJ_ADD);
-	sysfs_create_link(&p->kobj, &block_subsys.kobj, "subsystem");
+	if(sysfs_create_link(&p->kobj, &block_subsys.kobj, "subsystem")) 
+		goto out_cleanup;
 	if (flags & ADDPART_FLAG_WHOLEDISK) {
 		static struct attribute addpartattr = {
 			.name = "whole_disk",
 			.mode = S_IRUSR | S_IRGRP | S_IROTH,
 		};
 
-		sysfs_create_file(&p->kobj, &addpartattr);
+		if (sysfs_create_file(&p->kobj, &addpartattr)) {
+			sysfs_remove_link (&p->kobj, "subsystem");
+			goto out_cleanup;
+		}
 	}
 	partition_sysfs_add_subdir(p);
 	disk->part[part-1] = p;
+	
+	return 0;
+
+out_cleanup:
+	if (!disk->part_uevent_suppress)
+		kobject_uevent(&p->kobj, KOBJ_REMOVE);
+	kobject_del(&p->kobj);
+	return -1;
 }
 
 static char *make_block_name(struct gendisk *disk)
@@ -554,8 +567,11 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
 		if (from + size > get_capacity(disk)) {
 			printk(" %s: p%d exceeds device capacity\n",
 				disk->disk_name, p);
+			return -EBUSY;
+		}
+		if(add_partition(disk, p, from, size, state->parts[p].flags)) {
+			return -EBUSY;
 		}
-		add_partition(disk, p, from, size, state->parts[p].flags);
 #ifdef CONFIG_BLK_DEV_MD
 		if (state->parts[p].flags & ADDPART_FLAG_RAID)
 			md_autodetect_dev(bdev->bd_dev+p);
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index a47b802..ae6af2c 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -414,7 +414,7 @@ struct unixware_disklabel {
 char *disk_name (struct gendisk *hd, int part, char *buf);
 
 extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
-extern void add_partition(struct gendisk *, int, sector_t, sector_t, int);
+extern int add_partition(struct gendisk *, int, sector_t, sector_t, int);
 extern void delete_partition(struct gendisk *, int);
 extern void printk_all_partitions(void);
 
-- 
gitgui.0.8.4.g8d863


  reply	other threads:[~2007-10-29 14:25 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-29 12:22 [PATCH] add_partition silently ignored errors Dirk Hohndel
2007-10-29 13:06 ` Cornelia Huck
2007-10-29 14:24   ` Dirk Hohndel [this message]
2007-10-29 14:43     ` Cornelia Huck
2007-10-29 15:48       ` Dirk Hohndel
2007-10-29 16:47         ` Cornelia Huck
2007-10-30  8:07         ` Jens Axboe
2007-10-30  9:09           ` Cornelia Huck
2007-10-30 16:56             ` Dirk Hohndel
2007-10-30 17:31               ` Cornelia Huck
2007-10-30 22:56                 ` Dirk Hohndel
2007-10-31  9:45                   ` Cornelia Huck
2007-11-02 13:04                   ` Jens Axboe
2007-11-02 19:29                     ` Dirk Hohndel
2007-11-02 19:50                       ` Bob Copeland
2007-11-02 20:29                         ` Dirk Hohndel
2007-11-06 20:02                           ` [PATCH] FS: " Dirk Hohndel
2007-11-06 21:38                             ` Linus Torvalds

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20071029142427.GA21930@bigserver.hohndel.org \
    --to=hohndel@linux.intel.com \
    --cc=aeb@cwi.nl \
    --cc=cornelia.huck@de.ibm.com \
    --cc=jens.axboe@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=viro@ftp.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.