aboutsummaryrefslogtreecommitdiffstats
path: root/fs/partitions/check.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/partitions/check.c')
-rw-r--r--fs/partitions/check.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index af0cb4b9e784..7ef1f094de91 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
337void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) 339void 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
449exit:
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
435int rescan_partitions(struct gendisk *disk, struct block_device *bdev) 462int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
@@ -506,6 +533,7 @@ void del_gendisk(struct gendisk *disk)
506 533
507 devfs_remove_disk(disk); 534 devfs_remove_disk(disk);
508 535
536 kobject_uevent(&disk->kobj, KOBJ_REMOVE);
509 if (disk->holder_dir) 537 if (disk->holder_dir)
510 kobject_unregister(disk->holder_dir); 538 kobject_unregister(disk->holder_dir);
511 if (disk->slave_dir) 539 if (disk->slave_dir)
@@ -518,7 +546,7 @@ void del_gendisk(struct gendisk *disk)
518 kfree(disk_name); 546 kfree(disk_name);
519 } 547 }
520 put_device(disk->driverfs_dev); 548 put_device(disk->driverfs_dev);
549 disk->driverfs_dev = NULL;
521 } 550 }
522 kobject_uevent(&disk->kobj, KOBJ_REMOVE);
523 kobject_del(&disk->kobj); 551 kobject_del(&disk->kobj);
524} 552}