Merge master.kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
[pandora-kernel.git] / kernel / exit.c
index d891883..4e3f919 100644 (file)
 #include <linux/security.h>
 #include <linux/cpu.h>
 #include <linux/acct.h>
+#include <linux/tsacct_kern.h>
 #include <linux/file.h>
 #include <linux/binfmts.h>
+#include <linux/nsproxy.h>
 #include <linux/ptrace.h>
 #include <linux/profile.h>
 #include <linux/mount.h>
@@ -38,6 +40,7 @@
 #include <linux/pipe_fs_i.h>
 #include <linux/audit.h> /* for audit_free() */
 #include <linux/resource.h>
+#include <linux/blkdev.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -125,6 +128,7 @@ static void __exit_signal(struct task_struct *tsk)
        flush_sigqueue(&tsk->pending);
        if (sig) {
                flush_sigqueue(&sig->shared_pending);
+               taskstats_tgid_free(sig);
                __cleanup_signal(sig);
        }
 }
@@ -219,7 +223,7 @@ static int will_become_orphaned_pgrp(int pgrp, struct task_struct *ignored_task)
        do_each_task_pid(pgrp, PIDTYPE_PGID, p) {
                if (p == ignored_task
                                || p->exit_state
-                               || p->real_parent->pid == 1)
+                               || is_init(p->real_parent))
                        continue;
                if (process_group(p->real_parent) != pgrp
                            && p->real_parent->signal->session == p->signal->session) {
@@ -249,17 +253,6 @@ static int has_stopped_jobs(int pgrp)
        do_each_task_pid(pgrp, PIDTYPE_PGID, p) {
                if (p->state != TASK_STOPPED)
                        continue;
-
-               /* If p is stopped by a debugger on a signal that won't
-                  stop it, then don't count p as stopped.  This isn't
-                  perfect but it's a good approximation.  */
-               if (unlikely (p->ptrace)
-                   && p->exit_code != SIGSTOP
-                   && p->exit_code != SIGTSTP
-                   && p->exit_code != SIGTTOU
-                   && p->exit_code != SIGTTIN)
-                       continue;
-
                retval = 1;
                break;
        } while_each_task_pid(pgrp, PIDTYPE_PGID, p);
@@ -292,9 +285,7 @@ static void reparent_to_init(void)
        /* Set the exit signal to SIGCHLD so we signal init on exit */
        current->exit_signal = SIGCHLD;
 
-       if ((current->policy == SCHED_NORMAL ||
-                       current->policy == SCHED_BATCH)
-                               && (task_nice(current) < 0))
+       if (!has_rt_policy(current) && (task_nice(current) < 0))
                set_user_nice(current, 0);
        /* cpus_allowed? */
        /* rt_priority? */
@@ -408,9 +399,11 @@ void daemonize(const char *name, ...)
        fs = init_task.fs;
        current->fs = fs;
        atomic_inc(&fs->count);
-       exit_namespace(current);
-       current->namespace = init_task.namespace;
-       get_namespace(current->namespace);
+
+       exit_task_namespaces(current);
+       current->nsproxy = init_task.nsproxy;
+       get_task_namespaces(current);
+
        exit_files(current);
        current->files = init_task.files;
        atomic_inc(&current->files->count);
@@ -487,6 +480,18 @@ void fastcall put_files_struct(struct files_struct *files)
 
 EXPORT_SYMBOL(put_files_struct);
 
+void reset_files_struct(struct task_struct *tsk, struct files_struct *files)
+{
+       struct files_struct *old;
+
+       old = tsk->files;
+       task_lock(tsk);
+       tsk->files = files;
+       task_unlock(tsk);
+       put_files_struct(old);
+}
+EXPORT_SYMBOL(reset_files_struct);
+
 static inline void __exit_files(struct task_struct *tsk)
 {
        struct files_struct * files = tsk->files;
@@ -845,9 +850,7 @@ static void exit_notify(struct task_struct *tsk)
 fastcall NORET_TYPE void do_exit(long code)
 {
        struct task_struct *tsk = current;
-       struct taskstats *tidstats;
        int group_dead;
-       unsigned int mycpu;
 
        profile_task_exit(tsk);
 
@@ -885,8 +888,6 @@ fastcall NORET_TYPE void do_exit(long code)
                                current->comm, current->pid,
                                preempt_count());
 
-       taskstats_exit_alloc(&tidstats, &mycpu);
-
        acct_update_integrals(tsk);
        if (tsk->mm) {
                update_hiwater_rss(tsk->mm);
@@ -906,8 +907,8 @@ fastcall NORET_TYPE void do_exit(long code)
 #endif
        if (unlikely(tsk->audit_context))
                audit_free(tsk);
-       taskstats_exit_send(tsk, tidstats, group_dead, mycpu);
-       taskstats_exit_free(tidstats);
+
+       taskstats_exit(tsk, group_dead);
 
        exit_mm(tsk);
 
@@ -916,7 +917,6 @@ fastcall NORET_TYPE void do_exit(long code)
        exit_sem(tsk);
        __exit_files(tsk);
        __exit_fs(tsk);
-       exit_namespace(tsk);
        exit_thread();
        cpuset_exit(tsk);
        exit_keys(tsk);
@@ -931,6 +931,7 @@ fastcall NORET_TYPE void do_exit(long code)
        tsk->exit_code = code;
        proc_exit_connector(tsk);
        exit_notify(tsk);
+       exit_task_namespaces(tsk);
 #ifdef CONFIG_NUMA
        mpol_free(tsk->mempolicy);
        tsk->mempolicy = NULL;
@@ -954,15 +955,15 @@ fastcall NORET_TYPE void do_exit(long code)
        if (tsk->splice_pipe)
                __free_pipe_info(tsk->splice_pipe);
 
-       /* PF_DEAD causes final put_task_struct after we schedule. */
        preempt_disable();
-       BUG_ON(tsk->flags & PF_DEAD);
-       tsk->flags |= PF_DEAD;
+       /* causes final put_task_struct in finish_task_switch(). */
+       tsk->state = TASK_DEAD;
 
        schedule();
        BUG();
        /* Avoid "noreturn function does return".  */
-       for (;;) ;
+       for (;;)
+               cpu_relax();    /* For when BUG is null */
 }
 
 EXPORT_SYMBOL_GPL(do_exit);
@@ -971,7 +972,7 @@ NORET_TYPE void complete_and_exit(struct completion *comp, long code)
 {
        if (comp)
                complete(comp);
-       
+
        do_exit(code);
 }