aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/nvme/host/fc.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index b29b12498a1a..ba8f2a9cbdaf 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -2107,7 +2107,7 @@ nvme_fc_map_data(struct nvme_fc_ctrl *ctrl, struct request *rq,
2107 2107
2108 freq->sg_cnt = 0; 2108 freq->sg_cnt = 0;
2109 2109
2110 if (!blk_rq_payload_bytes(rq)) 2110 if (!blk_rq_nr_phys_segments(rq))
2111 return 0; 2111 return 0;
2112 2112
2113 freq->sg_table.sgl = freq->first_sgl; 2113 freq->sg_table.sgl = freq->first_sgl;
@@ -2304,12 +2304,23 @@ nvme_fc_queue_rq(struct blk_mq_hw_ctx *hctx,
2304 if (ret) 2304 if (ret)
2305 return ret; 2305 return ret;
2306 2306
2307 data_len = blk_rq_payload_bytes(rq); 2307 /*
2308 if (data_len) 2308 * nvme core doesn't quite treat the rq opaquely. Commands such
2309 * as WRITE ZEROES will return a non-zero rq payload_bytes yet
2310 * there is no actual payload to be transferred.
2311 * To get it right, key data transmission on there being 1 or
2312 * more physical segments in the sg list. If there is no
2313 * physical segments, there is no payload.
2314 */
2315 if (blk_rq_nr_phys_segments(rq)) {
2316 data_len = blk_rq_payload_bytes(rq);
2309 io_dir = ((rq_data_dir(rq) == WRITE) ? 2317 io_dir = ((rq_data_dir(rq) == WRITE) ?
2310 NVMEFC_FCP_WRITE : NVMEFC_FCP_READ); 2318 NVMEFC_FCP_WRITE : NVMEFC_FCP_READ);
2311 else 2319 } else {
2320 data_len = 0;
2312 io_dir = NVMEFC_FCP_NODATA; 2321 io_dir = NVMEFC_FCP_NODATA;
2322 }
2323
2313 2324
2314 return nvme_fc_start_fcp_op(ctrl, queue, op, data_len, io_dir); 2325 return nvme_fc_start_fcp_op(ctrl, queue, op, data_len, io_dir);
2315} 2326}