aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorSerge Hallyn <serue@us.ibm.com>2006-10-02 05:18:18 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-02 10:57:22 -0400
commitc0b2fc316599d6cd875b6b8cafa67f03b9512b4d (patch)
tree6e03101b6692dfe3284de05a5f4fd5495d513ab3 /kernel/fork.c
parent071df104f808b8195c40643dcb4d060681742e29 (diff)
[PATCH] uts: copy nsproxy only when needed
The nsproxy was being copied in unshare() when anything was being unshared, even if it was something not referenced from nsproxy. This should end up in some cases with far more memory usage than necessary. 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/fork.c')
-rw-r--r--kernel/fork.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index c08cf05dd59b..208dd99f13bc 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1606,7 +1606,7 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1606 struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL; 1606 struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
1607 struct files_struct *fd, *new_fd = NULL; 1607 struct files_struct *fd, *new_fd = NULL;
1608 struct sem_undo_list *new_ulist = NULL; 1608 struct sem_undo_list *new_ulist = NULL;
1609 struct nsproxy *new_nsproxy, *old_nsproxy; 1609 struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
1610 struct uts_namespace *uts, *new_uts = NULL; 1610 struct uts_namespace *uts, *new_uts = NULL;
1611 1611
1612 check_unshare_flags(&unshare_flags); 1612 check_unshare_flags(&unshare_flags);
@@ -1634,18 +1634,24 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1634 if ((err = unshare_utsname(unshare_flags, &new_uts))) 1634 if ((err = unshare_utsname(unshare_flags, &new_uts)))
1635 goto bad_unshare_cleanup_semundo; 1635 goto bad_unshare_cleanup_semundo;
1636 1636
1637 if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist || 1637 if (new_ns || new_uts) {
1638 new_uts) {
1639
1640 old_nsproxy = current->nsproxy; 1638 old_nsproxy = current->nsproxy;
1641 new_nsproxy = dup_namespaces(old_nsproxy); 1639 new_nsproxy = dup_namespaces(old_nsproxy);
1642 if (!new_nsproxy) { 1640 if (!new_nsproxy) {
1643 err = -ENOMEM; 1641 err = -ENOMEM;
1644 goto bad_unshare_cleanup_uts; 1642 goto bad_unshare_cleanup_uts;
1645 } 1643 }
1644 }
1645
1646 if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist ||
1647 new_uts) {
1646 1648
1647 task_lock(current); 1649 task_lock(current);
1648 current->nsproxy = new_nsproxy; 1650
1651 if (new_nsproxy) {
1652 current->nsproxy = new_nsproxy;
1653 new_nsproxy = old_nsproxy;
1654 }
1649 1655
1650 if (new_fs) { 1656 if (new_fs) {
1651 fs = current->fs; 1657 fs = current->fs;
@@ -1687,9 +1693,11 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
1687 } 1693 }
1688 1694
1689 task_unlock(current); 1695 task_unlock(current);
1690 put_nsproxy(old_nsproxy);
1691 } 1696 }
1692 1697
1698 if (new_nsproxy)
1699 put_nsproxy(new_nsproxy);
1700
1693bad_unshare_cleanup_uts: 1701bad_unshare_cleanup_uts:
1694 if (new_uts) 1702 if (new_uts)
1695 put_uts_ns(new_uts); 1703 put_uts_ns(new_uts);