- mutex_lock(&crp->crp_lock);
- /* new node index */
-
- if (crp->crp_cnt >= crp->crp_max) {
- /* no more room */
- /* allocate a new vector */
- OBD_ALLOC(v, NODE_VECTOR_SZ * sizeof(v[0]));
- if (v == NULL)
- GOTO(out, rc = -ENOMEM);
-
- if (crp->crp_max == 0)
- osz = 0;
- else
- osz = sizeof(new_vv[0]) *
- (crp->crp_max / NODE_VECTOR_SZ + 1);
-
- nsz = osz + sizeof(new_vv[0]);
- /* increase main vector size */
- OBD_ALLOC(new_vv, nsz);
- if (new_vv == NULL) {
- OBD_FREE(v, NODE_VECTOR_SZ * sizeof(v[0]));
- GOTO(out, rc = -ENOMEM);
- }
-
- if (osz == 0) {
- crp->crp_max = NODE_VECTOR_SZ - 1;
- } else {
- memcpy(new_vv, crp->crp_node, osz);
- OBD_FREE(crp->crp_node, osz);
- crp->crp_max += NODE_VECTOR_SZ;
- }
-
- crp->crp_node = new_vv;
- crp->crp_node[crp->crp_max / NODE_VECTOR_SZ] = v;
+ OBD_ALLOC_PTR(node);
+ if (!node)
+ RETURN(-ENOMEM);
+ node->pn_offset = extent->offset;
+ node->pn_end = end;
+
+ spin_lock(&crp->crp_lock);
+ total = crp->crp_total;
+ /* Search just before and just after the target interval
+ * to find intervals that would be adjacent. Remove them
+ * too and add their extra length to 'node'.
+ */
+ while ((overlap = progress_iter_first(&crp->crp_root,
+ (node->pn_offset == 0 ?
+ 0 : node->pn_offset - 1),
+ (node->pn_end == LUSTRE_EOF ?
+ LUSTRE_EOF : node->pn_end + 1)))
+ != NULL) {
+ node->pn_offset = min(node->pn_offset, overlap->pn_offset);
+ node->pn_end = max(node->pn_end, overlap->pn_end);
+ progress_remove(overlap, &crp->crp_root);
+ total -= overlap->pn_end - overlap->pn_offset + 1;
+ OBD_FREE_PTR(overlap);