diff -NurpP --minimal linux-2.6.19-vs2.1.x-t7.2.1/include/linux/vserver/context.h linux-2.6.19-vs2.1.x-t7.2.2/include/linux/vserver/context.h --- linux-2.6.19-vs2.1.x-t7.2.1/include/linux/vserver/context.h 2006-12-06 10:36:44 +0100 +++ linux-2.6.19-vs2.1.x-t7.2.2/include/linux/vserver/context.h 2006-12-08 03:12:33 +0100 @@ -98,6 +98,7 @@ struct vx_info { struct vx_info *vx_parent; /* parent context */ int vx_state; /* context state */ + unsigned long vx_nsmask; /* assignment mask */ struct nsproxy *vx_nsproxy; /* private namespace */ struct fs_struct *vx_fs; /* private namespace fs */ diff -NurpP --minimal linux-2.6.19-vs2.1.x-t7.2.1/kernel/vserver/space.c linux-2.6.19-vs2.1.x-t7.2.2/kernel/vserver/space.c --- linux-2.6.19-vs2.1.x-t7.2.1/kernel/vserver/space.c 2006-12-07 23:24:42 +0100 +++ linux-2.6.19-vs2.1.x-t7.2.2/kernel/vserver/space.c 2006-12-08 03:38:53 +0100 @@ -124,34 +124,50 @@ void __vs_merge_fs(struct fs_struct **pt int vx_enter_space(struct vx_info *vxi, unsigned long mask) { - struct fs_struct *fs; + struct fs_struct *fs = NULL; struct nsproxy *nsproxy; if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0)) return -EACCES; - nsproxy = vxi->vx_nsproxy; - if (!nsproxy) + if (!mask) + mask = vxi->vx_nsmask; + + if ((mask & vxi->vx_nsmask) != mask) return -EINVAL; - fs = copy_fs_struct(vxi->vx_fs); - if (!fs) - return -ENOMEM; + nsproxy = vxi->vx_nsproxy; + if ((mask & CLONE_FS)) { + BUG_ON(!vxi->vx_fs); + fs = copy_fs_struct(vxi->vx_fs); + if (!fs) + return -ENOMEM; + } task_lock(current); - __vs_merge_nsproxy(¤t->nsproxy, nsproxy, mask); - if (!mask || (mask & CLONE_FS)) + if (nsproxy) + __vs_merge_nsproxy(¤t->nsproxy, nsproxy, mask); + if (fs) __vs_merge_fs(¤t->fs, fs); task_unlock(current); return 0; } +static const unsigned long all_space_mask = + CLONE_FS | CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC; + int vx_set_space(struct vx_info *vxi, unsigned long mask) { - struct fs_struct *fs_copy, *fs; + struct fs_struct *fs, *fs_copy = NULL; struct nsproxy *nsproxy; int ret; + if (!mask) + mask = all_space_mask; + + if ((mask & all_space_mask) != mask) + return -EINVAL; + task_lock(current); fs = current->fs; atomic_inc(&fs->count); @@ -160,13 +176,17 @@ int vx_set_space(struct vx_info *vxi, un task_unlock(current); ret = -ENOMEM; - fs_copy = copy_fs_struct(fs); - if (!fs_copy) - goto out_put; + if ((mask & CLONE_FS)) { + fs_copy = copy_fs_struct(fs); + if (!fs_copy) + goto out_put; + } - __vs_merge_nsproxy(&vxi->vx_nsproxy, nsproxy, mask); - if (!mask || (mask & CLONE_FS)) + if (nsproxy) + __vs_merge_nsproxy(&vxi->vx_nsproxy, nsproxy, mask); + if (fs_copy) __vs_merge_fs(&vxi->vx_fs, fs_copy); + vxi->vx_nsmask |= mask; ret = 0; out_put: