diff -NurpP linux-2.6.36.2-vs2.3.0.36.38.2/include/linux/vserver/context.h linux-2.6.36.2-vs2.3.0.36.38.3/include/linux/vserver/context.h --- linux-2.6.36.2-vs2.3.0.36.38.2/include/linux/vserver/context.h 2010-12-01 17:36:51.000000000 +0100 +++ linux-2.6.36.2-vs2.3.0.36.38.3/include/linux/vserver/context.h 2010-12-15 16:52:30.000000000 +0100 @@ -99,6 +99,14 @@ struct _vx_info_pc { struct _vx_cvirt_pc cvirt_pc; }; +struct _vx_space { + unsigned long vx_nsmask; /* assignment mask */ + struct nsproxy *vx_nsproxy; /* private namespaces */ + struct fs_struct *vx_fs; /* private namespace fs */ + const struct cred *vx_real_cred; /* real task credentials */ + const struct cred *vx_cred; /* task credentials */ +}; + struct vx_info { struct hlist_node vx_hlist; /* linked list of contexts */ xid_t vx_id; /* context id */ @@ -107,11 +115,7 @@ struct vx_info { struct vx_info *vx_parent; /* parent context */ int vx_state; /* context state */ - unsigned long vx_nsmask[VX_SPACES]; /* assignment mask */ - struct nsproxy *vx_nsproxy[VX_SPACES]; /* private namespaces */ - struct fs_struct *vx_fs[VX_SPACES]; /* private namespace fs */ - const struct cred *vx_real_cred; /* real task credentials */ - const struct cred *vx_cred; /* task credentials */ + struct _vx_space space[VX_SPACES]; /* namespace store */ uint64_t vx_flags; /* context flags */ uint64_t vx_ccaps; /* context caps (vserver) */ diff -NurpP linux-2.6.36.2-vs2.3.0.36.38.2/kernel/vserver/context.c linux-2.6.36.2-vs2.3.0.36.38.3/kernel/vserver/context.c --- linux-2.6.36.2-vs2.3.0.36.38.2/kernel/vserver/context.c 2010-12-01 20:34:45.000000000 +0100 +++ linux-2.6.36.2-vs2.3.0.36.38.3/kernel/vserver/context.c 2010-12-15 19:44:51.000000000 +0100 @@ -121,17 +121,21 @@ static struct vx_info *__alloc_vx_info(x new->reboot_cmd = 0; new->exit_code = 0; - // preconfig fs entries + // preconfig spaces for (index = 0; index < VX_SPACES; index++) { + struct _vx_space *space = &new->space[index]; + + // filesystem spin_lock(&init_fs.lock); init_fs.users++; spin_unlock(&init_fs.lock); - new->vx_fs[index] = &init_fs; + space->vx_fs = &init_fs; + + /* FIXME: do we want defaults? */ + space->vx_real_cred = 0; + space->vx_cred = 0; } - /* FIXME: we want defaults */ - new->vx_real_cred = 0; - new->vx_cred = 0; vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d) = %p", xid, new); @@ -198,28 +202,30 @@ static void __shutdown_vx_info(struct vx vs_state_change(vxi, VSC_SHUTDOWN); for (index = 0; index < VX_SPACES; index++) { - nsproxy = xchg(&vxi->vx_nsproxy[index], NULL); + struct _vx_space *space = &vxi->space[index]; + + nsproxy = xchg(&space->vx_nsproxy, NULL); if (nsproxy) put_nsproxy(nsproxy); - fs = xchg(&vxi->vx_fs[index], NULL); + fs = xchg(&space->vx_fs, NULL); spin_lock(&fs->lock); kill = !--fs->users; spin_unlock(&fs->lock); if (kill) free_fs_struct(fs); - } - cred = xchg(&vxi->vx_real_cred, NULL); - if (cred) { - alter_cred_subscribers(cred, -1); - put_cred(cred); - } + cred = xchg(&space->vx_real_cred, NULL); + if (cred) { + alter_cred_subscribers(cred, -1); + put_cred(cred); + } - cred = xchg(&vxi->vx_cred, NULL); - if (cred) { - alter_cred_subscribers(cred, -1); - put_cred(cred); + cred = xchg(&space->vx_cred, NULL); + if (cred) { + alter_cred_subscribers(cred, -1); + put_cred(cred); + } } } @@ -240,10 +246,14 @@ void free_vx_info(struct vx_info *vxi) /* context shutdown is mandatory */ BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN)); - /* nsproxy and fs check */ + /* spaces check */ for (index = 0; index < VX_SPACES; index++) { - BUG_ON(vxi->vx_nsproxy[index]); - BUG_ON(vxi->vx_fs[index]); + struct _vx_space *space = &vxi->space[index]; + + BUG_ON(space->vx_nsproxy); + BUG_ON(space->vx_fs); + BUG_ON(space->vx_real_cred); + BUG_ON(space->vx_cred); } spin_lock_irqsave(&vx_info_inactive_lock, flags); diff -NurpP linux-2.6.36.2-vs2.3.0.36.38.2/kernel/vserver/cvirt.c linux-2.6.36.2-vs2.3.0.36.38.3/kernel/vserver/cvirt.c --- linux-2.6.36.2-vs2.3.0.36.38.2/kernel/vserver/cvirt.c 2010-10-24 12:39:42.000000000 +0200 +++ linux-2.6.36.2-vs2.3.0.36.38.3/kernel/vserver/cvirt.c 2010-12-15 20:48:33.000000000 +0100 @@ -169,7 +169,7 @@ static char *vx_vhi_name(struct vx_info if (id == VHIN_CONTEXT) return vxi->vx_name; - nsproxy = vxi->vx_nsproxy[0]; + nsproxy = vxi->space[0].vx_nsproxy; if (!nsproxy) return NULL; diff -NurpP linux-2.6.36.2-vs2.3.0.36.38.2/kernel/vserver/proc.c linux-2.6.36.2-vs2.3.0.36.38.3/kernel/vserver/proc.c --- linux-2.6.36.2-vs2.3.0.36.38.2/kernel/vserver/proc.c 2010-10-21 13:09:36.000000000 +0200 +++ linux-2.6.36.2-vs2.3.0.36.38.3/kernel/vserver/proc.c 2010-12-15 21:18:42.000000000 +0100 @@ -134,7 +134,7 @@ int proc_vxi_status(struct vx_info *vxi, "CCaps:\t%016llx\n" "Spaces:\t%08lx %08lx\n", (unsigned long long)vxi->vx_ccaps, - vxi->vx_nsmask[0], vxi->vx_nsmask[1]); + vxi->space[0].vx_nsmask, vxi->space[1].vx_nsmask); return buffer - orig; } @@ -158,12 +158,12 @@ int proc_vxi_sched(struct vx_info *vxi, int proc_vxi_nsproxy0(struct vx_info *vxi, char *buffer) { - return vx_info_proc_nsproxy(vxi->vx_nsproxy[0], buffer); + return vx_info_proc_nsproxy(vxi->space[0].vx_nsproxy, buffer); } int proc_vxi_nsproxy1(struct vx_info *vxi, char *buffer) { - return vx_info_proc_nsproxy(vxi->vx_nsproxy[1], buffer); + return vx_info_proc_nsproxy(vxi->space[1].vx_nsproxy, buffer); } int proc_vxi_cvirt(struct vx_info *vxi, char *buffer) diff -NurpP linux-2.6.36.2-vs2.3.0.36.38.2/kernel/vserver/space.c linux-2.6.36.2-vs2.3.0.36.38.3/kernel/vserver/space.c --- linux-2.6.36.2-vs2.3.0.36.38.2/kernel/vserver/space.c 2010-12-01 20:39:35.000000000 +0100 +++ linux-2.6.36.2-vs2.3.0.36.38.3/kernel/vserver/space.c 2010-12-15 20:01:53.000000000 +0100 @@ -191,6 +191,7 @@ int vx_enter_space(struct vx_info *vxi, { struct nsproxy *proxy, *proxy_cur, *proxy_new; struct fs_struct *fs_cur, *fs = NULL; + struct _vx_space *space; int ret, kill = 0; vxdprintk(VXD_CBIT(space, 8), "vx_enter_space(%p[#%u],0x%08lx,%d)", @@ -199,18 +200,23 @@ int vx_enter_space(struct vx_info *vxi, if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0)) return -EACCES; + if (index >= VX_SPACES) + return -EINVAL; + + space = &vxi->space[index]; + if (!mask) - mask = vxi->vx_nsmask[index]; + mask = space->vx_nsmask; - if ((mask & vxi->vx_nsmask[index]) != mask) + if ((mask & space->vx_nsmask) != mask) return -EINVAL; if (mask & CLONE_FS) { - fs = copy_fs_struct(vxi->vx_fs[index]); + fs = copy_fs_struct(space->vx_fs); if (!fs) return -ENOMEM; } - proxy = vxi->vx_nsproxy[index]; + proxy = space->vx_nsproxy; vxdprintk(VXD_CBIT(space, 9), "vx_enter_space(%p[#%u],0x%08lx,%d) -> (%p,%p)", @@ -244,12 +250,13 @@ int vx_enter_space(struct vx_info *vxi, if (mask & CLONE_NEWUSER) { vxdprintk(VXD_CBIT(space, 10), "vx_enter_space(%p[#%u],%p,%p) cred (%p,%p)", - vxi, vxi->vx_id, vxi->vx_real_cred, vxi->vx_cred, + vxi, vxi->vx_id, + space->vx_real_cred, space->vx_cred, current->real_cred, current->cred); exit_creds(current); - current->real_cred = get_cred(vxi->vx_real_cred); + current->real_cred = get_cred(space->vx_real_cred); alter_cred_subscribers(current->real_cred, 1); - current->cred = get_cred(vxi->vx_cred); + current->cred = get_cred(space->vx_cred); alter_cred_subscribers(current->cred, 1); } @@ -268,19 +275,22 @@ int vx_set_space(struct vx_info *vxi, un { struct nsproxy *proxy_vxi, *proxy_cur, *proxy_new; struct fs_struct *fs_vxi, *fs; + struct _vx_space *space; int ret, kill = 0; vxdprintk(VXD_CBIT(space, 8), "vx_set_space(%p[#%u],0x%08lx,%d)", vxi, vxi->vx_id, mask, index); -#if 0 - if (!mask) - mask = default_space_mask.mask; -#endif + if ((mask & space_mask.mask) != mask) return -EINVAL; - proxy_vxi = vxi->vx_nsproxy[index]; - fs_vxi = vxi->vx_fs[index]; + if (index >= VX_SPACES) + return -EINVAL; + + space = &vxi->space[index]; + + proxy_vxi = space->vx_nsproxy; + fs_vxi = space->vx_fs; if (mask & CLONE_FS) { fs = copy_fs_struct(current->fs); @@ -292,7 +302,7 @@ int vx_set_space(struct vx_info *vxi, un if (mask & CLONE_FS) { spin_lock(&fs_vxi->lock); - vxi->vx_fs[index] = fs; + space->vx_fs = fs; kill = !--fs_vxi->users; spin_unlock(&fs_vxi->lock); } @@ -310,15 +320,16 @@ int vx_set_space(struct vx_info *vxi, un goto out_put; } - proxy_new = xchg(&vxi->vx_nsproxy[index], proxy_new); - vxi->vx_nsmask[index] |= mask; + proxy_new = xchg(&space->vx_nsproxy, proxy_new); + space->vx_nsmask |= mask; if (mask & CLONE_NEWUSER) { const struct cred *cred; vxdprintk(VXD_CBIT(space, 10), "vx_set_space(%p[#%u],%p,%p) cred (%p,%p)", - vxi, vxi->vx_id, vxi->vx_real_cred, vxi->vx_cred, + vxi, vxi->vx_id, + space->vx_real_cred, space->vx_cred, current->real_cred, current->cred); if (current->real_cred) { @@ -326,7 +337,7 @@ int vx_set_space(struct vx_info *vxi, un alter_cred_subscribers(cred, 1); } else cred = NULL; - cred = xchg(&vxi->vx_real_cred, cred); + cred = xchg(&space->vx_real_cred, cred); if (cred) { alter_cred_subscribers(cred, -1); put_cred(cred); @@ -337,7 +348,7 @@ int vx_set_space(struct vx_info *vxi, un alter_cred_subscribers(cred, 1); } else cred = NULL; - cred = xchg(&vxi->vx_cred, cred); + cred = xchg(&space->vx_cred, cred); if (cred) { alter_cred_subscribers(cred, -1); put_cred(cred);