VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / net / sctp / sm_make_chunk.c
index b80ea90..c2ca732 100644 (file)
@@ -1834,23 +1834,27 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
        /* Allocate storage for the negotiated streams if it is not a temporary          * association.
         */
        if (!asoc->temp) {
-               sctp_assoc_t assoc_id;
+               int assoc_id;
+               int error;
 
                asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
                                               asoc->c.sinit_num_ostreams, gfp);
                if (!asoc->ssnmap)
                        goto clean_up;
 
-               do {
-                       if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
-                               goto clean_up;
-                       spin_lock_bh(&sctp_assocs_id_lock);
-                       assoc_id = (sctp_assoc_t)idr_get_new(&sctp_assocs_id,
-                                                            (void *)asoc);
-                       spin_unlock_bh(&sctp_assocs_id_lock);
-               } while (unlikely((int)assoc_id == -1));
+       retry:
+               if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
+                       goto clean_up;
+               spin_lock_bh(&sctp_assocs_id_lock);
+               error = idr_get_new_above(&sctp_assocs_id, (void *)asoc, 1,
+                                         &assoc_id);
+               spin_unlock_bh(&sctp_assocs_id_lock);
+               if (error == -EAGAIN)
+                       goto retry;
+               else if (error)
+                       goto clean_up;
 
-               asoc->assoc_id = assoc_id;
+               asoc->assoc_id = (sctp_assoc_t) assoc_id;
        }
 
        /* ADDIP Section 4.1 ASCONF Chunk Procedures