aboutsummaryrefslogtreecommitdiffstats
path: root/driver
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-04-03 15:16:51 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2006-04-03 15:16:51 -0700
commit645ef8413c0bcb7b3edcfb42f2d44f2151d2bd6e (patch)
tree5fd925dce4d63332dfb35cd6d442e7fed72a5c89 /driver
parentf9b3d7ae998e086d7247a662e656c40f4de0a18b (diff)
downloadpatches-645ef8413c0bcb7b3edcfb42f2d44f2151d2bd6e.tar.gz
added block uevent patch
Diffstat (limited to 'driver')
-rw-r--r--driver/block-delay-all-uevents-until-partition-table-is-scanned.patch130
1 files changed, 130 insertions, 0 deletions
diff --git a/driver/block-delay-all-uevents-until-partition-table-is-scanned.patch b/driver/block-delay-all-uevents-until-partition-table-is-scanned.patch
new file mode 100644
index 0000000000000..944230fc55ffb
--- /dev/null
+++ b/driver/block-delay-all-uevents-until-partition-table-is-scanned.patch
@@ -0,0 +1,130 @@
+From kay.sievers@vrfy.org Fri Mar 24 11:45:43 2006
+Date: Fri, 24 Mar 2006 20:45:35 +0100
+From: Kay Sievers <kay.sievers@vrfy.org>
+To: "Randy.Dunlap" <rdunlap@xenotime.net>
+Cc: greg@kroah.com, <viro@ftp.linux.org.uk>
+Subject: BLOCK: delay all uevents until partition table is scanned
+Message-ID: <20060324194535.GA13905@vrfy.org>
+Content-Disposition: inline
+
+From: Kay Sievers <kay.sievers@suse.de>
+
+[BLOCK] delay all uevents until partition table is scanned
+
+Here we delay the annoucement of all block device events until the
+disk's partition table is scanned and all partition devices are already
+created and sysfs is populated.
+
+We have a bunch of old bugs for removable storage handling where we
+probe successfully for a filesystem on the raw disk, but at the
+same time the kernel recognizes a partition table and creates partition
+devices.
+Currently there is no sane way to tell if partitions will show up or not
+at the time the disk device is announced to userspace. With the delayed
+events we can simply skip any probe for a filesystem on the raw disk when
+we find already present partitions.
+
+Signed-off-by: Kay Sievers <kay.sievers@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/partitions/check.c | 38 ++++++++++++++++++++++++++++++--------
+ include/linux/genhd.h | 1 +
+ 2 files changed, 31 insertions(+), 8 deletions(-)
+
+--- gregkh-2.6.orig/fs/partitions/check.c
++++ gregkh-2.6/fs/partitions/check.c
+@@ -331,7 +331,9 @@ void delete_partition(struct gendisk *di
+ devfs_remove("%s/part%d", disk->devfs_name, part);
+ if (p->holder_dir)
+ kobject_unregister(p->holder_dir);
+- kobject_unregister(&p->kobj);
++ kobject_uevent(&p->kobj, KOBJ_REMOVE);
++ kobject_del(&p->kobj);
++ kobject_put(&p->kobj);
+ }
+
+ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
+@@ -357,7 +359,10 @@ void add_partition(struct gendisk *disk,
+ snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part);
+ p->kobj.parent = &disk->kobj;
+ p->kobj.ktype = &ktype_part;
+- kobject_register(&p->kobj);
++ kobject_init(&p->kobj);
++ kobject_add(&p->kobj);
++ if (!disk->part_uevent_suppress)
++ kobject_uevent(&p->kobj, KOBJ_ADD);
+ partition_sysfs_add_subdir(p);
+ disk->part[part-1] = p;
+ }
+@@ -395,6 +400,8 @@ void register_disk(struct gendisk *disk)
+ {
+ struct block_device *bdev;
+ char *s;
++ int i;
++ struct hd_struct *p;
+ int err;
+
+ strlcpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN);
+@@ -406,13 +413,12 @@ void register_disk(struct gendisk *disk)
+ return;
+ disk_sysfs_symlinks(disk);
+ disk_sysfs_add_subdirs(disk);
+- kobject_uevent(&disk->kobj, KOBJ_ADD);
+
+ /* No minors to use for partitions */
+ if (disk->minors == 1) {
+ if (disk->devfs_name[0] != '\0')
+ devfs_add_disk(disk);
+- return;
++ goto exit;
+ }
+
+ /* always add handle for the whole disk */
+@@ -420,16 +426,32 @@ void register_disk(struct gendisk *disk)
+
+ /* No such device (e.g., media were just removed) */
+ if (!get_capacity(disk))
+- return;
++ goto exit;
+
+ bdev = bdget_disk(disk, 0);
+ if (!bdev)
+- return;
++ goto exit;
+
++ /* scan partition table, but suppress uevents */
+ bdev->bd_invalidated = 1;
+- if (blkdev_get(bdev, FMODE_READ, 0) < 0)
+- return;
++ disk->part_uevent_suppress = 1;
++ err = blkdev_get(bdev, FMODE_READ, 0);
++ disk->part_uevent_suppress = 0;
++ if (err < 0)
++ goto exit;
+ blkdev_put(bdev);
++
++exit:
++ /* announce disk after possible partitions are already created */
++ kobject_uevent(&disk->kobj, KOBJ_ADD);
++
++ /* announce possible partitions */
++ for (i = 1; i < disk->minors; i++) {
++ p = disk->part[i-1];
++ if (!p || !p->nr_sects)
++ continue;
++ kobject_uevent(&p->kobj, KOBJ_ADD);
++ }
+ }
+
+ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
+--- gregkh-2.6.orig/include/linux/genhd.h
++++ gregkh-2.6/include/linux/genhd.h
+@@ -105,6 +105,7 @@ struct gendisk {
+ * disks that can't be partitioned. */
+ char disk_name[32]; /* name of major driver */
+ struct hd_struct **part; /* [indexed by minor] */
++ int part_uevent_suppress;
+ struct block_device_operations *fops;
+ struct request_queue *queue;
+ void *private_data;