- srpc_bulk_t *bulk = tsu->tsu_private;
- sfw_test_instance_t *tsi = tsu->tsu_instance;
- test_bulk_req_t *breq = &tsi->tsi_u.bulk;
- int npg = breq->blk_npg;
- int flags = breq->blk_flags;
- srpc_client_rpc_t *rpc;
- srpc_brw_reqst_t *req;
- int rc;
-
- LASSERT (bulk != NULL);
- LASSERT (bulk->bk_niov == npg);
-
- rc = sfw_create_test_rpc(tsu, dest, npg, npg * CFS_PAGE_SIZE, &rpc);
- if (rc != 0) return rc;
-
- memcpy(&rpc->crpc_bulk, bulk, offsetof(srpc_bulk_t, bk_iovs[npg]));
- if (breq->blk_opc == LST_BRW_WRITE)
- brw_fill_bulk(&rpc->crpc_bulk, flags, BRW_MAGIC);
- else
- brw_fill_bulk(&rpc->crpc_bulk, flags, BRW_POISON);
-
- req = &rpc->crpc_reqstmsg.msg_body.brw_reqst;
- req->brw_flags = flags;
- req->brw_rw = breq->blk_opc;
- req->brw_len = npg * CFS_PAGE_SIZE;
-
- *rpcpp = rpc;
- return 0;
+ struct srpc_bulk *bulk = tsu->tsu_private;
+ struct sfw_test_instance *tsi = tsu->tsu_instance;
+ struct sfw_session *sn = tsi->tsi_batch->bat_session;
+ struct srpc_client_rpc *rpc;
+ struct srpc_brw_reqst *req;
+ int flags;
+ int npg;
+ int len;
+ int off;
+ int opc;
+ int rc;
+
+ LASSERT(sn != NULL);
+ LASSERT(bulk != NULL);
+
+ if ((sn->sn_features & LST_FEAT_BULK_LEN) == 0) {
+ struct test_bulk_req *breq = &tsi->tsi_u.bulk_v0;
+
+ opc = breq->blk_opc;
+ flags = breq->blk_flags;
+ len = breq->blk_npg * PAGE_SIZE;
+ off = 0;
+
+ } else {
+ struct test_bulk_req_v1 *breq = &tsi->tsi_u.bulk_v1;
+ int off;
+
+ /* 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;
+ off = breq->blk_offset;
+ }
+ npg = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ rc = sfw_create_test_rpc(tsu, dest, sn->sn_features, npg, len, &rpc);
+ if (rc != 0)
+ return rc;
+
+ unsafe_memcpy(&rpc->crpc_bulk, bulk,
+ offsetof(struct srpc_bulk, bk_iovs[npg]),
+ FLEXIBLE_OBJECT);
+ if (opc == LST_BRW_WRITE)
+ brw_fill_bulk(&rpc->crpc_bulk, flags, BRW_MAGIC);
+ else
+ brw_fill_bulk(&rpc->crpc_bulk, flags, BRW_POISON);
+
+ req = &rpc->crpc_reqstmsg.msg_body.brw_reqst;
+ req->brw_flags = flags;
+ req->brw_rw = opc;
+ req->brw_len = len;
+
+ *rpcpp = rpc;
+ return 0;