- test_bulk_req_t *breq = &tsi->tsi_u.bulk;
- int flags = breq->blk_flags;
- int npg = breq->blk_npg;
- srpc_bulk_t *bulk;
- sfw_test_unit_t *tsu;
-
- LASSERT (tsi->tsi_is_client);
-
- if (npg > LNET_MAX_IOV || npg <= 0)
- return -EINVAL;
-
- if (breq->blk_opc != LST_BRW_READ && breq->blk_opc != LST_BRW_WRITE)
- return -EINVAL;
-
- if (flags != LST_BRW_CHECK_NONE &&
- flags != LST_BRW_CHECK_FULL && flags != LST_BRW_CHECK_SIMPLE)
- return -EINVAL;
-
- list_for_each_entry (tsu, &tsi->tsi_units, tsu_list) {
- bulk = srpc_alloc_bulk(npg, breq->blk_opc == LST_BRW_READ);
+ sfw_session_t *sn = tsi->tsi_batch->bat_session;
+ int flags;
+ int npg;
+ int len;
+ int opc;
+ srpc_bulk_t *bulk;
+ sfw_test_unit_t *tsu;
+
+ LASSERT(sn != NULL);
+ LASSERT(tsi->tsi_is_client);
+
+ if ((sn->sn_features & LST_FEAT_BULK_LEN) == 0) {
+ test_bulk_req_t *breq = &tsi->tsi_u.bulk_v0;
+
+ opc = breq->blk_opc;
+ flags = breq->blk_flags;
+ npg = breq->blk_npg;
+ /* NB: this is not going to work for variable page size,
+ * but we have to keep it for compatibility */
+ len = npg * CFS_PAGE_SIZE;
+
+ } else {
+ test_bulk_req_v1_t *breq = &tsi->tsi_u.bulk_v1;
+
+ /* I should never get this step if it's unknown feature
+ * because make_session will reject unknown feature */
+ LASSERT((sn->sn_features & ~LST_FEATS_MASK) == 0);
+
+ opc = breq->blk_opc;
+ flags = breq->blk_flags;
+ len = breq->blk_len;
+ npg = (len + CFS_PAGE_SIZE - 1) >> CFS_PAGE_SHIFT;
+ }
+
+ if (npg > LNET_MAX_IOV || npg <= 0)
+ return -EINVAL;
+
+ if (opc != LST_BRW_READ && opc != LST_BRW_WRITE)
+ return -EINVAL;
+
+ if (flags != LST_BRW_CHECK_NONE &&
+ flags != LST_BRW_CHECK_FULL && flags != LST_BRW_CHECK_SIMPLE)
+ return -EINVAL;
+
+ cfs_list_for_each_entry_typed(tsu, &tsi->tsi_units,
+ sfw_test_unit_t, tsu_list) {
+ bulk = srpc_alloc_bulk(lnet_cpt_of_nid(tsu->tsu_dest.nid),
+ npg, len, opc == LST_BRW_READ);