aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kmod.c')
-rw-r--r--kernel/kmod.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 4079ac1d5e79..da7fcca279f9 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -334,6 +334,12 @@ static atomic_t running_helpers = ATOMIC_INIT(0);
334static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq); 334static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq);
335 335
336/* 336/*
337 * Used by usermodehelper_read_lock_wait() to wait for usermodehelper_disabled
338 * to become 'false'.
339 */
340static DECLARE_WAIT_QUEUE_HEAD(usermodehelper_disabled_waitq);
341
342/*
337 * Time to wait for running_helpers to become zero before the setting of 343 * Time to wait for running_helpers to become zero before the setting of
338 * usermodehelper_disabled in usermodehelper_disable() fails 344 * usermodehelper_disabled in usermodehelper_disable() fails
339 */ 345 */
@@ -352,6 +358,33 @@ int usermodehelper_read_trylock(void)
352} 358}
353EXPORT_SYMBOL_GPL(usermodehelper_read_trylock); 359EXPORT_SYMBOL_GPL(usermodehelper_read_trylock);
354 360
361long usermodehelper_read_lock_wait(long timeout)
362{
363 DEFINE_WAIT(wait);
364
365 if (timeout < 0)
366 return -EINVAL;
367
368 down_read(&umhelper_sem);
369 for (;;) {
370 prepare_to_wait(&usermodehelper_disabled_waitq, &wait,
371 TASK_UNINTERRUPTIBLE);
372 if (!usermodehelper_disabled)
373 break;
374
375 up_read(&umhelper_sem);
376
377 timeout = schedule_timeout(timeout);
378 if (!timeout)
379 break;
380
381 down_read(&umhelper_sem);
382 }
383 finish_wait(&usermodehelper_disabled_waitq, &wait);
384 return timeout;
385}
386EXPORT_SYMBOL_GPL(usermodehelper_read_lock_wait);
387
355void usermodehelper_read_unlock(void) 388void usermodehelper_read_unlock(void)
356{ 389{
357 up_read(&umhelper_sem); 390 up_read(&umhelper_sem);
@@ -359,6 +392,17 @@ void usermodehelper_read_unlock(void)
359EXPORT_SYMBOL_GPL(usermodehelper_read_unlock); 392EXPORT_SYMBOL_GPL(usermodehelper_read_unlock);
360 393
361/** 394/**
395 * usermodehelper_enable - allow new helpers to be started again
396 */
397void usermodehelper_enable(void)
398{
399 down_write(&umhelper_sem);
400 usermodehelper_disabled = 0;
401 wake_up(&usermodehelper_disabled_waitq);
402 up_write(&umhelper_sem);
403}
404
405/**
362 * usermodehelper_disable - prevent new helpers from being started 406 * usermodehelper_disable - prevent new helpers from being started
363 */ 407 */
364int usermodehelper_disable(void) 408int usermodehelper_disable(void)
@@ -381,22 +425,10 @@ int usermodehelper_disable(void)
381 if (retval) 425 if (retval)
382 return 0; 426 return 0;
383 427
384 down_write(&umhelper_sem); 428 usermodehelper_enable();
385 usermodehelper_disabled = 0;
386 up_write(&umhelper_sem);
387 return -EAGAIN; 429 return -EAGAIN;
388} 430}
389 431
390/**
391 * usermodehelper_enable - allow new helpers to be started again
392 */
393void usermodehelper_enable(void)
394{
395 down_write(&umhelper_sem);
396 usermodehelper_disabled = 0;
397 up_write(&umhelper_sem);
398}
399
400static void helper_lock(void) 432static void helper_lock(void)
401{ 433{
402 atomic_inc(&running_helpers); 434 atomic_inc(&running_helpers);