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:
"Only one core change, the rest are drivers.

The core change reorders some state operations in the error handler to
try to prevent missed wake ups of the error handler (which can halt
error processing and effectively freeze the entire system)"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: qla2xxx: Sanitize payload size to prevent member overflow
scsi: target: iscsi: Fix use-after-free in iscsit_dec_session_usage_count()
scsi: target: iscsi: Fix use-after-free in iscsit_dec_conn_usage_count()
scsi: core: Wake up the error handler when final completions race against each other
scsi: storvsc: Process unsupported MODE_SENSE_10
scsi: xen: scsiback: Fix potential memory leak in scsiback_remove()

+36 -4
+7
drivers/scsi/qla2xxx/qla_isr.c
··· 878 878 payload_size = sizeof(purex->els_frame_payload); 879 879 } 880 880 881 + if (total_bytes > sizeof(item->iocb.iocb)) 882 + total_bytes = sizeof(item->iocb.iocb); 883 + 881 884 pending_bytes = total_bytes; 882 885 no_bytes = (pending_bytes > payload_size) ? payload_size : 883 886 pending_bytes; ··· 1166 1163 1167 1164 total_bytes = (le16_to_cpu(purex->frame_size) & 0x0FFF) 1168 1165 - PURX_ELS_HEADER_SIZE; 1166 + 1167 + if (total_bytes > sizeof(item->iocb.iocb)) 1168 + total_bytes = sizeof(item->iocb.iocb); 1169 + 1169 1170 pending_bytes = total_bytes; 1170 1171 entry_count = entry_count_remaining = purex->entry_count; 1171 1172 no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ?
+10 -1
drivers/scsi/scsi_error.c
··· 282 282 { 283 283 struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu); 284 284 struct Scsi_Host *shost = scmd->device->host; 285 - unsigned int busy = scsi_host_busy(shost); 285 + unsigned int busy; 286 286 unsigned long flags; 287 287 288 288 spin_lock_irqsave(shost->host_lock, flags); 289 289 shost->host_failed++; 290 + spin_unlock_irqrestore(shost->host_lock, flags); 291 + /* 292 + * The counting of busy requests needs to occur after adding to 293 + * host_failed or after the lock acquire for adding to host_failed 294 + * to prevent a race with host unbusy and missing an eh wakeup. 295 + */ 296 + busy = scsi_host_busy(shost); 297 + 298 + spin_lock_irqsave(shost->host_lock, flags); 290 299 scsi_eh_wakeup(shost, busy); 291 300 spin_unlock_irqrestore(shost->host_lock, flags); 292 301 }
+8
drivers/scsi/scsi_lib.c
··· 376 376 rcu_read_lock(); 377 377 __clear_bit(SCMD_STATE_INFLIGHT, &cmd->state); 378 378 if (unlikely(scsi_host_in_recovery(shost))) { 379 + /* 380 + * Ensure the clear of SCMD_STATE_INFLIGHT is visible to 381 + * other CPUs before counting busy requests. Otherwise, 382 + * reordering can cause CPUs to race and miss an eh wakeup 383 + * when no CPU sees all busy requests as done or timed out. 384 + */ 385 + smp_mb(); 386 + 379 387 unsigned int busy = scsi_host_busy(shost); 380 388 381 389 spin_lock_irqsave(shost->host_lock, flags);
+2 -1
drivers/scsi/storvsc_drv.c
··· 1144 1144 * The current SCSI handling on the host side does 1145 1145 * not correctly handle: 1146 1146 * INQUIRY command with page code parameter set to 0x80 1147 - * MODE_SENSE command with cmd[2] == 0x1c 1147 + * MODE_SENSE and MODE_SENSE_10 command with cmd[2] == 0x1c 1148 1148 * MAINTENANCE_IN is not supported by HyperV FC passthrough 1149 1149 * 1150 1150 * Setup srb and scsi status so this won't be fatal. ··· 1154 1154 1155 1155 if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) || 1156 1156 (stor_pkt->vm_srb.cdb[0] == MODE_SENSE) || 1157 + (stor_pkt->vm_srb.cdb[0] == MODE_SENSE_10) || 1157 1158 (stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN && 1158 1159 hv_dev_is_fc(device))) { 1159 1160 vstor_packet->vm_srb.scsi_status = 0;
+8 -2
drivers/target/iscsi/iscsi_target_util.c
··· 741 741 spin_lock_bh(&sess->session_usage_lock); 742 742 sess->session_usage_count--; 743 743 744 - if (!sess->session_usage_count && sess->session_waiting_on_uc) 744 + if (!sess->session_usage_count && sess->session_waiting_on_uc) { 745 + spin_unlock_bh(&sess->session_usage_lock); 745 746 complete(&sess->session_waiting_on_uc_comp); 747 + return; 748 + } 746 749 747 750 spin_unlock_bh(&sess->session_usage_lock); 748 751 } ··· 813 810 spin_lock_bh(&conn->conn_usage_lock); 814 811 conn->conn_usage_count--; 815 812 816 - if (!conn->conn_usage_count && conn->conn_waiting_on_uc) 813 + if (!conn->conn_usage_count && conn->conn_waiting_on_uc) { 814 + spin_unlock_bh(&conn->conn_usage_lock); 817 815 complete(&conn->conn_waiting_on_uc_comp); 816 + return; 817 + } 818 818 819 819 spin_unlock_bh(&conn->conn_usage_lock); 820 820 }
+1
drivers/xen/xen-scsiback.c
··· 1262 1262 gnttab_page_cache_shrink(&info->free_pages, 0); 1263 1263 1264 1264 dev_set_drvdata(&dev->dev, NULL); 1265 + kfree(info); 1265 1266 } 1266 1267 1267 1268 static int scsiback_probe(struct xenbus_device *dev,