firmware_class: Rework usermodehelper check
authorRafael J. Wysocki <rjw@sisk.pl>
Wed, 28 Mar 2012 21:29:45 +0000 (23:29 +0200)
committerRafael J. Wysocki <rjw@sisk.pl>
Wed, 28 Mar 2012 21:29:45 +0000 (23:29 +0200)
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

drivers/base/firmware_class.c
include/linux/kmod.h
kernel/kmod.c

index 6c9387d..deee871 100644 (file)
@@ -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;
index 9efeae6..97d22c3 100644 (file)
@@ -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__ */
index 957a7aa..4079ac1 100644 (file)
@@ -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);