xfs: remove nr_to_write writeback windup.
[safe/jmp/linux-2.6] / kernel / kmod.c
index 531ef62..6e9b196 100644 (file)
@@ -134,36 +134,10 @@ static int ____call_usermodehelper(void *data)
        struct subprocess_info *sub_info = data;
        int retval;
 
-       BUG_ON(atomic_read(&sub_info->cred->usage) != 1);
-
-       /* Unblock all signals */
        spin_lock_irq(&current->sighand->siglock);
        flush_signal_handlers(current, 1);
-       sigemptyset(&current->blocked);
-       recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       /* Install the credentials */
-       commit_creds(sub_info->cred);
-       sub_info->cred = NULL;
-
-       /* Install input pipe when needed */
-       if (sub_info->stdin) {
-               struct files_struct *f = current->files;
-               struct fdtable *fdt;
-               /* no races because files should be private here */
-               sys_close(0);
-               fd_install(0, sub_info->stdin);
-               spin_lock(&f->file_lock);
-               fdt = files_fdtable(f);
-               FD_SET(0, fdt->open_fds);
-               FD_CLR(0, fdt->close_on_exec);
-               spin_unlock(&f->file_lock);
-
-               /* and disallow core files too */
-               current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
-       }
-
        /* We can run anywhere, unlike our parent keventd(). */
        set_cpus_allowed_ptr(current, cpu_all_mask);
 
@@ -191,8 +165,6 @@ void call_usermodehelper_freeinfo(struct subprocess_info *info)
 {
        if (info->cleanup)
                (*info->cleanup)(info);
-       if (info->cred)
-               put_cred(info->cred);
        kfree(info);
 }
 EXPORT_SYMBOL(call_usermodehelper_freeinfo);
@@ -203,16 +175,16 @@ static int wait_for_helper(void *data)
        struct subprocess_info *sub_info = data;
        pid_t pid;
 
-       /* Install a handler: if SIGCLD isn't handled sys_wait4 won't
-        * populate the status, but will return -ECHILD. */
-       allow_signal(SIGCHLD);
+       /* If SIGCLD is ignored sys_wait4 won't populate the status. */
+       spin_lock_irq(&current->sighand->siglock);
+       current->sighand->action[SIGCHLD-1].sa.sa_handler = SIG_DFL;
+       spin_unlock_irq(&current->sighand->siglock);
 
        pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
        if (pid < 0) {
                sub_info->retval = pid;
        } else {
-               int ret;
-
+               int ret = -ECHILD;
                /*
                 * Normally it is bogus to call wait4() from in-kernel because
                 * wait4() wants to write the exit code to a userspace address.
@@ -233,10 +205,7 @@ static int wait_for_helper(void *data)
                        sub_info->retval = ret;
        }
 
-       if (sub_info->wait == UMH_NO_WAIT)
-               call_usermodehelper_freeinfo(sub_info);
-       else
-               complete(sub_info->complete);
+       complete(sub_info->complete);
        return 0;
 }
 
@@ -245,15 +214,13 @@ static void __call_usermodehelper(struct work_struct *work)
 {
        struct subprocess_info *sub_info =
                container_of(work, struct subprocess_info, work);
-       pid_t pid;
        enum umh_wait wait = sub_info->wait;
-
-       BUG_ON(atomic_read(&sub_info->cred->usage) != 1);
+       pid_t pid;
 
        /* CLONE_VFORK: wait until the usermode helper has execve'd
         * successfully We need the data structures to stay around
         * until that is done.  */
-       if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT)
+       if (wait == UMH_WAIT_PROC)
                pid = kernel_thread(wait_for_helper, sub_info,
                                    CLONE_FS | CLONE_FILES | SIGCHLD);
        else
@@ -262,15 +229,16 @@ static void __call_usermodehelper(struct work_struct *work)
 
        switch (wait) {
        case UMH_NO_WAIT:
+               call_usermodehelper_freeinfo(sub_info);
                break;
 
        case UMH_WAIT_PROC:
                if (pid > 0)
                        break;
-               sub_info->retval = pid;
                /* FALLTHROUGH */
-
        case UMH_WAIT_EXEC:
+               if (pid < 0)
+                       sub_info->retval = pid;
                complete(sub_info->complete);
        }
 }
@@ -372,36 +340,12 @@ struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
        sub_info->path = path;
        sub_info->argv = argv;
        sub_info->envp = envp;
-       sub_info->cred = prepare_usermodehelper_creds();
-       if (!sub_info->cred) {
-               kfree(sub_info);
-               return NULL;
-       }
-
   out:
        return sub_info;
 }
 EXPORT_SYMBOL(call_usermodehelper_setup);
 
 /**
- * call_usermodehelper_setkeys - set the session keys for usermode helper
- * @info: a subprocess_info returned by call_usermodehelper_setup
- * @session_keyring: the session keyring for the process
- */
-void call_usermodehelper_setkeys(struct subprocess_info *info,
-                                struct key *session_keyring)
-{
-#ifdef CONFIG_KEYS
-       struct thread_group_cred *tgcred = info->cred->tgcred;
-       key_put(tgcred->session_keyring);
-       tgcred->session_keyring = key_get(session_keyring);
-#else
-       BUG();
-#endif
-}
-EXPORT_SYMBOL(call_usermodehelper_setkeys);
-
-/**
  * call_usermodehelper_setfns - set a cleanup/init function
  * @info: a subprocess_info returned by call_usermodehelper_setup
  * @cleanup: a cleanup function
@@ -429,35 +373,6 @@ void call_usermodehelper_setfns(struct subprocess_info *info,
 EXPORT_SYMBOL(call_usermodehelper_setfns);
 
 /**
- * call_usermodehelper_stdinpipe - set up a pipe to be used for stdin
- * @sub_info: a subprocess_info returned by call_usermodehelper_setup
- * @filp: set to the write-end of a pipe
- *
- * This constructs a pipe, and sets the read end to be the stdin of the
- * subprocess, and returns the write-end in *@filp.
- */
-int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
-                                 struct file **filp)
-{
-       struct file *f;
-
-       f = create_write_pipe(0);
-       if (IS_ERR(f))
-               return PTR_ERR(f);
-       *filp = f;
-
-       f = create_read_pipe(f, 0);
-       if (IS_ERR(f)) {
-               free_write_pipe(*filp);
-               return PTR_ERR(f);
-       }
-       sub_info->stdin = f;
-
-       return 0;
-}
-EXPORT_SYMBOL(call_usermodehelper_stdinpipe);
-
-/**
  * call_usermodehelper_exec - start a usermode application
  * @sub_info: information about the subprocessa
  * @wait: wait for the application to finish and return status.
@@ -475,9 +390,6 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
        DECLARE_COMPLETION_ONSTACK(done);
        int retval = 0;
 
-       BUG_ON(atomic_read(&sub_info->cred->usage) != 1);
-       validate_creds(sub_info->cred);
-
        helper_lock();
        if (sub_info->path[0] == '\0')
                goto out;
@@ -504,42 +416,6 @@ unlock:
 }
 EXPORT_SYMBOL(call_usermodehelper_exec);
 
-/**
- * call_usermodehelper_pipe - call a usermode helper process with a pipe stdin
- * @path: path to usermode executable
- * @argv: arg vector for process
- * @envp: environment for process
- * @filp: set to the write-end of a pipe
- *
- * This is a simple wrapper which executes a usermode-helper function
- * with a pipe as stdin.  It is implemented entirely in terms of
- * lower-level call_usermodehelper_* functions.
- */
-int call_usermodehelper_pipe(char *path, char **argv, char **envp,
-                            struct file **filp)
-{
-       struct subprocess_info *sub_info;
-       int ret;
-
-       sub_info = call_usermodehelper_setup(path, argv, envp,
-                                            GFP_KERNEL);
-       if (sub_info == NULL)
-               return -ENOMEM;
-
-       ret = call_usermodehelper_stdinpipe(sub_info, filp);
-       if (ret < 0) {
-               call_usermodehelper_freeinfo(sub_info);
-               return ret;
-       }
-
-       ret = call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC);
-       if (ret < 0)    /* Failed to execute helper, close pipe */
-               filp_close(*filp, NULL);
-
-       return ret;
-}
-EXPORT_SYMBOL(call_usermodehelper_pipe);
-
 void __init usermodehelper_init(void)
 {
        khelper_wq = create_singlethread_workqueue("khelper");