aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorSerge E. Hallyn <serue@us.ibm.com>2006-10-02 05:18:08 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-02 10:57:20 -0400
commit1651e14e28a2d9f446018ef522882e0709a2ce4f (patch)
tree401ff78624fdc4b445f3f95174a223acaf6a4ca0 /kernel
parent0437eb594e6e5e699248f865482e61034be846d0 (diff)
[PATCH] namespaces: incorporate fs namespace into nsproxy
This moves the mount namespace into the nsproxy. The mount namespace count now refers to the number of nsproxies point to it, rather than the number of tasks. As a result, the unshare_namespace() function in kernel/fork.c no longer checks whether it is being shared. Signed-off-by: Serge Hallyn <serue@us.ibm.com> Cc: Kirill Korotaev <dev@openvz.org> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Herbert Poetzl <herbert@13thfloor.at> Cc: Andrey Savochkin <saw@sw.ru> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/exit.c4
-rw-r--r--kernel/fork.c17
-rw-r--r--kernel/nsproxy.c32
3 files changed, 37 insertions, 16 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 1d0e9ea1fa05..741bbe42dfe8 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -399,11 +399,8 @@ void daemonize(const char *name, ...)
399 current->fs = fs; 399 current->fs = fs;
400 atomic_inc(&fs->count); 400 atomic_inc(&fs->count);
401 401
402 exit_namespace(current);
403 exit_task_namespaces(current); 402 exit_task_namespaces(current);
404 current->namespace = init_task.namespace;
405 current->nsproxy = init_task.nsproxy; 403 current->nsproxy = init_task.nsproxy;
406 get_namespace(current->namespace);
407 get_task_namespaces(current); 404 get_task_namespaces(current);
408 405
409 exit_files(current); 406 exit_files(current);
@@ -923,7 +920,6 @@ fastcall NORET_TYPE void do_exit(long code)
923 exit_sem(tsk); 920 exit_sem(tsk);
924 __exit_files(tsk); 921 __exit_files(tsk);
925 __exit_fs(tsk); 922 __exit_fs(tsk);
926 exit_namespace(tsk);
927 exit_task_namespaces(tsk); 923 exit_task_namespaces(tsk);
928 exit_thread(); 924 exit_thread();
929 cpuset_exit(tsk); 925 cpuset_exit(tsk);
diff --git a/kernel/fork.c b/kernel/fork.c
index c9e660ae47aa..33fcf0733ca6 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1119,11 +1119,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1119 goto bad_fork_cleanup_mm; 1119 goto bad_fork_cleanup_mm;
1120 if ((retval = copy_namespaces(clone_flags, p))) 1120 if ((retval = copy_namespaces(clone_flags, p)))
1121 goto bad_fork_cleanup_keys; 1121 goto bad_fork_cleanup_keys;
1122 if ((retval = copy_namespace(clone_flags, p)))
1123 goto bad_fork_cleanup_namespaces;
1124 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); 1122 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
1125 if (retval) 1123 if (retval)
1126 goto bad_fork_cleanup_namespace; 1124 goto bad_fork_cleanup_namespaces;
1127 1125
1128 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; 1126 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
1129 /* 1127 /*
@@ -1215,7 +1213,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1215 spin_unlock(&current->sighand->siglock); 1213 spin_unlock(&current->sighand->siglock);
1216 write_unlock_irq(&tasklist_lock); 1214 write_unlock_irq(&tasklist_lock);
1217 retval = -ERESTARTNOINTR; 1215 retval = -ERESTARTNOINTR;
1218 goto bad_fork_cleanup_namespace; 1216 goto bad_fork_cleanup_namespaces;
1219 } 1217 }
1220 1218
1221 if (clone_flags & CLONE_THREAD) { 1219 if (clone_flags & CLONE_THREAD) {
@@ -1263,8 +1261,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1263 proc_fork_connector(p); 1261 proc_fork_connector(p);
1264 return p; 1262 return p;
1265 1263
1266bad_fork_cleanup_namespace:
1267 exit_namespace(p);
1268bad_fork_cleanup_namespaces: 1264bad_fork_cleanup_namespaces:
1269 exit_task_namespaces(p); 1265 exit_task_namespaces(p);
1270bad_fork_cleanup_keys: 1266bad_fork_cleanup_keys:
@@ -1519,10 +1515,9 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
1519 */ 1515 */
1520static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs) 1516static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs)
1521{ 1517{
1522 struct namespace *ns = current->namespace; 1518 struct namespace *ns = current->nsproxy->namespace;
1523 1519
1524 if ((unshare_flags & CLONE_NEWNS) && 1520 if ((unshare_flags & CLONE_NEWNS) && ns) {
1525 (ns && atomic_read(&ns->count) > 1)) {
1526 if (!capable(CAP_SYS_ADMIN)) 1521 if (!capable(CAP_SYS_ADMIN))
1527 return -EPERM; 1522 return -EPERM;
1528 1523
@@ -1655,8 +1650,8 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1655 } 1650 }
1656 1651
1657 if (new_ns) { 1652 if (new_ns) {
1658 ns = current->namespace; 1653 ns = current->nsproxy->namespace;
1659 current->namespace = new_ns; 1654 current->nsproxy->namespace = new_ns;
1660 new_ns = ns; 1655 new_ns = ns;
1661 } 1656 }
1662 1657
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index a3612f82f187..e10385c17f73 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -13,6 +13,7 @@
13#include <linux/version.h> 13#include <linux/version.h>
14#include <linux/nsproxy.h> 14#include <linux/nsproxy.h>
15#include <linux/init_task.h> 15#include <linux/init_task.h>
16#include <linux/namespace.h>
16 17
17struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); 18struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
18 19
@@ -55,6 +56,11 @@ struct nsproxy *dup_namespaces(struct nsproxy *orig)
55{ 56{
56 struct nsproxy *ns = clone_namespaces(orig); 57 struct nsproxy *ns = clone_namespaces(orig);
57 58
59 if (ns) {
60 if (ns->namespace)
61 get_namespace(ns->namespace);
62 }
63
58 return ns; 64 return ns;
59} 65}
60 66
@@ -65,16 +71,40 @@ struct nsproxy *dup_namespaces(struct nsproxy *orig)
65int copy_namespaces(int flags, struct task_struct *tsk) 71int copy_namespaces(int flags, struct task_struct *tsk)
66{ 72{
67 struct nsproxy *old_ns = tsk->nsproxy; 73 struct nsproxy *old_ns = tsk->nsproxy;
74 struct nsproxy *new_ns;
75 int err = 0;
68 76
69 if (!old_ns) 77 if (!old_ns)
70 return 0; 78 return 0;
71 79
72 get_nsproxy(old_ns); 80 get_nsproxy(old_ns);
73 81
74 return 0; 82 if (!(flags & CLONE_NEWNS))
83 return 0;
84
85 new_ns = clone_namespaces(old_ns);
86 if (!new_ns) {
87 err = -ENOMEM;
88 goto out;
89 }
90
91 tsk->nsproxy = new_ns;
92
93 err = copy_namespace(flags, tsk);
94 if (err) {
95 tsk->nsproxy = old_ns;
96 put_nsproxy(new_ns);
97 goto out;
98 }
99
100out:
101 put_nsproxy(old_ns);
102 return err;
75} 103}
76 104
77void free_nsproxy(struct nsproxy *ns) 105void free_nsproxy(struct nsproxy *ns)
78{ 106{
107 if (ns->namespace)
108 put_namespace(ns->namespace);
79 kfree(ns); 109 kfree(ns);
80} 110}