]>
Commit | Line | Data |
---|---|---|
4d1e5b62 AF |
1 | From: Jan Kara <jack@suse.cz> |
2 | Subject: Allow setting of number of raw devices as a module parameter | |
3 | References: FATE 302178 | |
4 | Patch-mainline: never | |
5 | ||
6 | Allow setting of maximal number of raw devices as a module parameter. This requires | |
7 | changing of static array into a vmalloced one (the array is going to be too large | |
8 | for kmalloc). | |
9 | ||
10 | Signed-off-by: Jan Kara <jack@suse.cz> | |
11 | ||
12 | --- | |
13 | drivers/char/Kconfig | 2 +- | |
14 | drivers/char/raw.c | 33 +++++++++++++++++++++++++++------ | |
15 | 2 files changed, 28 insertions(+), 7 deletions(-) | |
16 | ||
17 | --- a/drivers/char/Kconfig | |
18 | +++ b/drivers/char/Kconfig | |
19 | @@ -1026,7 +1026,7 @@ config RAW_DRIVER | |
20 | with the O_DIRECT flag. | |
21 | ||
22 | config MAX_RAW_DEVS | |
23 | - int "Maximum number of RAW devices to support (1-8192)" | |
24 | + int "Maximum number of RAW devices to support (1-65536)" | |
25 | depends on RAW_DRIVER | |
26 | default "256" | |
27 | help | |
28 | --- a/drivers/char/raw.c | |
29 | +++ b/drivers/char/raw.c | |
30 | @@ -20,6 +20,7 @@ | |
31 | #include <linux/device.h> | |
32 | #include <linux/mutex.h> | |
33 | #include <linux/smp_lock.h> | |
34 | +#include <linux/vmalloc.h> | |
35 | ||
36 | #include <asm/uaccess.h> | |
37 | ||
38 | @@ -29,10 +30,15 @@ struct raw_device_data { | |
39 | }; | |
40 | ||
41 | static struct class *raw_class; | |
42 | -static struct raw_device_data raw_devices[MAX_RAW_MINORS]; | |
43 | +static struct raw_device_data *raw_devices; | |
44 | static DEFINE_MUTEX(raw_mutex); | |
45 | static const struct file_operations raw_ctl_fops; /* forward declaration */ | |
46 | ||
47 | +static int max_raw_minors = MAX_RAW_MINORS; | |
48 | + | |
49 | +module_param(max_raw_minors, int, 0); | |
50 | +MODULE_PARM_DESC(max_raw_minors, "Maximum number of raw devices (1-65536)"); | |
51 | + | |
52 | /* | |
53 | * Open/close code for raw IO. | |
54 | * | |
55 | @@ -158,7 +164,7 @@ static int raw_ctl_ioctl(struct inode *i | |
56 | goto out; | |
57 | } | |
58 | ||
59 | - if (rq.raw_minor <= 0 || rq.raw_minor >= MAX_RAW_MINORS) { | |
60 | + if (rq.raw_minor <= 0 || rq.raw_minor >= max_raw_minors) { | |
61 | err = -EINVAL; | |
62 | goto out; | |
63 | } | |
64 | @@ -266,12 +272,26 @@ static int __init raw_init(void) | |
65 | dev_t dev = MKDEV(RAW_MAJOR, 0); | |
66 | int ret; | |
67 | ||
68 | - ret = register_chrdev_region(dev, MAX_RAW_MINORS, "raw"); | |
69 | + if (max_raw_minors < 1 || max_raw_minors > 65536) { | |
70 | + printk(KERN_WARNING "raw: invalid max_raw_minors (must be" | |
71 | + " between 1 and 65536), using %d\n", MAX_RAW_MINORS); | |
72 | + max_raw_minors = MAX_RAW_MINORS; | |
73 | + } | |
74 | + | |
75 | + raw_devices = vmalloc(sizeof(struct raw_device_data) * max_raw_minors); | |
76 | + if (!raw_devices) { | |
77 | + printk(KERN_ERR "Not enough memory for raw device structures\n"); | |
78 | + ret = -ENOMEM; | |
79 | + goto error; | |
80 | + } | |
81 | + memset(raw_devices, 0, sizeof(struct raw_device_data) * max_raw_minors); | |
82 | + | |
83 | + ret = register_chrdev_region(dev, max_raw_minors, "raw"); | |
84 | if (ret) | |
85 | goto error; | |
86 | ||
87 | cdev_init(&raw_cdev, &raw_fops); | |
88 | - ret = cdev_add(&raw_cdev, dev, MAX_RAW_MINORS); | |
89 | + ret = cdev_add(&raw_cdev, dev, max_raw_minors); | |
90 | if (ret) { | |
91 | kobject_put(&raw_cdev.kobj); | |
92 | goto error_region; | |
93 | @@ -290,8 +310,9 @@ static int __init raw_init(void) | |
94 | return 0; | |
95 | ||
96 | error_region: | |
97 | - unregister_chrdev_region(dev, MAX_RAW_MINORS); | |
98 | + unregister_chrdev_region(dev, max_raw_minors); | |
99 | error: | |
100 | + vfree(raw_devices); | |
101 | return ret; | |
102 | } | |
103 | ||
104 | @@ -300,7 +321,7 @@ static void __exit raw_exit(void) | |
105 | device_destroy(raw_class, MKDEV(RAW_MAJOR, 0)); | |
106 | class_destroy(raw_class); | |
107 | cdev_del(&raw_cdev); | |
108 | - unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS); | |
109 | + unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), max_raw_minors); | |
110 | } | |
111 | ||
112 | module_init(raw_init); |