diff options
Diffstat (limited to 'fs/partitions/check.c')
-rw-r--r-- | fs/partitions/check.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index af0cb4b9e784..45ae7dd3c650 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -331,7 +331,9 @@ void delete_partition(struct gendisk *disk, int part) | |||
331 | devfs_remove("%s/part%d", disk->devfs_name, part); | 331 | devfs_remove("%s/part%d", disk->devfs_name, part); |
332 | if (p->holder_dir) | 332 | if (p->holder_dir) |
333 | kobject_unregister(p->holder_dir); | 333 | kobject_unregister(p->holder_dir); |
334 | kobject_unregister(&p->kobj); | 334 | kobject_uevent(&p->kobj, KOBJ_REMOVE); |
335 | kobject_del(&p->kobj); | ||
336 | kobject_put(&p->kobj); | ||
335 | } | 337 | } |
336 | 338 | ||
337 | void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) | 339 | void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) |
@@ -357,7 +359,10 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) | |||
357 | snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part); | 359 | snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part); |
358 | p->kobj.parent = &disk->kobj; | 360 | p->kobj.parent = &disk->kobj; |
359 | p->kobj.ktype = &ktype_part; | 361 | p->kobj.ktype = &ktype_part; |
360 | kobject_register(&p->kobj); | 362 | kobject_init(&p->kobj); |
363 | kobject_add(&p->kobj); | ||
364 | if (!disk->part_uevent_suppress) | ||
365 | kobject_uevent(&p->kobj, KOBJ_ADD); | ||
361 | partition_sysfs_add_subdir(p); | 366 | partition_sysfs_add_subdir(p); |
362 | disk->part[part-1] = p; | 367 | disk->part[part-1] = p; |
363 | } | 368 | } |
@@ -367,6 +372,7 @@ static char *make_block_name(struct gendisk *disk) | |||
367 | char *name; | 372 | char *name; |
368 | static char *block_str = "block:"; | 373 | static char *block_str = "block:"; |
369 | int size; | 374 | int size; |
375 | char *s; | ||
370 | 376 | ||
371 | size = strlen(block_str) + strlen(disk->disk_name) + 1; | 377 | size = strlen(block_str) + strlen(disk->disk_name) + 1; |
372 | name = kmalloc(size, GFP_KERNEL); | 378 | name = kmalloc(size, GFP_KERNEL); |
@@ -374,6 +380,10 @@ static char *make_block_name(struct gendisk *disk) | |||
374 | return NULL; | 380 | return NULL; |
375 | strcpy(name, block_str); | 381 | strcpy(name, block_str); |
376 | strcat(name, disk->disk_name); | 382 | strcat(name, disk->disk_name); |
383 | /* ewww... some of these buggers have / in name... */ | ||
384 | s = strchr(name, '/'); | ||
385 | if (s) | ||
386 | *s = '!'; | ||
377 | return name; | 387 | return name; |
378 | } | 388 | } |
379 | 389 | ||
@@ -395,6 +405,8 @@ void register_disk(struct gendisk *disk) | |||
395 | { | 405 | { |
396 | struct block_device *bdev; | 406 | struct block_device *bdev; |
397 | char *s; | 407 | char *s; |
408 | int i; | ||
409 | struct hd_struct *p; | ||
398 | int err; | 410 | int err; |
399 | 411 | ||
400 | strlcpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN); | 412 | strlcpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN); |
@@ -406,13 +418,12 @@ void register_disk(struct gendisk *disk) | |||
406 | return; | 418 | return; |
407 | disk_sysfs_symlinks(disk); | 419 | disk_sysfs_symlinks(disk); |
408 | disk_sysfs_add_subdirs(disk); | 420 | disk_sysfs_add_subdirs(disk); |
409 | kobject_uevent(&disk->kobj, KOBJ_ADD); | ||
410 | 421 | ||
411 | /* No minors to use for partitions */ | 422 | /* No minors to use for partitions */ |
412 | if (disk->minors == 1) { | 423 | if (disk->minors == 1) { |
413 | if (disk->devfs_name[0] != '\0') | 424 | if (disk->devfs_name[0] != '\0') |
414 | devfs_add_disk(disk); | 425 | devfs_add_disk(disk); |
415 | return; | 426 | goto exit; |
416 | } | 427 | } |
417 | 428 | ||
418 | /* always add handle for the whole disk */ | 429 | /* always add handle for the whole disk */ |
@@ -420,16 +431,32 @@ void register_disk(struct gendisk *disk) | |||
420 | 431 | ||
421 | /* No such device (e.g., media were just removed) */ | 432 | /* No such device (e.g., media were just removed) */ |
422 | if (!get_capacity(disk)) | 433 | if (!get_capacity(disk)) |
423 | return; | 434 | goto exit; |
424 | 435 | ||
425 | bdev = bdget_disk(disk, 0); | 436 | bdev = bdget_disk(disk, 0); |
426 | if (!bdev) | 437 | if (!bdev) |
427 | return; | 438 | goto exit; |
428 | 439 | ||
440 | /* scan partition table, but suppress uevents */ | ||
429 | bdev->bd_invalidated = 1; | 441 | bdev->bd_invalidated = 1; |
430 | if (blkdev_get(bdev, FMODE_READ, 0) < 0) | 442 | disk->part_uevent_suppress = 1; |
431 | return; | 443 | err = blkdev_get(bdev, FMODE_READ, 0); |
444 | disk->part_uevent_suppress = 0; | ||
445 | if (err < 0) | ||
446 | goto exit; | ||
432 | blkdev_put(bdev); | 447 | blkdev_put(bdev); |
448 | |||
449 | exit: | ||
450 | /* announce disk after possible partitions are already created */ | ||
451 | kobject_uevent(&disk->kobj, KOBJ_ADD); | ||
452 | |||
453 | /* announce possible partitions */ | ||
454 | for (i = 1; i < disk->minors; i++) { | ||
455 | p = disk->part[i-1]; | ||
456 | if (!p || !p->nr_sects) | ||
457 | continue; | ||
458 | kobject_uevent(&p->kobj, KOBJ_ADD); | ||
459 | } | ||
433 | } | 460 | } |
434 | 461 | ||
435 | int rescan_partitions(struct gendisk *disk, struct block_device *bdev) | 462 | int rescan_partitions(struct gendisk *disk, struct block_device *bdev) |