+ if (pos < data_off) {
+ for (i = 0; i < comp_size; i++) {
+ uint64_t cur_pos;
+ size_t to_punch;
+ uint32_t mid = comp_array[i].lrc_mirror_id;
+
+ /* skip non-overlapped component */
+ if (pos >= comp_array[i].lrc_end ||
+ data_off <= comp_array[i].lrc_start)
+ continue;
+
+ if (pos < comp_array[i].lrc_start)
+ cur_pos = comp_array[i].lrc_start;
+ else
+ cur_pos = pos;
+
+ if (data_off > comp_array[i].lrc_end)
+ to_punch = comp_array[i].lrc_end -
+ cur_pos;
+ else
+ to_punch = data_off - cur_pos;
+
+ if (comp_array[i].lrc_end == OBD_OBJECT_EOF) {
+ /* the last component can be truncated
+ * safely
+ */
+ rc = llapi_mirror_truncate(fd, mid,
+ cur_pos);
+ /* hole at the end of file, so just
+ * truncate up to set size.
+ */
+ if (!rc && data_off == data_end)
+ rc = llapi_mirror_truncate(fd,
+ mid, data_end);
+ } else {
+ rc = llapi_mirror_punch(fd,
+ comp_array[i].lrc_mirror_id,
+ cur_pos, to_punch);
+ }
+ /* if failed then read failed hole range */
+ if (rc < 0) {
+ rc = 0;
+ pos = cur_pos;
+ if (pos + to_punch == data_off)
+ to_read = data_end - pos;
+ else
+ to_read = to_punch;
+ goto do_read;
+ }
+ }
+ pos = data_off;
+ }
+ if (pos == mirror_end)
+ continue;
+ to_read = data_end - pos;
+do_read:
+ if (!to_read)
+ break;
+
+ assert(data_end <= mirror_end);
+
+ to_read = MIN(buflen, to_read);
+ to_read = ((to_read - 1) | (page_size - 1)) + 1;