return end_page - start_page + 1;
}
-void io_lnb_to_tx_lnb(struct niobuf_local *io_lnb, struct niobuf_local *tx_lnb,
- struct niobuf_remote *rnb, int niocount, int npages_local)
+int io_lnb_to_tx_lnb(struct niobuf_local *io_lnb, struct niobuf_local *tx_lnb,
+ struct niobuf_remote *rnb, int niocount, int npages_local)
{
+ int prev_lnb_index = -1;
int lnb_index = 0;
int tx_lnb_pg = 0;
int i;
+ ENTRY;
+
/* for each io in the remote niobuf, we find the offset of the
* starting page in the lnb, then we point the tx lnbs at the matching
* pages in the io lnb, so we can do transfer from just those pages
break;
lnb_index++;
}
+ /* this indicates remote ios overlapped at the page level,
+ * which is impossible until we have unaligned DIO
+ */
+ if (lnb_index == prev_lnb_index) {
+ CDEBUG(D_ERROR,
+ "lnbs overlap at page level: lnb %d, at %llu page offset %d, rnb %d, rnb offset %llu, prev lnb at %llu, page offset %d\n",
+ lnb_index, io_lnb[lnb_index].lnb_file_offset,
+ io_lnb[lnb_index].lnb_page_offset, i,
+ rnb[i].rnb_offset,
+ io_lnb[prev_lnb_index].lnb_file_offset,
+ io_lnb[prev_lnb_index].lnb_page_offset);
+ RETURN(-EINVAL);
+ }
+ prev_lnb_index = lnb_index;
+ /* this means we didn't find the remote IO, which should be
+ * impossible
+ */
+ if (lnb_index == npages_local) {
+ CDEBUG(D_ERROR,
+ "hit end of local pages, remote IO not found!\n");
+ CDEBUG(D_ERROR,
+ "npages_local %d, last offset %llu, rnb %d, rnb offset %llu\n",
+ npages_local,
+ io_lnb[lnb_index - 1].lnb_file_offset, i,
+ rnb[i].rnb_offset);
+ LBUG();
+ }
npages_remote = range_to_page_count(rnb[i].rnb_offset,
rnb[i].rnb_len);
CDEBUG(D_SEC, "nio %d npages_remote %d, lnb_index %d\n", i,
}
LASSERT(len == 0);
}
+ RETURN(0);
}
int tgt_brw_read(struct tgt_session_info *tsi)
if (npages_local != npages_remote) {
LASSERT(compr_type != LL_COMPR_TYPE_NONE);
local_tx_nb = tbc->tbc_lnb2;
- io_lnb_to_tx_lnb(local_io_nb, local_tx_nb, remote_nb,
- niocount, npages_local);
+ rc = io_lnb_to_tx_lnb(local_io_nb, local_tx_nb, remote_nb,
+ niocount, npages_local);
+ if (rc)
+ GOTO(out_commitrw, rc);
}
npages_read = npages_remote;
if (npages_local != npages_remote) {
LASSERT(compr_type != LL_COMPR_TYPE_NONE);
local_tx_nb = tbc->tbc_lnb2;
- io_lnb_to_tx_lnb(local_write_nb, local_tx_nb, remote_nb,
- niocount, npages_local);
+ rc = io_lnb_to_tx_lnb(local_write_nb, local_tx_nb, remote_nb,
+ niocount, npages_local);
+ if (rc)
+ GOTO(out_commitrw, rc);
}
if (body->oa.o_valid & OBD_MD_FLFLAGS &&