Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls

This patch converts tcm_loop to use target_submit_cmd_map_sgls() for
I/O submission and mapping of pre-allocated SGL memory from incoming
scsi_cmnd -> se_cmd descriptors.

This includes removing the original open-coded fabric uses of target
core callers to support transport_generic_map_mem_to_cmd() between
target_setup_cmd_from_cdb() and transport_handle_cdb_direct() logic.

(v2: Use renamed target_submit_cmd_map_sgls)

Reported-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

+8 -54
+8 -54
drivers/target/loopback/tcm_loop.c
··· 166 166 struct tcm_loop_tpg *tl_tpg; 167 167 struct scatterlist *sgl_bidi = NULL; 168 168 u32 sgl_bidi_count = 0; 169 - int ret; 169 + int rc; 170 170 171 171 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); 172 172 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; ··· 187 187 set_host_byte(sc, DID_ERROR); 188 188 goto out_done; 189 189 } 190 - 191 - transport_init_se_cmd(se_cmd, tl_tpg->tl_se_tpg.se_tpg_tfo, 192 - tl_nexus->se_sess, 193 - scsi_bufflen(sc), sc->sc_data_direction, 194 - tcm_loop_sam_attr(sc), &tl_cmd->tl_sense_buf[0]); 195 - 196 190 if (scsi_bidi_cmnd(sc)) { 197 191 struct scsi_data_buffer *sdb = scsi_in(sc); 198 192 ··· 195 201 se_cmd->se_cmd_flags |= SCF_BIDI; 196 202 197 203 } 198 - 199 - if (transport_lookup_cmd_lun(se_cmd, tl_cmd->sc->device->lun) < 0) { 200 - kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); 204 + rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd, 205 + &tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun, 206 + scsi_bufflen(sc), tcm_loop_sam_attr(sc), 207 + sc->sc_data_direction, 0, 208 + scsi_sglist(sc), scsi_sg_count(sc), 209 + sgl_bidi, sgl_bidi_count); 210 + if (rc < 0) { 201 211 set_host_byte(sc, DID_NO_CONNECT); 202 212 goto out_done; 203 213 } 204 - 205 - /* 206 - * Because some userspace code via scsi-generic do not memset their 207 - * associated read buffers, go ahead and do that here for type 208 - * non-data CDBs. Also note that this is currently guaranteed to be a 209 - * single SGL for this case by target core in 210 - * target_setup_cmd_from_cdb() -> transport_generic_cmd_sequencer(). 211 - */ 212 - if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && 213 - se_cmd->data_direction == DMA_FROM_DEVICE) { 214 - struct scatterlist *sg = scsi_sglist(sc); 215 - unsigned char *buf = kmap(sg_page(sg)) + sg->offset; 216 - 217 - if (buf != NULL) { 218 - memset(buf, 0, sg->length); 219 - kunmap(sg_page(sg)); 220 - } 221 - } 222 - 223 - ret = target_setup_cmd_from_cdb(se_cmd, sc->cmnd); 224 - if (ret == -ENOMEM) { 225 - transport_send_check_condition_and_sense(se_cmd, 226 - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); 227 - transport_generic_free_cmd(se_cmd, 0); 228 - return; 229 - } else if (ret < 0) { 230 - if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) 231 - tcm_loop_queue_status(se_cmd); 232 - else 233 - transport_send_check_condition_and_sense(se_cmd, 234 - se_cmd->scsi_sense_reason, 0); 235 - transport_generic_free_cmd(se_cmd, 0); 236 - return; 237 - } 238 - 239 - ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), 240 - scsi_sg_count(sc), sgl_bidi, sgl_bidi_count); 241 - if (ret) { 242 - transport_send_check_condition_and_sense(se_cmd, 243 - se_cmd->scsi_sense_reason, 0); 244 - transport_generic_free_cmd(se_cmd, 0); 245 - return; 246 - } 247 - transport_handle_cdb_direct(se_cmd); 248 214 return; 249 215 250 216 out_done: