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) | 
