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:
"Four driver fixes and one core fix.

The core fix closes a race window where we could kick off a second
asynchronous scan because the test and set of the variable preventing
it isn't atomic"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: hisi_sas: Stop using queue #0 always for v2 hw
scsi: ibmvscsi: Fix potential race after loss of transport
scsi: mptfusion: Fix null pointer dereferences in mptscsih_remove()
scsi: qla2xxx: Return EBUSY on fcport deletion
scsi: core: Don't start concurrent async scan on same host

+43 -21
+8 -5
drivers/message/fusion/mptscsih.c
··· 1176 1176 MPT_SCSI_HOST *hd; 1177 1177 int sz1; 1178 1178 1179 - if((hd = shost_priv(host)) == NULL) 1180 - return; 1179 + if (host == NULL) 1180 + hd = NULL; 1181 + else 1182 + hd = shost_priv(host); 1181 1183 1182 1184 mptscsih_shutdown(pdev); 1183 1185 ··· 1195 1193 "Free'd ScsiLookup (%d) memory\n", 1196 1194 ioc->name, sz1)); 1197 1195 1198 - kfree(hd->info_kbuf); 1196 + if (hd) 1197 + kfree(hd->info_kbuf); 1199 1198 1200 1199 /* NULL the Scsi_Host pointer 1201 1200 */ 1202 1201 ioc->sh = NULL; 1203 1202 1204 - scsi_host_put(host); 1205 - 1203 + if (host) 1204 + scsi_host_put(host); 1206 1205 mpt_detach(pdev); 1207 1206 1208 1207 }
+1 -1
drivers/scsi/hisi_sas/hisi_sas_main.c
··· 445 445 } 446 446 } 447 447 448 - if (scmd) { 448 + if (scmd && hisi_hba->shost->nr_hw_queues) { 449 449 unsigned int dq_index; 450 450 u32 blk_tag; 451 451
+26 -10
drivers/scsi/ibmvscsi/ibmvscsi.c
··· 807 807 } 808 808 809 809 /** 810 + * ibmvscsi_set_request_limit - Set the adapter request_limit in response to 811 + * an adapter failure, reset, or SRP Login. Done under host lock to prevent 812 + * race with SCSI command submission. 813 + * @hostdata: adapter to adjust 814 + * @limit: new request limit 815 + */ 816 + static void ibmvscsi_set_request_limit(struct ibmvscsi_host_data *hostdata, int limit) 817 + { 818 + unsigned long flags; 819 + 820 + spin_lock_irqsave(hostdata->host->host_lock, flags); 821 + atomic_set(&hostdata->request_limit, limit); 822 + spin_unlock_irqrestore(hostdata->host->host_lock, flags); 823 + } 824 + 825 + /** 810 826 * ibmvscsi_reset_host - Reset the connection to the server 811 827 * @hostdata: struct ibmvscsi_host_data to reset 812 828 */ 813 829 static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata) 814 830 { 815 831 scsi_block_requests(hostdata->host); 816 - atomic_set(&hostdata->request_limit, 0); 832 + ibmvscsi_set_request_limit(hostdata, 0); 817 833 818 834 purge_requests(hostdata, DID_ERROR); 819 835 hostdata->action = IBMVSCSI_HOST_ACTION_RESET; ··· 1162 1146 dev_info(hostdata->dev, "SRP_LOGIN_REJ reason %u\n", 1163 1147 evt_struct->xfer_iu->srp.login_rej.reason); 1164 1148 /* Login failed. */ 1165 - atomic_set(&hostdata->request_limit, -1); 1149 + ibmvscsi_set_request_limit(hostdata, -1); 1166 1150 return; 1167 1151 default: 1168 1152 dev_err(hostdata->dev, "Invalid login response typecode 0x%02x!\n", 1169 1153 evt_struct->xfer_iu->srp.login_rsp.opcode); 1170 1154 /* Login failed. */ 1171 - atomic_set(&hostdata->request_limit, -1); 1155 + ibmvscsi_set_request_limit(hostdata, -1); 1172 1156 return; 1173 1157 } 1174 1158 ··· 1179 1163 * This value is set rather than added to request_limit because 1180 1164 * request_limit could have been set to -1 by this client. 1181 1165 */ 1182 - atomic_set(&hostdata->request_limit, 1166 + ibmvscsi_set_request_limit(hostdata, 1183 1167 be32_to_cpu(evt_struct->xfer_iu->srp.login_rsp.req_lim_delta)); 1184 1168 1185 1169 /* If we had any pending I/Os, kick them */ ··· 1211 1195 login->req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | 1212 1196 SRP_BUF_FORMAT_INDIRECT); 1213 1197 1214 - spin_lock_irqsave(hostdata->host->host_lock, flags); 1215 1198 /* Start out with a request limit of 0, since this is negotiated in 1216 1199 * the login request we are just sending and login requests always 1217 1200 * get sent by the driver regardless of request_limit. 1218 1201 */ 1219 - atomic_set(&hostdata->request_limit, 0); 1202 + ibmvscsi_set_request_limit(hostdata, 0); 1220 1203 1204 + spin_lock_irqsave(hostdata->host->host_lock, flags); 1221 1205 rc = ibmvscsi_send_srp_event(evt_struct, hostdata, login_timeout * 2); 1222 1206 spin_unlock_irqrestore(hostdata->host->host_lock, flags); 1223 1207 dev_info(hostdata->dev, "sent SRP login\n"); ··· 1797 1781 return; 1798 1782 case VIOSRP_CRQ_XPORT_EVENT: /* Hypervisor telling us the connection is closed */ 1799 1783 scsi_block_requests(hostdata->host); 1800 - atomic_set(&hostdata->request_limit, 0); 1784 + ibmvscsi_set_request_limit(hostdata, 0); 1801 1785 if (crq->format == 0x06) { 1802 1786 /* We need to re-setup the interpartition connection */ 1803 1787 dev_info(hostdata->dev, "Re-enabling adapter!\n"); ··· 2153 2137 } 2154 2138 2155 2139 hostdata->action = IBMVSCSI_HOST_ACTION_NONE; 2140 + spin_unlock_irqrestore(hostdata->host->host_lock, flags); 2156 2141 2157 2142 if (rc) { 2158 - atomic_set(&hostdata->request_limit, -1); 2143 + ibmvscsi_set_request_limit(hostdata, -1); 2159 2144 dev_err(hostdata->dev, "error after %s\n", action); 2160 2145 } 2161 - spin_unlock_irqrestore(hostdata->host->host_lock, flags); 2162 2146 2163 2147 scsi_unblock_requests(hostdata->host); 2164 2148 } ··· 2242 2226 init_waitqueue_head(&hostdata->work_wait_q); 2243 2227 hostdata->host = host; 2244 2228 hostdata->dev = dev; 2245 - atomic_set(&hostdata->request_limit, -1); 2229 + ibmvscsi_set_request_limit(hostdata, -1); 2246 2230 hostdata->host->max_sectors = IBMVSCSI_MAX_SECTORS_DEFAULT; 2247 2231 2248 2232 if (map_persist_bufs(hostdata)) {
+4 -2
drivers/scsi/qla2xxx/qla_nvme.c
··· 554 554 555 555 fcport = qla_rport->fcport; 556 556 557 - if (!qpair || !fcport || (qpair && !qpair->fw_started) || 558 - (fcport && fcport->deleted)) 557 + if (!qpair || !fcport) 559 558 return -ENODEV; 559 + 560 + if (!qpair->fw_started || fcport->deleted) 561 + return -EBUSY; 560 562 561 563 vha = fcport->vha; 562 564
+4 -3
drivers/scsi/scsi_scan.c
··· 1714 1714 */ 1715 1715 static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) 1716 1716 { 1717 - struct async_scan_data *data; 1717 + struct async_scan_data *data = NULL; 1718 1718 unsigned long flags; 1719 1719 1720 1720 if (strncmp(scsi_scan_type, "sync", 4) == 0) 1721 1721 return NULL; 1722 1722 1723 + mutex_lock(&shost->scan_mutex); 1723 1724 if (shost->async_scan) { 1724 1725 shost_printk(KERN_DEBUG, shost, "%s called twice\n", __func__); 1725 - return NULL; 1726 + goto err; 1726 1727 } 1727 1728 1728 1729 data = kmalloc(sizeof(*data), GFP_KERNEL); ··· 1734 1733 goto err; 1735 1734 init_completion(&data->prev_finished); 1736 1735 1737 - mutex_lock(&shost->scan_mutex); 1738 1736 spin_lock_irqsave(shost->host_lock, flags); 1739 1737 shost->async_scan = 1; 1740 1738 spin_unlock_irqrestore(shost->host_lock, flags); ··· 1748 1748 return data; 1749 1749 1750 1750 err: 1751 + mutex_unlock(&shost->scan_mutex); 1751 1752 kfree(data); 1752 1753 return NULL; 1753 1754 }