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) ...@@ -69,8 +69,7 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
struct gendisk *g; struct gendisk *g;
long long ppstart, pplength; long long ppstart, pplength;
long pstart, plength; long pstart, plength;
int i; int part, i;
kdev_t dev = to_kdev_t(bdev->bd_dev);
/* convert bytes to sectors, check for fit in a hd_struct */ /* convert bytes to sectors, check for fit in a hd_struct */
ppstart = (p->start >> 9); ppstart = (p->start >> 9);
...@@ -82,7 +81,7 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p) ...@@ -82,7 +81,7 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
return -EINVAL; return -EINVAL;
/* find the drive major */ /* find the drive major */
g = get_gendisk(dev); g = get_gendisk(bdev->bd_dev, &part);
if (!g) if (!g)
return -ENXIO; return -ENXIO;
...@@ -91,6 +90,8 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p) ...@@ -91,6 +90,8 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
/* drive and partition number OK? */ /* drive and partition number OK? */
if (bdev != bdev->bd_contains) if (bdev != bdev->bd_contains)
return -EINVAL; return -EINVAL;
if (part)
BUG();
if (p->pno <= 0 || p->pno >= (1 << g->minor_shift)) if (p->pno <= 0 || p->pno >= (1 << g->minor_shift))
return -EINVAL; return -EINVAL;
...@@ -123,17 +124,19 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p) ...@@ -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) int del_partition(struct block_device *bdev, struct blkpg_partition *p)
{ {
kdev_t dev = to_kdev_t(bdev->bd_dev);
struct gendisk *g; struct gendisk *g;
struct block_device *bdevp; struct block_device *bdevp;
int part;
int holder; int holder;
/* find the drive major */ /* find the drive major */
g = get_gendisk(dev); g = get_gendisk(bdev->bd_dev, &part);
if (!g) if (!g)
return -ENXIO; return -ENXIO;
if (bdev != bdev->bd_contains) if (bdev != bdev->bd_contains)
return -EINVAL; return -EINVAL;
if (part)
BUG();
if (p->pno <= 0 || p->pno >= (1 << g->minor_shift)) if (p->pno <= 0 || p->pno >= (1 << g->minor_shift))
return -EINVAL; return -EINVAL;
...@@ -142,7 +145,7 @@ int del_partition(struct block_device *bdev, struct blkpg_partition *p) ...@@ -142,7 +145,7 @@ int del_partition(struct block_device *bdev, struct blkpg_partition *p)
return -ENXIO; return -ENXIO;
/* partition in use? Incomplete check for now. */ /* 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) if (!bdevp)
return -ENOMEM; return -ENOMEM;
if (bd_claim(bdevp, &holder) < 0) { if (bd_claim(bdevp, &holder) < 0) {
......
...@@ -108,13 +108,14 @@ void unlink_gendisk(struct gendisk *disk) ...@@ -108,13 +108,14 @@ void unlink_gendisk(struct gendisk *disk)
* information for the given device @dev. * information for the given device @dev.
*/ */
struct gendisk * struct gendisk *
get_gendisk(kdev_t dev) get_gendisk(dev_t dev, int *part)
{ {
struct gendisk *disk; struct gendisk *disk;
struct list_head *p; struct list_head *p;
int major = major(dev); int major = MAJOR(dev);
int minor = minor(dev); int minor = MINOR(dev);
*part = 0;
read_lock(&gendisk_lock); read_lock(&gendisk_lock);
if (gendisks[major].get) { if (gendisks[major].get) {
disk = gendisks[major].get(minor); disk = gendisks[major].get(minor);
...@@ -128,6 +129,7 @@ get_gendisk(kdev_t dev) ...@@ -128,6 +129,7 @@ get_gendisk(kdev_t dev)
if (disk->first_minor + (1<<disk->minor_shift) <= minor) if (disk->first_minor + (1<<disk->minor_shift) <= minor)
continue; continue;
read_unlock(&gendisk_lock); read_unlock(&gendisk_lock);
*part = minor - disk->first_minor;
return disk; return disk;
} }
read_unlock(&gendisk_lock); read_unlock(&gendisk_lock);
......
...@@ -526,6 +526,7 @@ int check_disk_change(struct block_device *bdev) ...@@ -526,6 +526,7 @@ int check_disk_change(struct block_device *bdev)
struct block_device_operations * bdops = bdev->bd_op; struct block_device_operations * bdops = bdev->bd_op;
kdev_t dev = to_kdev_t(bdev->bd_dev); kdev_t dev = to_kdev_t(bdev->bd_dev);
struct gendisk *disk; struct gendisk *disk;
int part;
if (bdops->check_media_change == NULL) if (bdops->check_media_change == NULL)
return 0; return 0;
...@@ -535,7 +536,7 @@ int check_disk_change(struct block_device *bdev) ...@@ -535,7 +536,7 @@ int check_disk_change(struct block_device *bdev)
if (invalidate_device(dev, 0)) if (invalidate_device(dev, 0))
printk("VFS: busy inodes on changed media.\n"); printk("VFS: busy inodes on changed media.\n");
disk = get_gendisk(dev); disk = get_gendisk(bdev->bd_dev, &part);
if (bdops->revalidate) if (bdops->revalidate)
bdops->revalidate(dev); bdops->revalidate(dev);
if (disk && disk->minor_shift) if (disk && disk->minor_shift)
...@@ -546,11 +547,12 @@ int check_disk_change(struct block_device *bdev) ...@@ -546,11 +547,12 @@ int check_disk_change(struct block_device *bdev)
int full_check_disk_change(struct block_device *bdev) int full_check_disk_change(struct block_device *bdev)
{ {
int res = 0; int res = 0;
int n;
if (bdev->bd_contains != bdev) if (bdev->bd_contains != bdev)
BUG(); BUG();
down(&bdev->bd_sem); down(&bdev->bd_sem);
if (check_disk_change(bdev)) { 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; res = 1;
} }
up(&bdev->bd_sem); up(&bdev->bd_sem);
...@@ -612,26 +614,24 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file * ...@@ -612,26 +614,24 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
__MOD_DEC_USE_COUNT(owner); __MOD_DEC_USE_COUNT(owner);
} }
if (!bdev->bd_contains) { if (!bdev->bd_contains) {
unsigned minor = minor(dev); int part;
struct gendisk *g = get_gendisk(dev); struct gendisk *g = get_gendisk(bdev->bd_dev, &part);
bdev->bd_contains = bdev; bdev->bd_contains = bdev;
if (g) { if (g && part) {
unsigned minor0 = g->first_minor; struct block_device *disk;
if (minor != minor0) { disk = bdget(MKDEV(g->major, g->first_minor));
struct block_device *disk; ret = -ENOMEM;
disk = bdget(MKDEV(major(dev), minor0)); if (!disk)
ret = -ENOMEM; goto out1;
if (!disk) ret = blkdev_get(disk, file->f_mode, file->f_flags, BDEV_RAW);
goto out1; if (ret)
ret = blkdev_get(disk, file->f_mode, file->f_flags, BDEV_RAW); goto out1;
if (ret) bdev->bd_contains = disk;
goto out1;
bdev->bd_contains = disk;
}
} }
} }
if (bdev->bd_contains == bdev) { 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) { if (!bdev->bd_queue) {
struct blk_dev_struct *p = blk_dev + major(dev); 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 * ...@@ -665,9 +665,10 @@ static int do_open(struct block_device *bdev, struct inode *inode, struct file *
down(&bdev->bd_contains->bd_sem); down(&bdev->bd_contains->bd_sem);
bdev->bd_contains->bd_part_count++; bdev->bd_contains->bd_part_count++;
if (!bdev->bd_openers) { 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; struct hd_struct *p;
p = g->part + minor(dev) - g->first_minor - 1; p = g->part + part - 1;
inode->i_data.backing_dev_info = inode->i_data.backing_dev_info =
bdev->bd_inode->i_data.backing_dev_info = bdev->bd_inode->i_data.backing_dev_info =
bdev->bd_contains->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) ...@@ -793,12 +794,14 @@ int blkdev_close(struct inode * inode, struct file * filp)
static int blkdev_reread_part(struct block_device *bdev) static int blkdev_reread_part(struct block_device *bdev)
{ {
kdev_t dev = to_kdev_t(bdev->bd_dev); int part;
struct gendisk *disk = get_gendisk(dev); struct gendisk *disk = get_gendisk(bdev->bd_dev, &part);
int res = 0; int res = 0;
if (!disk || !disk->minor_shift || bdev != bdev->bd_contains) if (!disk || !disk->minor_shift || bdev != bdev->bd_contains)
return -EINVAL; return -EINVAL;
if (part)
BUG();
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EACCES; return -EACCES;
if (down_trylock(&bdev->bd_sem)) if (down_trylock(&bdev->bd_sem))
......
...@@ -569,6 +569,7 @@ char *partition_name(dev_t dev) ...@@ -569,6 +569,7 @@ char *partition_name(dev_t dev)
static char nomem [] = "<nomem>"; static char nomem [] = "<nomem>";
struct dev_name *dname; struct dev_name *dname;
struct list_head *tmp; struct list_head *tmp;
int part;
list_for_each(tmp, &device_names) { list_for_each(tmp, &device_names) {
dname = list_entry(tmp, struct dev_name, list); dname = list_entry(tmp, struct dev_name, list);
...@@ -583,10 +584,10 @@ char *partition_name(dev_t dev) ...@@ -583,10 +584,10 @@ char *partition_name(dev_t dev)
/* /*
* ok, add this new device name to the 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; dname->name = NULL;
if (hd) 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) { if (!dname->name) {
sprintf(dname->namebuf, "[dev %s]", kdevname(to_kdev_t(dev))); sprintf(dname->namebuf, "[dev %s]", kdevname(to_kdev_t(dev)));
dname->name = dname->namebuf; dname->name = dname->namebuf;
......
...@@ -95,7 +95,7 @@ struct gendisk { ...@@ -95,7 +95,7 @@ struct gendisk {
extern void add_disk(struct gendisk *disk); extern void add_disk(struct gendisk *disk);
extern void del_gendisk(struct gendisk *gp); extern void del_gendisk(struct gendisk *gp);
extern void unlink_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) static inline unsigned long get_start_sect(struct block_device *bdev)
{ {
return bdev->bd_offset; return bdev->bd_offset;
...@@ -268,7 +268,8 @@ extern void blk_set_probe(int major, struct gendisk *(p)(int)); ...@@ -268,7 +268,8 @@ extern void blk_set_probe(int major, struct gendisk *(p)(int));
static inline unsigned int disk_index (kdev_t dev) 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; 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