diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-04-03 15:16:51 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-04-03 15:16:51 -0700 |
commit | 645ef8413c0bcb7b3edcfb42f2d44f2151d2bd6e (patch) | |
tree | 5fd925dce4d63332dfb35cd6d442e7fed72a5c89 /driver | |
parent | f9b3d7ae998e086d7247a662e656c40f4de0a18b (diff) | |
download | patches-645ef8413c0bcb7b3edcfb42f2d44f2151d2bd6e.tar.gz |
added block uevent patch
Diffstat (limited to 'driver')
-rw-r--r-- | driver/block-delay-all-uevents-until-partition-table-is-scanned.patch | 130 |
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; |