diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2012-03-28 17:29:45 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-03-28 17:29:45 -0400 |
commit | fe2e39d8782d885755139304d8dba0b3e5bfa878 (patch) | |
tree | 200fb998fe94b9ccd93d07c59656b8f5ab62c5d7 | |
parent | 9a4768d849d28a79566aa37de19b9852d2da8ec4 (diff) |
firmware_class: Rework usermodehelper check
Instead of two functions, read_lock_usermodehelper() and
usermodehelper_is_disabled(), used in combination, introduce
usermodehelper_read_trylock() that will only return with umhelper_sem
held if usermodehelper_disabled is unset (and will return -EAGAIN
otherwise) and make _request_firmware() use it.
Rename read_unlock_usermodehelper() to
usermodehelper_read_unlock() to follow the naming convention of the
new function.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: stable@vger.kernel.org
-rw-r--r-- | drivers/base/firmware_class.c | 11 | ||||
-rw-r--r-- | include/linux/kmod.h | 5 | ||||
-rw-r--r-- | kernel/kmod.c | 24 |
3 files changed, 18 insertions, 22 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 6c9387d646ec..deee871e509c 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -533,12 +533,10 @@ static int _request_firmware(const struct firmware **firmware_p, | |||
533 | return 0; | 533 | return 0; |
534 | } | 534 | } |
535 | 535 | ||
536 | read_lock_usermodehelper(); | 536 | retval = usermodehelper_read_trylock(); |
537 | 537 | if (WARN_ON(retval)) { | |
538 | if (WARN_ON(usermodehelper_is_disabled())) { | ||
539 | dev_err(device, "firmware: %s will not be loaded\n", name); | 538 | dev_err(device, "firmware: %s will not be loaded\n", name); |
540 | retval = -EBUSY; | 539 | goto out_nolock; |
541 | goto out; | ||
542 | } | 540 | } |
543 | 541 | ||
544 | if (uevent) | 542 | if (uevent) |
@@ -573,8 +571,9 @@ static int _request_firmware(const struct firmware **firmware_p, | |||
573 | fw_destroy_instance(fw_priv); | 571 | fw_destroy_instance(fw_priv); |
574 | 572 | ||
575 | out: | 573 | out: |
576 | read_unlock_usermodehelper(); | 574 | usermodehelper_read_unlock(); |
577 | 575 | ||
576 | out_nolock: | ||
578 | if (retval) { | 577 | if (retval) { |
579 | release_firmware(firmware); | 578 | release_firmware(firmware); |
580 | *firmware_p = NULL; | 579 | *firmware_p = NULL; |
diff --git a/include/linux/kmod.h b/include/linux/kmod.h index 9efeae679106..97d22c3e08b1 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h | |||
@@ -114,8 +114,7 @@ extern void usermodehelper_init(void); | |||
114 | 114 | ||
115 | extern int usermodehelper_disable(void); | 115 | extern int usermodehelper_disable(void); |
116 | extern void usermodehelper_enable(void); | 116 | extern void usermodehelper_enable(void); |
117 | extern bool usermodehelper_is_disabled(void); | 117 | extern int usermodehelper_read_trylock(void); |
118 | extern void read_lock_usermodehelper(void); | 118 | extern void usermodehelper_read_unlock(void); |
119 | extern void read_unlock_usermodehelper(void); | ||
120 | 119 | ||
121 | #endif /* __LINUX_KMOD_H__ */ | 120 | #endif /* __LINUX_KMOD_H__ */ |
diff --git a/kernel/kmod.c b/kernel/kmod.c index 957a7aab8ebc..4079ac1d5e79 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -339,17 +339,24 @@ static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq); | |||
339 | */ | 339 | */ |
340 | #define RUNNING_HELPERS_TIMEOUT (5 * HZ) | 340 | #define RUNNING_HELPERS_TIMEOUT (5 * HZ) |
341 | 341 | ||
342 | void read_lock_usermodehelper(void) | 342 | int usermodehelper_read_trylock(void) |
343 | { | 343 | { |
344 | int ret = 0; | ||
345 | |||
344 | down_read(&umhelper_sem); | 346 | down_read(&umhelper_sem); |
347 | if (usermodehelper_disabled) { | ||
348 | up_read(&umhelper_sem); | ||
349 | ret = -EAGAIN; | ||
350 | } | ||
351 | return ret; | ||
345 | } | 352 | } |
346 | EXPORT_SYMBOL_GPL(read_lock_usermodehelper); | 353 | EXPORT_SYMBOL_GPL(usermodehelper_read_trylock); |
347 | 354 | ||
348 | void read_unlock_usermodehelper(void) | 355 | void usermodehelper_read_unlock(void) |
349 | { | 356 | { |
350 | up_read(&umhelper_sem); | 357 | up_read(&umhelper_sem); |
351 | } | 358 | } |
352 | EXPORT_SYMBOL_GPL(read_unlock_usermodehelper); | 359 | EXPORT_SYMBOL_GPL(usermodehelper_read_unlock); |
353 | 360 | ||
354 | /** | 361 | /** |
355 | * usermodehelper_disable - prevent new helpers from being started | 362 | * usermodehelper_disable - prevent new helpers from being started |
@@ -390,15 +397,6 @@ void usermodehelper_enable(void) | |||
390 | up_write(&umhelper_sem); | 397 | up_write(&umhelper_sem); |
391 | } | 398 | } |
392 | 399 | ||
393 | /** | ||
394 | * usermodehelper_is_disabled - check if new helpers are allowed to be started | ||
395 | */ | ||
396 | bool usermodehelper_is_disabled(void) | ||
397 | { | ||
398 | return usermodehelper_disabled; | ||
399 | } | ||
400 | EXPORT_SYMBOL_GPL(usermodehelper_is_disabled); | ||
401 | |||
402 | static void helper_lock(void) | 400 | static void helper_lock(void) |
403 | { | 401 | { |
404 | atomic_inc(&running_helpers); | 402 | atomic_inc(&running_helpers); |