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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:
"Driver (and enclosure) only fixes. Most are obvious. The big change is
in the tcm_loop driver to add command draining to error handling (the
lack of which was causing hangs with the potential for double use
crashes)"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: target: file: Use kzalloc_flex for aio_cmd
scsi: scsi_transport_sas: Fix the maximum channel scanning issue
scsi: target: tcm_loop: Drain commands in target_reset handler
scsi: ibmvfc: Fix OOB access in ibmvfc_discover_targets_done()
scsi: ses: Handle positive SCSI error from ses_recv_diag()

+51 -10
+2 -1
drivers/scsi/ibmvscsi/ibmvfc.c
··· 4966 4966 switch (mad_status) { 4967 4967 case IBMVFC_MAD_SUCCESS: 4968 4968 ibmvfc_dbg(vhost, "Discover Targets succeeded\n"); 4969 - vhost->num_targets = be32_to_cpu(rsp->num_written); 4969 + vhost->num_targets = min_t(u32, be32_to_cpu(rsp->num_written), 4970 + max_targets); 4970 4971 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_ALLOC_TGTS); 4971 4972 break; 4972 4973 case IBMVFC_MAD_FAILED:
+1 -1
drivers/scsi/scsi_transport_sas.c
··· 1734 1734 break; 1735 1735 1736 1736 default: 1737 - if (channel < shost->max_channel) { 1737 + if (channel <= shost->max_channel) { 1738 1738 res = scsi_scan_host_selected(shost, channel, id, lun, 1739 1739 SCSI_SCAN_MANUAL); 1740 1740 } else {
+1 -1
drivers/scsi/ses.c
··· 215 215 unsigned char *type_ptr = ses_dev->page1_types; 216 216 unsigned char *desc_ptr = ses_dev->page2 + 8; 217 217 218 - if (ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len) < 0) 218 + if (ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len)) 219 219 return NULL; 220 220 221 221 for (i = 0; i < ses_dev->page1_num_types; i++, type_ptr += 4) {
+46 -6
drivers/target/loopback/tcm_loop.c
··· 26 26 #include <linux/slab.h> 27 27 #include <linux/types.h> 28 28 #include <linux/configfs.h> 29 + #include <linux/blk-mq.h> 29 30 #include <scsi/scsi.h> 30 31 #include <scsi/scsi_tcq.h> 31 32 #include <scsi/scsi_host.h> ··· 270 269 return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED; 271 270 } 272 271 272 + static bool tcm_loop_flush_work_iter(struct request *rq, void *data) 273 + { 274 + struct scsi_cmnd *sc = blk_mq_rq_to_pdu(rq); 275 + struct tcm_loop_cmd *tl_cmd = scsi_cmd_priv(sc); 276 + struct se_cmd *se_cmd = &tl_cmd->tl_se_cmd; 277 + 278 + flush_work(&se_cmd->work); 279 + return true; 280 + } 281 + 273 282 static int tcm_loop_target_reset(struct scsi_cmnd *sc) 274 283 { 275 284 struct tcm_loop_hba *tl_hba; 276 285 struct tcm_loop_tpg *tl_tpg; 286 + struct Scsi_Host *sh = sc->device->host; 287 + int ret; 277 288 278 289 /* 279 290 * Locate the tcm_loop_hba_t pointer 280 291 */ 281 - tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); 292 + tl_hba = *(struct tcm_loop_hba **)shost_priv(sh); 282 293 if (!tl_hba) { 283 294 pr_err("Unable to perform device reset without active I_T Nexus\n"); 284 295 return FAILED; ··· 299 286 * Locate the tl_tpg pointer from TargetID in sc->device->id 300 287 */ 301 288 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; 302 - if (tl_tpg) { 303 - tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE; 304 - return SUCCESS; 305 - } 306 - return FAILED; 289 + if (!tl_tpg) 290 + return FAILED; 291 + 292 + /* 293 + * Issue a LUN_RESET to drain all commands that the target core 294 + * knows about. This handles commands not yet marked CMD_T_COMPLETE. 295 + */ 296 + ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun, 0, TMR_LUN_RESET); 297 + if (ret != TMR_FUNCTION_COMPLETE) 298 + return FAILED; 299 + 300 + /* 301 + * Flush any deferred target core completion work that may still be 302 + * queued. Commands that already had CMD_T_COMPLETE set before the TMR 303 + * are skipped by the TMR drain, but their async completion work 304 + * (transport_lun_remove_cmd → percpu_ref_put, release_cmd → scsi_done) 305 + * may still be pending in target_completion_wq. 306 + * 307 + * The SCSI EH will reuse in-flight scsi_cmnd structures for recovery 308 + * commands (e.g. TUR) immediately after this handler returns SUCCESS — 309 + * if deferred work is still pending, the memset in queuecommand would 310 + * zero the se_cmd while the work accesses it, leaking the LUN 311 + * percpu_ref and hanging configfs unlink forever. 312 + * 313 + * Use blk_mq_tagset_busy_iter() to find all started requests and 314 + * flush_work() on each — the same pattern used by mpi3mr, scsi_debug, 315 + * and other SCSI drivers to drain outstanding commands during reset. 316 + */ 317 + blk_mq_tagset_busy_iter(&sh->tag_set, tcm_loop_flush_work_iter, NULL); 318 + 319 + tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE; 320 + return SUCCESS; 307 321 } 308 322 309 323 static const struct scsi_host_template tcm_loop_driver_template = {
+1 -1
drivers/target/target_core_file.c
··· 276 276 ssize_t len = 0; 277 277 int ret = 0, i; 278 278 279 - aio_cmd = kmalloc_flex(*aio_cmd, bvecs, sgl_nents); 279 + aio_cmd = kzalloc_flex(*aio_cmd, bvecs, sgl_nents); 280 280 if (!aio_cmd) 281 281 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 282 282