Merge to Fedora kernel-2.6.18-1.2255_FC5-vs2.0.2.2-rc9 patched with stable patch...
[linux-2.6.git] / kernel / vserver / context.c
index aa2b220..e2026df 100644 (file)
@@ -16,6 +16,7 @@
  *  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
  *
  */
 
@@ -195,9 +196,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 */
@@ -205,6 +206,7 @@ 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);
 }
 
 
@@ -326,7 +328,7 @@ out_unlock:
 /*     __create_vx_info()
 
        * create the requested context
-       * get() and hash it                                     */
+       * get(), claim() and hash it                            */
 
 static struct vx_info * __create_vx_info(int id)
 {
@@ -371,6 +373,7 @@ 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;
 
@@ -389,9 +392,7 @@ 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);
 }
 
@@ -636,7 +637,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, current);
+       claim_vx_info(vxi, NULL);
 }
 
 void vx_clear_persistent(struct vx_info *vxi)
@@ -644,7 +645,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, current);
+       release_vx_info(vxi, NULL);
        put_vx_info(vxi);
 }
 
@@ -762,26 +763,22 @@ 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_unhash;
+               goto out;
+
        ret = vx_migrate_task(current, new_vxi);
-       if (!ret) {
-               /* return context id on success */
-               ret = new_vxi->vx_id;
+       if (ret)
                goto out;
-       }
-out_unhash:
-       /* prepare for context disposal */
-       new_vxi->vx_state |= VXS_SHUTDOWN;
+
+       /* return context id on success */
+       ret = new_vxi->vx_id;
+
+       /* get a reference for persistent contexts */
        if ((vc_data.flagword & VXF_PERSISTENT))
-               vx_clear_persistent(new_vxi);
-       __unhash_vx_info(new_vxi);
+               vx_set_persistent(new_vxi);
 out:
+       release_vx_info(new_vxi, NULL);
        put_vx_info(new_vxi);
        return ret;
 }