p->ios[0] = p->ios[1] = 0;
p->sectors[0] = p->sectors[1] = 0;
devfs_remove("%s/part%d", disk->devfs_name, part);
+ sysfs_remove_link(&p->kobj, "subsystem");
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)
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);
+ sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem");
partition_sysfs_add_subdir(p);
disk->part[part-1] = p;
}
char *name;
static char *block_str = "block:";
int size;
+ char *s;
size = strlen(block_str) + strlen(disk->disk_name) + 1;
name = kmalloc(size, GFP_KERNEL);
return NULL;
strcpy(name, block_str);
strcat(name, disk->disk_name);
+ /* ewww... some of these buggers have / in name... */
+ s = strchr(name, '/');
+ if (s)
+ *s = '!';
return name;
}
kfree(disk_name);
}
}
+ sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, "subsystem");
}
/* Not exported, helper to add_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);
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 */
/* 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)
sector_t from = state->parts[p].from;
if (!size)
continue;
+ if (from + size > get_capacity(disk)) {
+ printk(" %s: p%d exceeds device capacity\n",
+ disk->disk_name, p);
+ }
add_partition(disk, p, from, size);
#ifdef CONFIG_BLK_DEV_MD
if (state->parts[p].flags)
struct address_space *mapping = bdev->bd_inode->i_mapping;
struct page *page;
- page = read_cache_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)),
- (filler_t *)mapping->a_ops->readpage, NULL);
+ page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)),
+ NULL);
if (!IS_ERR(page)) {
wait_on_page_locked(page);
if (!PageUptodate(page))
devfs_remove_disk(disk);
+ kobject_uevent(&disk->kobj, KOBJ_REMOVE);
if (disk->holder_dir)
kobject_unregister(disk->holder_dir);
if (disk->slave_dir)
kfree(disk_name);
}
put_device(disk->driverfs_dev);
+ disk->driverfs_dev = NULL;
}
- kobject_uevent(&disk->kobj, KOBJ_REMOVE);
+ sysfs_remove_link(&disk->kobj, "subsystem");
kobject_del(&disk->kobj);
}