Commit ab013c5f60b7ead254863c75b9adc2a47992d01b

Authored by Steven Rostedt
Committed by Rusty Russell
1 parent 7cb14ba75d

module: Add flag to allow mod params to have no arguments

Currently the params.c code allows only two "set" functions to have
no arguments. If a parameter does not have an argument, then it
looks at the set function and tests if it is either param_set_bool()
or param_set_bint(). If it is not one of these functions, then it
fails the loading of the module.

But there may be module parameters that have different set functions
and still allow no arguments. But unless each of these cases adds
their function to the if statement, it wont be allowed to have no
arguments. This method gets rather messing and does not scale.

Instead, introduce a flags field to the kernel_param_ops, where if
the flag KERNEL_PARAM_FL_NOARG is set, the parameter will not fail
if it does not contain an argument. It will be expected that the
corresponding set function can handle a NULL pointer as "val".

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

Showing 2 changed files with 16 additions and 3 deletions Side-by-side Diff

include/linux/moduleparam.h
... ... @@ -36,7 +36,18 @@
36 36  
37 37 struct kernel_param;
38 38  
  39 +/*
  40 + * Flags available for kernel_param_ops
  41 + *
  42 + * NOARG - the parameter allows for no argument (foo instead of foo=1)
  43 + */
  44 +enum {
  45 + KERNEL_PARAM_FL_NOARG = (1 << 0)
  46 +};
  47 +
39 48 struct kernel_param_ops {
  49 + /* How the ops should behave */
  50 + unsigned int flags;
40 51 /* Returns 0, or -errno. arg is in kp->arg. */
41 52 int (*set)(const char *val, const struct kernel_param *kp);
42 53 /* Returns length written or -errno. Buffer is 4k (ie. be short!) */
... ... @@ -187,7 +198,7 @@
187 198 /* Obsolete - use module_param_cb() */
188 199 #define module_param_call(name, set, get, arg, perm) \
189 200 static struct kernel_param_ops __param_ops_##name = \
190   - { (void *)set, (void *)get }; \
  201 + { 0, (void *)set, (void *)get }; \
191 202 __module_param_call(MODULE_PARAM_PREFIX, \
192 203 name, &__param_ops_##name, arg, \
193 204 (perm) + sizeof(__check_old_set_param(set))*0, -1)
... ... @@ -103,8 +103,8 @@
103 103 || params[i].level > max_level)
104 104 return 0;
105 105 /* No one handled NULL, so do it here. */
106   - if (!val && params[i].ops->set != param_set_bool
107   - && params[i].ops->set != param_set_bint)
  106 + if (!val &&
  107 + !(params[i].ops->flags & KERNEL_PARAM_FL_NOARG))
108 108 return -EINVAL;
109 109 pr_debug("handling %s with %p\n", param,
110 110 params[i].ops->set);
... ... @@ -320,6 +320,7 @@
320 320 EXPORT_SYMBOL(param_get_bool);
321 321  
322 322 struct kernel_param_ops param_ops_bool = {
  323 + .flags = KERNEL_PARAM_FL_NOARG,
323 324 .set = param_set_bool,
324 325 .get = param_get_bool,
325 326 };
... ... @@ -370,6 +371,7 @@
370 371 EXPORT_SYMBOL(param_set_bint);
371 372  
372 373 struct kernel_param_ops param_ops_bint = {
  374 + .flags = KERNEL_PARAM_FL_NOARG,
373 375 .set = param_set_bint,
374 376 .get = param_get_int,
375 377 };