diff -NurpP linux-2.6.29.3-vs2.3.0.36.13/kernel/vserver/context.c linux-2.6.29.3-vs2.3.0.36.13.1/kernel/vserver/context.c --- linux-2.6.29.3-vs2.3.0.36.13/kernel/vserver/context.c 2009-05-20 17:08:50.000000000 +0200 +++ linux-2.6.29.3-vs2.3.0.36.13.1/kernel/vserver/context.c 2009-05-20 11:23:31.000000000 +0200 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -67,7 +68,7 @@ static spinlock_t vx_info_inactive_lock static struct vx_info *__alloc_vx_info(xid_t xid) { struct vx_info *new = NULL; - int cpu; + int cpu, index; vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid); @@ -117,6 +118,14 @@ static struct vx_info *__alloc_vx_info(x new->reboot_cmd = 0; new->exit_code = 0; + // preconfig fs entries + for (index = 0; index < VX_SPACES; index++) { + write_lock(&init_fs.lock); + init_fs.users++; + write_unlock(&init_fs.lock); + new->vx_fs[index] = &init_fs; + } + vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d) = %p", xid, new); vxh_alloc_vx_info(new); @@ -172,7 +181,7 @@ static void __shutdown_vx_info(struct vx { struct nsproxy *nsproxy; struct fs_struct *fs; - int index; + int index, kill; might_sleep(); @@ -185,7 +194,10 @@ static void __shutdown_vx_info(struct vx put_nsproxy(nsproxy); fs = xchg(&vxi->vx_fs[index], NULL); - if (fs) + write_lock(&fs->lock); + kill = !--fs->users; + write_unlock(&fs->lock); + if (kill) free_fs_struct(fs); } } diff -NurpP linux-2.6.29.3-vs2.3.0.36.13/kernel/vserver/space.c linux-2.6.29.3-vs2.3.0.36.13.1/kernel/vserver/space.c --- linux-2.6.29.3-vs2.3.0.36.13/kernel/vserver/space.c 2009-05-20 17:08:50.000000000 +0200 +++ linux-2.6.29.3-vs2.3.0.36.13.1/kernel/vserver/space.c 2009-05-20 14:40:41.000000000 +0200 @@ -184,28 +184,6 @@ struct nsproxy *__vs_merge_nsproxy(struc return proxy; } -/* - * merge two fs structs into a new one. - * will take a reference on the result. - */ - -static inline -struct fs_struct *__vs_merge_fs(struct fs_struct *old, - struct fs_struct *fs, unsigned long mask) -{ - if (!(mask & CLONE_FS)) { - if (!old) - return NULL; - write_lock(&old->lock); - fs->users++; - write_unlock(&old->lock); - } - - if (!fs) - return NULL; - return copy_fs_struct(fs); -} - int vx_enter_space(struct vx_info *vxi, unsigned long mask, unsigned index) { @@ -238,7 +216,7 @@ int vx_enter_space(struct vx_info *vxi, write_lock(&fs_cur->lock); current->fs = fs; - kill = !--fs->users; + kill = !--fs_cur->users; write_unlock(&fs_cur->lock); } @@ -286,8 +264,9 @@ int vx_set_space(struct vx_info *vxi, un fs_vxi = vxi->vx_fs[index]; task_lock(current); - if (mask & CLONE_FS) { - fs_cur = current->fs; + fs_cur = current->fs; + + if ((mask & CLONE_FS) && (fs_cur != fs_vxi)) { write_lock(&fs_cur->lock); fs_cur->users++; write_unlock(&fs_cur->lock); @@ -302,6 +281,9 @@ int vx_set_space(struct vx_info *vxi, un get_nsproxy(proxy_cur); task_unlock(current); + if (kill) + free_fs_struct(fs_vxi); + proxy_new = __vs_merge_nsproxy(proxy_vxi, proxy_cur, mask); if (IS_ERR(proxy_new)) { ret = PTR_ERR(proxy_new);