Skip to content
This repository has been archived by the owner on Aug 27, 2022. It is now read-only.

Commit

Permalink
firmware_class: Rework usermodehelper check
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rjwysocki committed Mar 28, 2012
1 parent 9a4768d commit fe2e39d
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 22 deletions.
11 changes: 5 additions & 6 deletions drivers/base/firmware_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 2 additions & 3 deletions include/linux/kmod.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */
24 changes: 11 additions & 13 deletions kernel/kmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit fe2e39d

Please sign in to comment.