+ /* in case of range overlap, the location must be same */
+ if (range_compare_loc(new, erange) != 0) {
+ CERROR("the start of given range "DRANGE" conflict to"
+ "an existing range "DRANGE"\n",
+ PRANGE(new), PRANGE(erange));
+ GOTO(out, rc = -EIO);
+ }
+
+ if (new->lsr_end < erange->lsr_end)
+ GOTO(out, rc);
+ do_merge = 1;
+ } else if (rc == -ENOENT) {
+ /* check for merge case: optimizes for single mds lustre.
+ * As entry does not exist, returned entry must be left side
+ * entry compared to start of new range (ref dio_lookup()).
+ * So try to merge from left.
+ */
+ if (new->lsr_start == erange->lsr_end &&
+ range_compare_loc(new, erange) == 0)
+ do_merge = 1;
+ } else {
+ /* no overlap allowed in fld, so failure in lookup is error */
+ GOTO(out, rc);
+ }
+
+ if (do_merge) {
+ /* new range will be merged with the existing one.
+ * delete this range at first. */
+ rc = fld_index_delete(fld, env, erange, th);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ new->lsr_start = min(erange->lsr_start, new->lsr_start);
+ new->lsr_end = max(erange->lsr_end, new->lsr_end);
+ do_merge = 0;
+ }
+
+ /* STEP 2: try to merge with next range */
+ rc = fld_index_lookup(fld, env, new->lsr_end, erange);
+ if (rc == 0) {
+ /* found a matched range, meaning we're either
+ * overlapping or ajacent, must merge with it. */
+ do_merge = 1;
+ } else if (rc == -ENOENT) {
+ /* this range is left of new range end point */
+ LASSERT(erange->lsr_end <= new->lsr_end);