diff options
Diffstat (limited to 'kernel/params.c')
| -rw-r--r-- | kernel/params.c | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/kernel/params.c b/kernel/params.c index de273ec85bd2..7f6912ced2ba 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
| @@ -24,9 +24,6 @@ | |||
| 24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | 26 | ||
| 27 | /* We abuse the high bits of "perm" to record whether we kmalloc'ed. */ | ||
| 28 | #define KPARAM_KMALLOCED 0x80000000 | ||
| 29 | |||
| 30 | #if 0 | 27 | #if 0 |
| 31 | #define DEBUGP printk | 28 | #define DEBUGP printk |
| 32 | #else | 29 | #else |
| @@ -220,13 +217,13 @@ int param_set_charp(const char *val, struct kernel_param *kp) | |||
| 220 | return -ENOSPC; | 217 | return -ENOSPC; |
| 221 | } | 218 | } |
| 222 | 219 | ||
| 223 | if (kp->perm & KPARAM_KMALLOCED) | 220 | if (kp->flags & KPARAM_KMALLOCED) |
| 224 | kfree(*(char **)kp->arg); | 221 | kfree(*(char **)kp->arg); |
| 225 | 222 | ||
| 226 | /* This is a hack. We can't need to strdup in early boot, and we | 223 | /* This is a hack. We can't need to strdup in early boot, and we |
| 227 | * don't need to; this mangled commandline is preserved. */ | 224 | * don't need to; this mangled commandline is preserved. */ |
| 228 | if (slab_is_available()) { | 225 | if (slab_is_available()) { |
| 229 | kp->perm |= KPARAM_KMALLOCED; | 226 | kp->flags |= KPARAM_KMALLOCED; |
| 230 | *(char **)kp->arg = kstrdup(val, GFP_KERNEL); | 227 | *(char **)kp->arg = kstrdup(val, GFP_KERNEL); |
| 231 | if (!kp->arg) | 228 | if (!kp->arg) |
| 232 | return -ENOMEM; | 229 | return -ENOMEM; |
| @@ -241,44 +238,63 @@ int param_get_charp(char *buffer, struct kernel_param *kp) | |||
| 241 | return sprintf(buffer, "%s", *((char **)kp->arg)); | 238 | return sprintf(buffer, "%s", *((char **)kp->arg)); |
| 242 | } | 239 | } |
| 243 | 240 | ||
| 241 | /* Actually could be a bool or an int, for historical reasons. */ | ||
| 244 | int param_set_bool(const char *val, struct kernel_param *kp) | 242 | int param_set_bool(const char *val, struct kernel_param *kp) |
| 245 | { | 243 | { |
| 244 | bool v; | ||
| 245 | |||
| 246 | /* No equals means "set"... */ | 246 | /* No equals means "set"... */ |
| 247 | if (!val) val = "1"; | 247 | if (!val) val = "1"; |
| 248 | 248 | ||
| 249 | /* One of =[yYnN01] */ | 249 | /* One of =[yYnN01] */ |
| 250 | switch (val[0]) { | 250 | switch (val[0]) { |
| 251 | case 'y': case 'Y': case '1': | 251 | case 'y': case 'Y': case '1': |
| 252 | *(int *)kp->arg = 1; | 252 | v = true; |
| 253 | return 0; | 253 | break; |
| 254 | case 'n': case 'N': case '0': | 254 | case 'n': case 'N': case '0': |
| 255 | *(int *)kp->arg = 0; | 255 | v = false; |
| 256 | return 0; | 256 | break; |
| 257 | default: | ||
| 258 | return -EINVAL; | ||
| 257 | } | 259 | } |
| 258 | return -EINVAL; | 260 | |
| 261 | if (kp->flags & KPARAM_ISBOOL) | ||
| 262 | *(bool *)kp->arg = v; | ||
| 263 | else | ||
| 264 | *(int *)kp->arg = v; | ||
| 265 | return 0; | ||
| 259 | } | 266 | } |
| 260 | 267 | ||
| 261 | int param_get_bool(char *buffer, struct kernel_param *kp) | 268 | int param_get_bool(char *buffer, struct kernel_param *kp) |
| 262 | { | 269 | { |
| 270 | bool val; | ||
| 271 | if (kp->flags & KPARAM_ISBOOL) | ||
| 272 | val = *(bool *)kp->arg; | ||
| 273 | else | ||
| 274 | val = *(int *)kp->arg; | ||
| 275 | |||
| 263 | /* Y and N chosen as being relatively non-coder friendly */ | 276 | /* Y and N chosen as being relatively non-coder friendly */ |
| 264 | return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'Y' : 'N'); | 277 | return sprintf(buffer, "%c", val ? 'Y' : 'N'); |
| 265 | } | 278 | } |
| 266 | 279 | ||
| 280 | /* This one must be bool. */ | ||
| 267 | int param_set_invbool(const char *val, struct kernel_param *kp) | 281 | int param_set_invbool(const char *val, struct kernel_param *kp) |
| 268 | { | 282 | { |
| 269 | int boolval, ret; | 283 | int ret; |
| 284 | bool boolval; | ||
| 270 | struct kernel_param dummy; | 285 | struct kernel_param dummy; |
| 271 | 286 | ||
| 272 | dummy.arg = &boolval; | 287 | dummy.arg = &boolval; |
| 288 | dummy.flags = KPARAM_ISBOOL; | ||
| 273 | ret = param_set_bool(val, &dummy); | 289 | ret = param_set_bool(val, &dummy); |
| 274 | if (ret == 0) | 290 | if (ret == 0) |
| 275 | *(int *)kp->arg = !boolval; | 291 | *(bool *)kp->arg = !boolval; |
| 276 | return ret; | 292 | return ret; |
| 277 | } | 293 | } |
| 278 | 294 | ||
| 279 | int param_get_invbool(char *buffer, struct kernel_param *kp) | 295 | int param_get_invbool(char *buffer, struct kernel_param *kp) |
| 280 | { | 296 | { |
| 281 | return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'N' : 'Y'); | 297 | return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y'); |
| 282 | } | 298 | } |
| 283 | 299 | ||
| 284 | /* We break the rule and mangle the string. */ | 300 | /* We break the rule and mangle the string. */ |
| @@ -591,7 +607,7 @@ void destroy_params(const struct kernel_param *params, unsigned num) | |||
| 591 | unsigned int i; | 607 | unsigned int i; |
| 592 | 608 | ||
| 593 | for (i = 0; i < num; i++) | 609 | for (i = 0; i < num; i++) |
| 594 | if (params[i].perm & KPARAM_KMALLOCED) | 610 | if (params[i].flags & KPARAM_KMALLOCED) |
| 595 | kfree(*(char **)params[i].arg); | 611 | kfree(*(char **)params[i].arg); |
| 596 | } | 612 | } |
| 597 | 613 | ||
