Revert "[PATCH] namespaces: fix exit race by splitting exit"
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 30 Jan 2007 21:35:18 +0000 (13:35 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 30 Jan 2007 21:35:18 +0000 (13:35 -0800)
This reverts commit 7a238fcba0629b6f2edbcd37458bae56fcf36be5 in
preparation for a better and simpler fix proposed by Eric Biederman
(and fixed up by Serge Hallyn)

Acked-by: Serge E. Hallyn <serue@us.ibm.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/nsproxy.h
kernel/exit.c
kernel/fork.c
kernel/nsproxy.c

index 678e1d38effba0866464ec560639fe07aaa929fa..0b9f0dc30d6114a1f5177a7fde829d2199137172 100644 (file)
@@ -35,30 +35,22 @@ struct nsproxy *dup_namespaces(struct nsproxy *orig);
 int copy_namespaces(int flags, struct task_struct *tsk);
 void get_task_namespaces(struct task_struct *tsk);
 void free_nsproxy(struct nsproxy *ns);
-struct nsproxy *put_nsproxy(struct nsproxy *ns);
 
-static inline void finalize_put_nsproxy(struct nsproxy *ns)
+static inline void put_nsproxy(struct nsproxy *ns)
 {
-       if (ns)
+       if (atomic_dec_and_test(&ns->count)) {
                free_nsproxy(ns);
+       }
 }
 
-static inline void put_and_finalize_nsproxy(struct nsproxy *ns)
+static inline void exit_task_namespaces(struct task_struct *p)
 {
-       finalize_put_nsproxy(put_nsproxy(ns));
-}
-
-static inline struct nsproxy *preexit_task_namespaces(struct task_struct *p)
-{
-       return put_nsproxy(p->nsproxy);
-}
-
-static inline void exit_task_namespaces(struct task_struct *p,
-                                               struct nsproxy *ns)
-{
-       task_lock(p);
-       p->nsproxy = NULL;
-       task_unlock(p);
-       finalize_put_nsproxy(ns);
+       struct nsproxy *ns = p->nsproxy;
+       if (ns) {
+               task_lock(p);
+               p->nsproxy = NULL;
+               task_unlock(p);
+               put_nsproxy(ns);
+       }
 }
 #endif
index a5bf5329ff97673c3d1843f10fcb4ad2004b114c..35401720635b4df01afe542c655ba350ac13d6a2 100644 (file)
@@ -396,7 +396,7 @@ void daemonize(const char *name, ...)
        current->fs = fs;
        atomic_inc(&fs->count);
 
-       put_and_finalize_nsproxy(current->nsproxy);
+       exit_task_namespaces(current);
        current->nsproxy = init_task.nsproxy;
        get_task_namespaces(current);
 
@@ -853,7 +853,6 @@ static void exit_notify(struct task_struct *tsk)
 fastcall NORET_TYPE void do_exit(long code)
 {
        struct task_struct *tsk = current;
-       struct nsproxy *ns;
        int group_dead;
 
        profile_task_exit(tsk);
@@ -939,9 +938,8 @@ fastcall NORET_TYPE void do_exit(long code)
 
        tsk->exit_code = code;
        proc_exit_connector(tsk);
-       ns = preexit_task_namespaces(tsk);
        exit_notify(tsk);
-       exit_task_namespaces(tsk, ns);
+       exit_task_namespaces(tsk);
 #ifdef CONFIG_NUMA
        mpol_free(tsk->mempolicy);
        tsk->mempolicy = NULL;
index 4cf868458f06bb2fed06df3ff9f5624ca4d92a20..fc723e595cd5ba2c95499ba058636005dd9946e3 100644 (file)
@@ -1265,7 +1265,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        return p;
 
 bad_fork_cleanup_namespaces:
-       put_and_finalize_nsproxy(p->nsproxy);
+       exit_task_namespaces(p);
 bad_fork_cleanup_keys:
        exit_keys(p);
 bad_fork_cleanup_mm:
@@ -1711,7 +1711,7 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
        }
 
        if (new_nsproxy)
-               put_and_finalize_nsproxy(new_nsproxy);
+               put_nsproxy(new_nsproxy);
 
 bad_unshare_cleanup_ipc:
        if (new_ipc)
index 7b05bce75cde28ff75b423157c165a8150858329..f5b9ee6f6bbb02733cef1e64fabe4dc521efc767 100644 (file)
@@ -117,7 +117,7 @@ int copy_namespaces(int flags, struct task_struct *tsk)
                goto out_pid;
 
 out:
-       put_and_finalize_nsproxy(old_ns);
+       put_nsproxy(old_ns);
        return err;
 
 out_pid:
@@ -135,20 +135,6 @@ out_ns:
        goto out;
 }
 
-struct nsproxy *put_nsproxy(struct nsproxy *ns)
-{
-       if (ns) {
-               if (atomic_dec_and_test(&ns->count)) {
-                       if (ns->mnt_ns) {
-                               put_mnt_ns(ns->mnt_ns);
-                               ns->mnt_ns = NULL;
-                       }
-                       return ns;
-               }
-       }
-       return NULL;
-}
-
 void free_nsproxy(struct nsproxy *ns)
 {
        if (ns->mnt_ns)