struct gendisk *g;
long long ppstart, pplength;
long pstart, plength;
- int i;
- kdev_t dev = to_kdev_t(bdev->bd_dev);
+ int part, i;
/* convert bytes to sectors, check for fit in a hd_struct */
ppstart = (p->start >> 9);
return -EINVAL;
/* find the drive major */
- g = get_gendisk(dev);
+ g = get_gendisk(bdev->bd_dev, &part);
if (!g)
return -ENXIO;
/* drive and partition number OK? */
if (bdev != bdev->bd_contains)
return -EINVAL;
+ if (part)
+ BUG();
if (p->pno <= 0 || p->pno >= (1 << g->minor_shift))
return -EINVAL;
*/
int del_partition(struct block_device *bdev, struct blkpg_partition *p)
{
- kdev_t dev = to_kdev_t(bdev->bd_dev);
struct gendisk *g;
struct block_device *bdevp;
+ int part;
int holder;
/* find the drive major */
- g = get_gendisk(dev);
+ g = get_gendisk(bdev->bd_dev, &part);
if (!g)
return -ENXIO;
if (bdev != bdev->bd_contains)
return -EINVAL;
+ if (part)
+ BUG();
if (p->pno <= 0 || p->pno >= (1 << g->minor_shift))
return -EINVAL;
return -ENXIO;
/* partition in use? Incomplete check for now. */
- bdevp = bdget(MKDEV(major(dev), minor(dev) + p->pno));
+ bdevp = bdget(MKDEV(g->major, g->first_minor + p->pno));
if (!bdevp)
return -ENOMEM;
if (bd_claim(bdevp, &holder) < 0) {
* information for the given device @dev.
*/
struct gendisk *
-get_gendisk(kdev_t dev)
+get_gendisk(dev_t dev, int *part)
{
struct gendisk *disk;
struct list_head *p;
- int major = major(dev);
- int minor = minor(dev);
+ int major = MAJOR(dev);
+ int minor = MINOR(dev);
+ *part = 0;
read_lock(&gendisk_lock);
if (gendisks[major].get) {
disk = gendisks[major].get(minor);
if (disk->first_minor + (1<<disk->minor_shift) <= minor)
continue;
read_unlock(&gendisk_lock);
+ *part = minor - disk->first_minor;
return disk;
}
read_unlock(&gendisk_lock);
struct block_device_operations * bdops = bdev->bd_op;
kdev_t dev = to_kdev_t(bdev->bd_dev);
struct gendisk *disk;
+ int part;
if (bdops->check_media_change == NULL)
return 0;
if (invalidate_device(dev, 0))
printk("VFS: busy inodes on changed media.\n");
- disk = get_gendisk(dev);
+ disk = get_gendisk(bdev->bd_dev, &part);
if (bdops->revalidate)
bdops->revalidate(dev);
if (disk && disk->minor_shift)
int full_check_disk_change(struct block_device *bdev)
{
int res = 0;
+ int n;
if (bdev->bd_contains != bdev)
BUG();
down(&bdev->bd_sem);
if (check_disk_change(bdev)) {
- rescan_partitions(get_gendisk(to_kdev_t(bdev->bd_dev)), bdev);
+ rescan_partitions(get_gendisk(bdev->bd_dev, &n), bdev);
res = 1;
}
up(&bdev->bd_sem);
__MOD_DEC_USE_COUNT(owner);
}
if (!bdev->bd_contains) {
- unsigned minor = minor(dev);
- struct gendisk *g = get_gendisk(dev);
+ int part;
+ struct gendisk *g = get_gendisk(bdev->bd_dev, &part);
bdev->bd_contains = bdev;
- if (g) {
- unsigned minor0 = g->first_minor;
- if (minor != minor0) {
- struct block_device *disk;
- disk = bdget(MKDEV(major(dev), minor0));
- ret = -ENOMEM;
- if (!disk)
- goto out1;
- ret = blkdev_get(disk, file->f_mode, file->f_flags, BDEV_RAW);
- if (ret)
- goto out1;
- bdev->bd_contains = disk;
- }
+ if (g && part) {
+ struct block_device *disk;
+ disk = bdget(MKDEV(g->major, g->first_minor));
+ ret = -ENOMEM;
+ if (!disk)
+ goto out1;
+ ret = blkdev_get(disk, file->f_mode, file->f_flags, BDEV_RAW);
+ if (ret)
+ goto out1;
+ bdev->bd_contains = disk;
}
}
if (bdev->bd_contains == bdev) {
- struct gendisk *g = get_gendisk(dev);
+ int part;
+ struct gendisk *g = get_gendisk(bdev->bd_dev, &part);
if (!bdev->bd_queue) {
struct blk_dev_struct *p = blk_dev + major(dev);
down(&bdev->bd_contains->bd_sem);
bdev->bd_contains->bd_part_count++;
if (!bdev->bd_openers) {
- struct gendisk *g = get_gendisk(dev);
+ int part;
+ struct gendisk *g = get_gendisk(bdev->bd_dev, &part);
struct hd_struct *p;
- p = g->part + minor(dev) - g->first_minor - 1;
+ p = g->part + part - 1;
inode->i_data.backing_dev_info =
bdev->bd_inode->i_data.backing_dev_info =
bdev->bd_contains->bd_inode->i_data.backing_dev_info;
static int blkdev_reread_part(struct block_device *bdev)
{
- kdev_t dev = to_kdev_t(bdev->bd_dev);
- struct gendisk *disk = get_gendisk(dev);
+ int part;
+ struct gendisk *disk = get_gendisk(bdev->bd_dev, &part);
int res = 0;
if (!disk || !disk->minor_shift || bdev != bdev->bd_contains)
return -EINVAL;
+ if (part)
+ BUG();
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (down_trylock(&bdev->bd_sem))
static char nomem [] = "<nomem>";
struct dev_name *dname;
struct list_head *tmp;
+ int part;
list_for_each(tmp, &device_names) {
dname = list_entry(tmp, struct dev_name, list);
/*
* ok, add this new device name to the list
*/
- hd = get_gendisk(to_kdev_t(dev));
+ hd = get_gendisk(dev, &part);
dname->name = NULL;
if (hd)
- dname->name = disk_name(hd, MINOR(dev)-hd->first_minor, dname->namebuf);
+ dname->name = disk_name(hd, part, dname->namebuf);
if (!dname->name) {
sprintf(dname->namebuf, "[dev %s]", kdevname(to_kdev_t(dev)));
dname->name = dname->namebuf;
extern void add_disk(struct gendisk *disk);
extern void del_gendisk(struct gendisk *gp);
extern void unlink_gendisk(struct gendisk *gp);
-extern struct gendisk *get_gendisk(kdev_t dev);
+extern struct gendisk *get_gendisk(dev_t dev, int *part);
static inline unsigned long get_start_sect(struct block_device *bdev)
{
return bdev->bd_offset;
static inline unsigned int disk_index (kdev_t dev)
{
- struct gendisk *g = get_gendisk(dev);
+ int part;
+ struct gendisk *g = get_gendisk(kdev_t_to_nr(dev), &part);
return g ? (minor(dev) >> g->minor_shift) : 0;
}