Allow setting of number of raw devices as a module parameter

Allow setting of maximal number of raw devices as a module parameter. This
requires changing of static array into a vmalloced one (the array is going to
be too large for kmalloc).

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Jan Kara 2011-04-29 00:24:29 +02:00 committed by Greg Kroah-Hartman
parent a1d9a09ae8
commit 0078bff528
2 changed files with 28 additions and 7 deletions

View File

@ -523,7 +523,7 @@ config RAW_DRIVER
with the O_DIRECT flag.
config MAX_RAW_DEVS
int "Maximum number of RAW devices to support (1-8192)"
int "Maximum number of RAW devices to support (1-65536)"
depends on RAW_DRIVER
default "256"
help

View File

@ -21,6 +21,7 @@
#include <linux/mutex.h>
#include <linux/gfp.h>
#include <linux/compat.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>
@ -30,10 +31,15 @@ struct raw_device_data {
};
static struct class *raw_class;
static struct raw_device_data raw_devices[MAX_RAW_MINORS];
static struct raw_device_data *raw_devices;
static DEFINE_MUTEX(raw_mutex);
static const struct file_operations raw_ctl_fops; /* forward declaration */
static int max_raw_minors = MAX_RAW_MINORS;
module_param(max_raw_minors, int, 0);
MODULE_PARM_DESC(max_raw_minors, "Maximum number of raw devices (1-65536)");
/*
* Open/close code for raw IO.
*
@ -125,7 +131,7 @@ static int bind_set(int number, u64 major, u64 minor)
struct raw_device_data *rawdev;
int err = 0;
if (number <= 0 || number >= MAX_RAW_MINORS)
if (number <= 0 || number >= max_raw_minors)
return -EINVAL;
if (MAJOR(dev) != major || MINOR(dev) != minor)
@ -312,12 +318,26 @@ static int __init raw_init(void)
dev_t dev = MKDEV(RAW_MAJOR, 0);
int ret;
ret = register_chrdev_region(dev, MAX_RAW_MINORS, "raw");
if (max_raw_minors < 1 || max_raw_minors > 65536) {
printk(KERN_WARNING "raw: invalid max_raw_minors (must be"
" between 1 and 65536), using %d\n", MAX_RAW_MINORS);
max_raw_minors = MAX_RAW_MINORS;
}
raw_devices = vmalloc(sizeof(struct raw_device_data) * max_raw_minors);
if (!raw_devices) {
printk(KERN_ERR "Not enough memory for raw device structures\n");
ret = -ENOMEM;
goto error;
}
memset(raw_devices, 0, sizeof(struct raw_device_data) * max_raw_minors);
ret = register_chrdev_region(dev, max_raw_minors, "raw");
if (ret)
goto error;
cdev_init(&raw_cdev, &raw_fops);
ret = cdev_add(&raw_cdev, dev, MAX_RAW_MINORS);
ret = cdev_add(&raw_cdev, dev, max_raw_minors);
if (ret) {
kobject_put(&raw_cdev.kobj);
goto error_region;
@ -336,8 +356,9 @@ static int __init raw_init(void)
return 0;
error_region:
unregister_chrdev_region(dev, MAX_RAW_MINORS);
unregister_chrdev_region(dev, max_raw_minors);
error:
vfree(raw_devices);
return ret;
}
@ -346,7 +367,7 @@ static void __exit raw_exit(void)
device_destroy(raw_class, MKDEV(RAW_MAJOR, 0));
class_destroy(raw_class);
cdev_del(&raw_cdev);
unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS);
unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), max_raw_minors);
}
module_init(raw_init);