Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / kernel / vserver / context.c
index d24d014..c80df75 100644 (file)
@@ -16,7 +16,6 @@
  *  V0.09  revert to non RCU for now
  *  V0.10  and back to working RCU hash
  *  V0.11  and back to locking again
- *  V0.12  have __create claim() the vxi
  *
  */
 
@@ -196,9 +195,9 @@ static inline void __hash_vx_info(struct vx_info *vxi)
 
 static inline void __unhash_vx_info(struct vx_info *vxi)
 {
+       vxd_assert_lock(&vx_info_hash_lock);
        vxdprintk(VXD_CBIT(xid, 4),
                "__unhash_vx_info: %p[#%d]", vxi, vxi->vx_id);
-       spin_lock(&vx_info_hash_lock);
        vxh_unhash_vx_info(vxi);
 
        /* context must be hashed */
@@ -206,7 +205,6 @@ static inline void __unhash_vx_info(struct vx_info *vxi)
 
        vxi->vx_state &= ~VXS_HASHED;
        hlist_del(&vxi->vx_hlist);
-       spin_unlock(&vx_info_hash_lock);
 }
 
 
@@ -328,7 +326,7 @@ out_unlock:
 /*     __create_vx_info()
 
        * create the requested context
-       * get(), claim() and hash it                            */
+       * get() and hash it                                     */
 
 static struct vx_info * __create_vx_info(int id)
 {
@@ -373,7 +371,6 @@ static struct vx_info * __create_vx_info(int id)
        /* new context */
        vxdprintk(VXD_CBIT(xid, 0),
                "create_vx_info(%d) = %p (new)", id, new);
-       claim_vx_info(new, NULL);
        __hash_vx_info(get_vx_info(new));
        vxi = new, new = NULL;
 
@@ -392,7 +389,9 @@ out_unlock:
 void unhash_vx_info(struct vx_info *vxi)
 {
        __shutdown_vx_info(vxi);
+       spin_lock(&vx_info_hash_lock);
        __unhash_vx_info(vxi);
+       spin_unlock(&vx_info_hash_lock);
        __wakeup_vx_info(vxi);
 }
 
@@ -637,7 +636,7 @@ void vx_set_persistent(struct vx_info *vxi)
                "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
 
        get_vx_info(vxi);
-       claim_vx_info(vxi, NULL);
+       claim_vx_info(vxi, current);
 }
 
 void vx_clear_persistent(struct vx_info *vxi)
@@ -645,7 +644,7 @@ void vx_clear_persistent(struct vx_info *vxi)
        vxdprintk(VXD_CBIT(xid, 6),
                "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
 
-       release_vx_info(vxi, NULL);
+       release_vx_info(vxi, current);
        put_vx_info(vxi);
 }
 
@@ -669,19 +668,11 @@ void      exit_vx_info(struct task_struct *p, int code)
                vx_nproc_dec(p);
 
                vxi->exit_code = code;
-               release_vx_info(vxi, p);
-       }
-}
-
-void   exit_vx_info_early(struct task_struct *p, int code)
-{
-       struct vx_info *vxi = p->vx_info;
-
-       if (vxi) {
                if (vxi->vx_initpid == p->tgid)
                        vx_exit_init(vxi, p, code);
                if (vxi->vx_reaper == p)
                        vx_set_reaper(vxi, child_reaper);
+               release_vx_info(vxi, p);
        }
 }
 
@@ -763,22 +754,26 @@ int vc_ctx_create(uint32_t xid, void __user *data)
        /* initial flags */
        new_vxi->vx_flags = vc_data.flagword;
 
+       /* get a reference for persistent contexts */
+       if ((vc_data.flagword & VXF_PERSISTENT))
+               vx_set_persistent(new_vxi);
+
        ret = -ENOEXEC;
        if (vs_state_change(new_vxi, VSC_STARTUP))
-               goto out;
-
+               goto out_unhash;
        ret = vx_migrate_task(current, new_vxi);
-       if (ret)
+       if (!ret) {
+               /* return context id on success */
+               ret = new_vxi->vx_id;
                goto out;
-
-       /* return context id on success */
-       ret = new_vxi->vx_id;
-
-       /* get a reference for persistent contexts */
+       }
+out_unhash:
+       /* prepare for context disposal */
+       new_vxi->vx_state |= VXS_SHUTDOWN;
        if ((vc_data.flagword & VXF_PERSISTENT))
-               vx_set_persistent(new_vxi);
+               vx_clear_persistent(new_vxi);
+       __unhash_vx_info(new_vxi);
 out:
-       release_vx_info(new_vxi, NULL);
        put_vx_info(new_vxi);
        return ret;
 }