From fe2e39d8782d885755139304d8dba0b3e5bfa878 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 28 Mar 2012 23:29:45 +0200 Subject: 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 Acked-by: Greg Kroah-Hartman Cc: stable@vger.kernel.org --- drivers/base/firmware_class.c | 11 +++++------ include/linux/kmod.h | 5 ++--- 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, return 0; } - read_lock_usermodehelper(); - - if (WARN_ON(usermodehelper_is_disabled())) { + retval = usermodehelper_read_trylock(); + if (WARN_ON(retval)) { dev_err(device, "firmware: %s will not be loaded\n", name); - retval = -EBUSY; - goto out; + goto out_nolock; } if (uevent) @@ -573,8 +571,9 @@ static int _request_firmware(const struct firmware **firmware_p, fw_destroy_instance(fw_priv); out: - read_unlock_usermodehelper(); + usermodehelper_read_unlock(); +out_nolock: if (retval) { release_firmware(firmware); *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); extern int usermodehelper_disable(void); extern void usermodehelper_enable(void); -extern bool usermodehelper_is_disabled(void); -extern void read_lock_usermodehelper(void); -extern void read_unlock_usermodehelper(void); +extern int usermodehelper_read_trylock(void); +extern void usermodehelper_read_unlock(void); #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); */ #define RUNNING_HELPERS_TIMEOUT (5 * HZ) -void read_lock_usermodehelper(void) +int usermodehelper_read_trylock(void) { + int ret = 0; + down_read(&umhelper_sem); + if (usermodehelper_disabled) { + up_read(&umhelper_sem); + ret = -EAGAIN; + } + return ret; } -EXPORT_SYMBOL_GPL(read_lock_usermodehelper); +EXPORT_SYMBOL_GPL(usermodehelper_read_trylock); -void read_unlock_usermodehelper(void) +void usermodehelper_read_unlock(void) { up_read(&umhelper_sem); } -EXPORT_SYMBOL_GPL(read_unlock_usermodehelper); +EXPORT_SYMBOL_GPL(usermodehelper_read_unlock); /** * usermodehelper_disable - prevent new helpers from being started @@ -390,15 +397,6 @@ void usermodehelper_enable(void) up_write(&umhelper_sem); } -/** - * usermodehelper_is_disabled - check if new helpers are allowed to be started - */ -bool usermodehelper_is_disabled(void) -{ - return usermodehelper_disabled; -} -EXPORT_SYMBOL_GPL(usermodehelper_is_disabled); - static void helper_lock(void) { atomic_inc(&running_helpers); -- cgit