diff options
| -rw-r--r-- | drivers/nvme/host/fc.c | 19 |
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 | } |
