Commit 7bc4777d authored by Andrew Morton's avatar Andrew Morton Committed by Jeff Garzik

[PATCH] remove MAX_BLKDEV from genhd.c

Patch from Andries.Brouwer@cwi.nl

A patch for genhd.c:

- removed outdated comments
- removed MAX_BLKDEV

In genhd.c the variable MAX_BLKDEV was only the size of a hash
table, so I made it MAX_PROBE_HASH. It can be 1, or 23, or 256, or
whatever one wants.

Note that the current setup requires that every device number
in a given range is mapped by dev_to_index() to the same index
in the hash table, so this routine will have to be adapted in
case one wants to register multimajor ranges.

Discussion is possible about whether struct blk_probe needs
a dev_t or a kdev_t, but I left things this time.

If a range can end at precisely the end of [k]dev_t space,
the old code was wrong since (p->dev + p->range) would be 0.
That is why "p->dev + p->range <= dev" was replaced by
"p->dev + p->range - 1 < dev".
parent 51040fa7
/*
* Code extracted from
* linux/kernel/hd.c
*
* Copyright (C) 1991-1998 Linus Torvalds
*
* devfs support - jj, rgooch, 980122
*
* Moved partition checking code to fs/partitions* - Russell King
* (linux@arm.uk.linux.org)
*/
/*
* TODO: rip out the remaining init crap from this file --hch
* gendisk handling
*/
#include <linux/config.h>
......@@ -29,8 +17,9 @@
static struct subsystem block_subsys;
#define MAX_PROBE_HASH 23 /* random */
struct blk_probe {
static struct blk_probe {
struct blk_probe *next;
dev_t dev;
unsigned long range;
......@@ -38,21 +27,27 @@ struct blk_probe {
struct gendisk *(*get)(dev_t dev, int *part, void *data);
int (*lock)(dev_t, void *);
void *data;
} *probes[MAX_BLKDEV];
} *probes[MAX_PROBE_HASH];
/* index in the above */
/* index in the above - for now: assume no multimajor ranges */
static inline int dev_to_index(dev_t dev)
{
return MAJOR(dev);
return MAJOR(dev) % MAX_PROBE_HASH;
}
/*
* Register device numbers dev..(dev+range-1)
* range must be nonzero
* The hash chain is sorted on range, so that subranges can override.
*/
void blk_register_region(dev_t dev, unsigned long range, struct module *module,
struct gendisk *(*probe)(dev_t, int *, void *),
int (*lock)(dev_t, void *), void *data)
struct gendisk *(*probe)(dev_t, int *, void *),
int (*lock)(dev_t, void *), void *data)
{
int index = dev_to_index(dev);
struct blk_probe *p = kmalloc(sizeof(struct blk_probe), GFP_KERNEL);
struct blk_probe **s;
p->owner = module;
p->get = probe;
p->lock = lock;
......@@ -71,6 +66,7 @@ void blk_unregister_region(dev_t dev, unsigned long range)
{
int index = dev_to_index(dev);
struct blk_probe **s;
down_write(&block_subsys.rwsem);
for (s = &probes[index]; *s; s = &(*s)->next) {
struct blk_probe *p = *s;
......@@ -94,6 +90,7 @@ static struct gendisk *exact_match(dev_t dev, int *part, void *data)
static int exact_lock(dev_t dev, void *data)
{
struct gendisk *p = data;
if (!get_disk(p))
return -1;
return 0;
......@@ -109,14 +106,14 @@ static int exact_lock(dev_t dev, void *data)
void add_disk(struct gendisk *disk)
{
disk->flags |= GENHD_FL_UP;
blk_register_region(MKDEV(disk->major, disk->first_minor), disk->minors,
NULL, exact_match, exact_lock, disk);
blk_register_region(MKDEV(disk->major, disk->first_minor),
disk->minors, NULL, exact_match, exact_lock, disk);
register_disk(disk);
elv_register_queue(disk);
}
EXPORT_SYMBOL(add_disk);
EXPORT_SYMBOL(del_gendisk);
EXPORT_SYMBOL(del_gendisk); /* in partitions/check.c */
void unlink_gendisk(struct gendisk *disk)
{
......@@ -146,18 +143,17 @@ get_gendisk(dev_t dev, int *part)
struct gendisk *(*probe)(dev_t, int *, void *);
struct module *owner;
void *data;
if (p->dev > dev || p->dev + p->range <= dev)
if (p->dev > dev || p->dev + p->range - 1 < dev)
continue;
if (p->range >= best) {
up_read(&block_subsys.rwsem);
return NULL;
}
if (p->range - 1 >= best)
break;
if (!try_module_get(p->owner))
continue;
owner = p->owner;
data = p->data;
probe = p->get;
best = p->range;
best = p->range - 1;
*part = dev - p->dev;
if (p->lock && p->lock(dev, data) < 0) {
module_put(owner);
......@@ -169,7 +165,7 @@ get_gendisk(dev_t dev, int *part)
module_put(owner);
if (disk)
return disk;
goto retry;
goto retry; /* this terminates: best decreases */
}
up_read(&block_subsys.rwsem);
return NULL;
......@@ -245,7 +241,7 @@ extern int blk_dev_init(void);
static struct gendisk *base_probe(dev_t dev, int *part, void *data)
{
char name[20];
char name[30];
sprintf(name, "block-major-%d", MAJOR(dev));
request_module(name);
return NULL;
......@@ -256,11 +252,11 @@ int __init device_init(void)
struct blk_probe *base = kmalloc(sizeof(struct blk_probe), GFP_KERNEL);
int i;
memset(base, 0, sizeof(struct blk_probe));
base->dev = MKDEV(1,0);
base->range = MKDEV(MAX_BLKDEV-1, 255) - base->dev + 1;
base->dev = 1;
base->range = ~0; /* range 1 .. ~0 */
base->get = base_probe;
for (i = 1; i < MAX_BLKDEV; i++)
probes[i] = base;
for (i = 0; i < MAX_PROBE_HASH; i++)
probes[i] = base; /* must remain last in chain */
blk_dev_init();
subsystem_register(&block_subsys);
return 0;
......@@ -281,12 +277,14 @@ struct disk_attribute {
ssize_t (*show)(struct gendisk *, char *);
};
static ssize_t disk_attr_show(struct kobject * kobj, struct attribute * attr,
char * page)
static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
char *page)
{
struct gendisk * disk = to_disk(kobj);
struct disk_attribute * disk_attr = container_of(attr,struct disk_attribute,attr);
struct gendisk *disk = to_disk(kobj);
struct disk_attribute *disk_attr =
container_of(attr,struct disk_attribute,attr);
ssize_t ret = 0;
if (disk_attr->show)
ret = disk_attr->show(disk,page);
return ret;
......@@ -303,11 +301,11 @@ static ssize_t disk_dev_read(struct gendisk * disk, char *page)
}
static ssize_t disk_range_read(struct gendisk * disk, char *page)
{
return sprintf(page, "%d\n",disk->minors);
return sprintf(page, "%d\n", disk->minors);
}
static ssize_t disk_size_read(struct gendisk * disk, char *page)
{
return sprintf(page, "%llu\n",(unsigned long long)get_capacity(disk));
return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
}
static inline unsigned jiffies_to_msec(unsigned jif)
......
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