Commit 02bf8fda authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] get_gendisk() prototype change

get_gendisk() now takes dev_t (instead of kdev_t) and gets an additional
argument - int *part.  Set to 0 for non-partitioned, partition number
for partititoned.  Callers updated.  Yes, I hate passing return values
that way ;-/  We need that since old "minor(dev) - disk->first_minor"
doesn't work for stuff with non-trivial numbers (e.g. floppy) and
get_gendisk() really has to return both gendisk and partition number.
Fortunately, amount of callers of gendisk() is about to drop RSN big way...
parent 780ad0f4
......@@ -69,8 +69,7 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
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);
......@@ -82,7 +81,7 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
return -EINVAL;
/* find the drive major */
g = get_gendisk(dev);
g = get_gendisk(bdev->bd_dev, &part);
if (!g)
return -ENXIO;
......@@ -91,6 +90,8 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
/* 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;
......@@ -123,17 +124,19 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
*/
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;
......@@ -142,7 +145,7 @@ int del_partition(struct block_device *bdev, struct blkpg_partition *p)
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) {
......
......@@ -108,13 +108,14 @@ void unlink_gendisk(struct gendisk *disk)
* 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);
......@@ -128,6 +129,7 @@ get_gendisk(kdev_t dev)
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);
......
......@@ -526,6 +526,7 @@ int check_disk_change(struct block_device *bdev)
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;
......@@ -535,7 +536,7 @@ int check_disk_change(struct block_device *bdev)
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)
......@@ -546,11 +547,12 @@ int check_disk_change(struct block_device *bdev)
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);
......@@ -612,26 +614,24 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
__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);
......@@ -665,9 +665,10 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
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;
......@@ -793,12 +794,14 @@ int blkdev_close(struct inode * inode, struct file * filp)
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))
......
......@@ -569,6 +569,7 @@ char *partition_name(dev_t dev)
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);
......@@ -583,10 +584,10 @@ char *partition_name(dev_t dev)
/*
* 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;
......
......@@ -95,7 +95,7 @@ struct gendisk {
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;
......@@ -268,7 +268,8 @@ extern void blk_set_probe(int major, struct gendisk *(p)(int));
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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment