diff options
Diffstat (limited to 'kernel/kmod.c')
-rw-r--r-- | kernel/kmod.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c index d2dce71115d8..78d365c524ed 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -119,7 +119,7 @@ struct subprocess_info { | |||
119 | char **argv; | 119 | char **argv; |
120 | char **envp; | 120 | char **envp; |
121 | struct key *ring; | 121 | struct key *ring; |
122 | int wait; | 122 | enum umh_wait wait; |
123 | int retval; | 123 | int retval; |
124 | struct file *stdin; | 124 | struct file *stdin; |
125 | void (*cleanup)(char **argv, char **envp); | 125 | void (*cleanup)(char **argv, char **envp); |
@@ -225,7 +225,7 @@ static int wait_for_helper(void *data) | |||
225 | sub_info->retval = ret; | 225 | sub_info->retval = ret; |
226 | } | 226 | } |
227 | 227 | ||
228 | if (sub_info->wait < 0) | 228 | if (sub_info->wait == UMH_NO_WAIT) |
229 | call_usermodehelper_freeinfo(sub_info); | 229 | call_usermodehelper_freeinfo(sub_info); |
230 | else | 230 | else |
231 | complete(sub_info->complete); | 231 | complete(sub_info->complete); |
@@ -238,26 +238,31 @@ static void __call_usermodehelper(struct work_struct *work) | |||
238 | struct subprocess_info *sub_info = | 238 | struct subprocess_info *sub_info = |
239 | container_of(work, struct subprocess_info, work); | 239 | container_of(work, struct subprocess_info, work); |
240 | pid_t pid; | 240 | pid_t pid; |
241 | int wait = sub_info->wait; | 241 | enum umh_wait wait = sub_info->wait; |
242 | 242 | ||
243 | /* CLONE_VFORK: wait until the usermode helper has execve'd | 243 | /* CLONE_VFORK: wait until the usermode helper has execve'd |
244 | * successfully We need the data structures to stay around | 244 | * successfully We need the data structures to stay around |
245 | * until that is done. */ | 245 | * until that is done. */ |
246 | if (wait) | 246 | if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT) |
247 | pid = kernel_thread(wait_for_helper, sub_info, | 247 | pid = kernel_thread(wait_for_helper, sub_info, |
248 | CLONE_FS | CLONE_FILES | SIGCHLD); | 248 | CLONE_FS | CLONE_FILES | SIGCHLD); |
249 | else | 249 | else |
250 | pid = kernel_thread(____call_usermodehelper, sub_info, | 250 | pid = kernel_thread(____call_usermodehelper, sub_info, |
251 | CLONE_VFORK | SIGCHLD); | 251 | CLONE_VFORK | SIGCHLD); |
252 | 252 | ||
253 | if (wait < 0) | 253 | switch (wait) { |
254 | return; | 254 | case UMH_NO_WAIT: |
255 | break; | ||
255 | 256 | ||
256 | if (pid < 0) { | 257 | case UMH_WAIT_PROC: |
258 | if (pid > 0) | ||
259 | break; | ||
257 | sub_info->retval = pid; | 260 | sub_info->retval = pid; |
261 | /* FALLTHROUGH */ | ||
262 | |||
263 | case UMH_WAIT_EXEC: | ||
258 | complete(sub_info->complete); | 264 | complete(sub_info->complete); |
259 | } else if (!wait) | 265 | } |
260 | complete(sub_info->complete); | ||
261 | } | 266 | } |
262 | 267 | ||
263 | /** | 268 | /** |
@@ -359,7 +364,7 @@ EXPORT_SYMBOL(call_usermodehelper_stdinpipe); | |||
359 | * (ie. it runs with full root capabilities). | 364 | * (ie. it runs with full root capabilities). |
360 | */ | 365 | */ |
361 | int call_usermodehelper_exec(struct subprocess_info *sub_info, | 366 | int call_usermodehelper_exec(struct subprocess_info *sub_info, |
362 | int wait) | 367 | enum umh_wait wait) |
363 | { | 368 | { |
364 | DECLARE_COMPLETION_ONSTACK(done); | 369 | DECLARE_COMPLETION_ONSTACK(done); |
365 | int retval; | 370 | int retval; |
@@ -378,7 +383,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, | |||
378 | sub_info->wait = wait; | 383 | sub_info->wait = wait; |
379 | 384 | ||
380 | queue_work(khelper_wq, &sub_info->work); | 385 | queue_work(khelper_wq, &sub_info->work); |
381 | if (wait < 0) /* task has freed sub_info */ | 386 | if (wait == UMH_NO_WAIT) /* task has freed sub_info */ |
382 | return 0; | 387 | return 0; |
383 | wait_for_completion(&done); | 388 | wait_for_completion(&done); |
384 | retval = sub_info->retval; | 389 | retval = sub_info->retval; |