Skip to content

Commit 3467b90

Browse files
committed
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "Thirteen fixes, seven of which are for IBM fibre channel and three additional for fairly serious bugs in drivers (qla2xxx, mpt3sas, aacraid). Of the three core fixes, the most significant is probably the missed run queue causing an indefinite hang. The others are fixing a potential use after free on device close and silencing an incorrect warning" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: ibmvfc: Clean up transport events scsi: ibmvfc: Byte swap status and error codes when logging scsi: ibmvfc: Add failed PRLI to cmd_status lookup array scsi: ibmvfc: Remove "failed" from logged errors scsi: zfcp: reduce flood of fcrscn1 trace records on multi-element RSCN scsi: zfcp: fix scsi_eh host reset with port_forced ERP for non-NPIV FCP devices scsi: zfcp: fix rport unblock if deleted SCSI devices on Scsi_Host scsi: sd: Quiesce warning if device does not report optimal I/O size scsi: sd: Fix a race between closing an sd device and sd I/O scsi: core: Run queue when state is set to running after being blocked scsi: qla4xxx: fix a potential NULL pointer dereference scsi: aacraid: Insure we don't access PCIe space during AER/EEH scsi: mpt3sas: Fix kernel panic during expander reset
2 parents 4ad5283 + d6e2635 commit 3467b90

File tree

13 files changed

+118
-31
lines changed

13 files changed

+118
-31
lines changed

drivers/s390/scsi/zfcp_erp.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,20 @@ static void zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
624624
add_timer(&erp_action->timer);
625625
}
626626

627+
void zfcp_erp_port_forced_reopen_all(struct zfcp_adapter *adapter,
628+
int clear, char *dbftag)
629+
{
630+
unsigned long flags;
631+
struct zfcp_port *port;
632+
633+
write_lock_irqsave(&adapter->erp_lock, flags);
634+
read_lock(&adapter->port_list_lock);
635+
list_for_each_entry(port, &adapter->port_list, list)
636+
_zfcp_erp_port_forced_reopen(port, clear, dbftag);
637+
read_unlock(&adapter->port_list_lock);
638+
write_unlock_irqrestore(&adapter->erp_lock, flags);
639+
}
640+
627641
static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
628642
int clear, char *dbftag)
629643
{
@@ -1341,6 +1355,9 @@ static void zfcp_erp_try_rport_unblock(struct zfcp_port *port)
13411355
struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev);
13421356
int lun_status;
13431357

1358+
if (sdev->sdev_state == SDEV_DEL ||
1359+
sdev->sdev_state == SDEV_CANCEL)
1360+
continue;
13441361
if (zsdev->port != port)
13451362
continue;
13461363
/* LUN under port of interest */

drivers/s390/scsi/zfcp_ext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ extern void zfcp_erp_port_reopen(struct zfcp_port *port, int clear,
7070
char *dbftag);
7171
extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *);
7272
extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *);
73+
extern void zfcp_erp_port_forced_reopen_all(struct zfcp_adapter *adapter,
74+
int clear, char *dbftag);
7375
extern void zfcp_erp_set_lun_status(struct scsi_device *, u32);
7476
extern void zfcp_erp_clear_lun_status(struct scsi_device *, u32);
7577
extern void zfcp_erp_lun_reopen(struct scsi_device *, int, char *);

drivers/s390/scsi/zfcp_fc.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,17 +239,14 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
239239
list_for_each_entry(port, &adapter->port_list, list) {
240240
if ((port->d_id & range) == (ntoh24(page->rscn_fid) & range))
241241
zfcp_fc_test_link(port);
242-
if (!port->d_id)
243-
zfcp_erp_port_reopen(port,
244-
ZFCP_STATUS_COMMON_ERP_FAILED,
245-
"fcrscn1");
246242
}
247243
read_unlock_irqrestore(&adapter->port_list_lock, flags);
248244
}
249245

250246
static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
251247
{
252248
struct fsf_status_read_buffer *status_buffer = (void *)fsf_req->data;
249+
struct zfcp_adapter *adapter = fsf_req->adapter;
253250
struct fc_els_rscn *head;
254251
struct fc_els_rscn_page *page;
255252
u16 i;
@@ -263,6 +260,22 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
263260
no_entries = be16_to_cpu(head->rscn_plen) /
264261
sizeof(struct fc_els_rscn_page);
265262

263+
if (no_entries > 1) {
264+
/* handle failed ports */
265+
unsigned long flags;
266+
struct zfcp_port *port;
267+
268+
read_lock_irqsave(&adapter->port_list_lock, flags);
269+
list_for_each_entry(port, &adapter->port_list, list) {
270+
if (port->d_id)
271+
continue;
272+
zfcp_erp_port_reopen(port,
273+
ZFCP_STATUS_COMMON_ERP_FAILED,
274+
"fcrscn1");
275+
}
276+
read_unlock_irqrestore(&adapter->port_list_lock, flags);
277+
}
278+
266279
for (i = 1; i < no_entries; i++) {
267280
/* skip head and start with 1st element */
268281
page++;

drivers/s390/scsi/zfcp_scsi.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,10 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
368368
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
369369
int ret = SUCCESS, fc_ret;
370370

371+
if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) {
372+
zfcp_erp_port_forced_reopen_all(adapter, 0, "schrh_p");
373+
zfcp_erp_wait(adapter);
374+
}
371375
zfcp_erp_adapter_reopen(adapter, 0, "schrh_1");
372376
zfcp_erp_wait(adapter);
373377
fc_ret = fc_block_scsi_eh(scpnt);

drivers/scsi/aacraid/aacraid.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2640,9 +2640,14 @@ static inline unsigned int cap_to_cyls(sector_t capacity, unsigned divisor)
26402640
return capacity;
26412641
}
26422642

2643+
static inline int aac_pci_offline(struct aac_dev *dev)
2644+
{
2645+
return pci_channel_offline(dev->pdev) || dev->handle_pci_error;
2646+
}
2647+
26432648
static inline int aac_adapter_check_health(struct aac_dev *dev)
26442649
{
2645-
if (unlikely(pci_channel_offline(dev->pdev)))
2650+
if (unlikely(aac_pci_offline(dev)))
26462651
return -1;
26472652

26482653
return (dev)->a_ops.adapter_check_health(dev);

drivers/scsi/aacraid/commsup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
672672
return -ETIMEDOUT;
673673
}
674674

675-
if (unlikely(pci_channel_offline(dev->pdev)))
675+
if (unlikely(aac_pci_offline(dev)))
676676
return -EFAULT;
677677

678678
if ((blink = aac_adapter_check_health(dev)) > 0) {
@@ -772,7 +772,7 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
772772

773773
spin_unlock_irqrestore(&fibptr->event_lock, flags);
774774

775-
if (unlikely(pci_channel_offline(dev->pdev)))
775+
if (unlikely(aac_pci_offline(dev)))
776776
return -EFAULT;
777777

778778
fibptr->flags |= FIB_CONTEXT_FLAG_WAIT;

drivers/scsi/ibmvscsi/ibmvfc.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ static const struct {
139139
{ IBMVFC_FC_FAILURE, IBMVFC_VENDOR_SPECIFIC, DID_ERROR, 1, 1, "vendor specific" },
140140

141141
{ IBMVFC_FC_SCSI_ERROR, 0, DID_OK, 1, 0, "SCSI error" },
142+
{ IBMVFC_FC_SCSI_ERROR, IBMVFC_COMMAND_FAILED, DID_ERROR, 0, 1, "PRLI to device failed." },
142143
};
143144

144145
static void ibmvfc_npiv_login(struct ibmvfc_host *);
@@ -1494,9 +1495,9 @@ static void ibmvfc_log_error(struct ibmvfc_event *evt)
14941495
if (rsp->flags & FCP_RSP_LEN_VALID)
14951496
rsp_code = rsp->data.info.rsp_code;
14961497

1497-
scmd_printk(KERN_ERR, cmnd, "Command (%02X) failed: %s (%x:%x) "
1498+
scmd_printk(KERN_ERR, cmnd, "Command (%02X) : %s (%x:%x) "
14981499
"flags: %x fcp_rsp: %x, resid=%d, scsi_status: %x\n",
1499-
cmnd->cmnd[0], err, vfc_cmd->status, vfc_cmd->error,
1500+
cmnd->cmnd[0], err, be16_to_cpu(vfc_cmd->status), be16_to_cpu(vfc_cmd->error),
15001501
rsp->flags, rsp_code, scsi_get_resid(cmnd), rsp->scsi_status);
15011502
}
15021503

@@ -2022,7 +2023,7 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc)
20222023
sdev_printk(KERN_ERR, sdev, "%s reset failed: %s (%x:%x) "
20232024
"flags: %x fcp_rsp: %x, scsi_status: %x\n", desc,
20242025
ibmvfc_get_cmd_error(be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error)),
2025-
rsp_iu.cmd.status, rsp_iu.cmd.error, fc_rsp->flags, rsp_code,
2026+
be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error), fc_rsp->flags, rsp_code,
20262027
fc_rsp->scsi_status);
20272028
rsp_rc = -EIO;
20282029
} else
@@ -2381,7 +2382,7 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
23812382
sdev_printk(KERN_ERR, sdev, "Abort failed: %s (%x:%x) "
23822383
"flags: %x fcp_rsp: %x, scsi_status: %x\n",
23832384
ibmvfc_get_cmd_error(be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error)),
2384-
rsp_iu.cmd.status, rsp_iu.cmd.error, fc_rsp->flags, rsp_code,
2385+
be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error), fc_rsp->flags, rsp_code,
23852386
fc_rsp->scsi_status);
23862387
rsp_rc = -EIO;
23872388
} else
@@ -2755,16 +2756,18 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost)
27552756
ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE);
27562757
if (crq->format == IBMVFC_PARTITION_MIGRATED) {
27572758
/* We need to re-setup the interpartition connection */
2758-
dev_info(vhost->dev, "Re-enabling adapter\n");
2759+
dev_info(vhost->dev, "Partition migrated, Re-enabling adapter\n");
27592760
vhost->client_migrated = 1;
27602761
ibmvfc_purge_requests(vhost, DID_REQUEUE);
27612762
ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
27622763
ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_REENABLE);
2763-
} else {
2764-
dev_err(vhost->dev, "Virtual adapter failed (rc=%d)\n", crq->format);
2764+
} else if (crq->format == IBMVFC_PARTNER_FAILED || crq->format == IBMVFC_PARTNER_DEREGISTER) {
2765+
dev_err(vhost->dev, "Host partner adapter deregistered or failed (rc=%d)\n", crq->format);
27652766
ibmvfc_purge_requests(vhost, DID_ERROR);
27662767
ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
27672768
ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_RESET);
2769+
} else {
2770+
dev_err(vhost->dev, "Received unknown transport event from partner (rc=%d)\n", crq->format);
27682771
}
27692772
return;
27702773
case IBMVFC_CRQ_CMD_RSP:
@@ -3348,7 +3351,7 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
33483351

33493352
tgt_log(tgt, level, "Process Login failed: %s (%x:%x) rc=0x%02X\n",
33503353
ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
3351-
rsp->status, rsp->error, status);
3354+
be16_to_cpu(rsp->status), be16_to_cpu(rsp->error), status);
33523355
break;
33533356
}
33543357

@@ -3446,9 +3449,10 @@ static void ibmvfc_tgt_plogi_done(struct ibmvfc_event *evt)
34463449
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
34473450

34483451
tgt_log(tgt, level, "Port Login failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n",
3449-
ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)), rsp->status, rsp->error,
3450-
ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)), rsp->fc_type,
3451-
ibmvfc_get_ls_explain(be16_to_cpu(rsp->fc_explain)), rsp->fc_explain, status);
3452+
ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
3453+
be16_to_cpu(rsp->status), be16_to_cpu(rsp->error),
3454+
ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)), be16_to_cpu(rsp->fc_type),
3455+
ibmvfc_get_ls_explain(be16_to_cpu(rsp->fc_explain)), be16_to_cpu(rsp->fc_explain), status);
34523456
break;
34533457
}
34543458

@@ -3619,7 +3623,7 @@ static void ibmvfc_tgt_adisc_done(struct ibmvfc_event *evt)
36193623
fc_explain = (be32_to_cpu(mad->fc_iu.response[1]) & 0x0000ff00) >> 8;
36203624
tgt_info(tgt, "ADISC failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n",
36213625
ibmvfc_get_cmd_error(be16_to_cpu(mad->iu.status), be16_to_cpu(mad->iu.error)),
3622-
mad->iu.status, mad->iu.error,
3626+
be16_to_cpu(mad->iu.status), be16_to_cpu(mad->iu.error),
36233627
ibmvfc_get_fc_type(fc_reason), fc_reason,
36243628
ibmvfc_get_ls_explain(fc_explain), fc_explain, status);
36253629
break;
@@ -3831,9 +3835,10 @@ static void ibmvfc_tgt_query_target_done(struct ibmvfc_event *evt)
38313835

38323836
tgt_log(tgt, level, "Query Target failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n",
38333837
ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
3834-
rsp->status, rsp->error, ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)),
3835-
rsp->fc_type, ibmvfc_get_gs_explain(be16_to_cpu(rsp->fc_explain)),
3836-
rsp->fc_explain, status);
3838+
be16_to_cpu(rsp->status), be16_to_cpu(rsp->error),
3839+
ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)), be16_to_cpu(rsp->fc_type),
3840+
ibmvfc_get_gs_explain(be16_to_cpu(rsp->fc_explain)), be16_to_cpu(rsp->fc_explain),
3841+
status);
38373842
break;
38383843
}
38393844

@@ -3959,7 +3964,7 @@ static void ibmvfc_discover_targets_done(struct ibmvfc_event *evt)
39593964
level += ibmvfc_retry_host_init(vhost);
39603965
ibmvfc_log(vhost, level, "Discover Targets failed: %s (%x:%x)\n",
39613966
ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
3962-
rsp->status, rsp->error);
3967+
be16_to_cpu(rsp->status), be16_to_cpu(rsp->error));
39633968
break;
39643969
case IBMVFC_MAD_DRIVER_FAILED:
39653970
break;
@@ -4024,7 +4029,7 @@ static void ibmvfc_npiv_login_done(struct ibmvfc_event *evt)
40244029
ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
40254030
ibmvfc_log(vhost, level, "NPIV Login failed: %s (%x:%x)\n",
40264031
ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
4027-
rsp->status, rsp->error);
4032+
be16_to_cpu(rsp->status), be16_to_cpu(rsp->error));
40284033
ibmvfc_free_event(evt);
40294034
return;
40304035
case IBMVFC_MAD_CRQ_ERROR:

drivers/scsi/ibmvscsi/ibmvfc.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,14 @@ enum ibmvfc_crq_valid {
7878
IBMVFC_CRQ_XPORT_EVENT = 0xFF,
7979
};
8080

81-
enum ibmvfc_crq_format {
81+
enum ibmvfc_crq_init_msg {
8282
IBMVFC_CRQ_INIT = 0x01,
8383
IBMVFC_CRQ_INIT_COMPLETE = 0x02,
84+
};
85+
86+
enum ibmvfc_crq_xport_evts {
87+
IBMVFC_PARTNER_FAILED = 0x01,
88+
IBMVFC_PARTNER_DEREGISTER = 0x02,
8489
IBMVFC_PARTITION_MIGRATED = 0x06,
8590
};
8691

drivers/scsi/mpt3sas/mpt3sas_base.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3281,12 +3281,18 @@ mpt3sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid)
32813281

32823282
if (smid < ioc->hi_priority_smid) {
32833283
struct scsiio_tracker *st;
3284+
void *request;
32843285

32853286
st = _get_st_from_smid(ioc, smid);
32863287
if (!st) {
32873288
_base_recovery_check(ioc);
32883289
return;
32893290
}
3291+
3292+
/* Clear MPI request frame */
3293+
request = mpt3sas_base_get_msg_frame(ioc, smid);
3294+
memset(request, 0, ioc->request_sz);
3295+
32903296
mpt3sas_base_clear_st(ioc, st);
32913297
_base_recovery_check(ioc);
32923298
return;

drivers/scsi/mpt3sas/mpt3sas_scsih.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,11 +1462,23 @@ mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, u16 smid)
14621462
{
14631463
struct scsi_cmnd *scmd = NULL;
14641464
struct scsiio_tracker *st;
1465+
Mpi25SCSIIORequest_t *mpi_request;
14651466

14661467
if (smid > 0 &&
14671468
smid <= ioc->scsiio_depth - INTERNAL_SCSIIO_CMDS_COUNT) {
14681469
u32 unique_tag = smid - 1;
14691470

1471+
mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
1472+
1473+
/*
1474+
* If SCSI IO request is outstanding at driver level then
1475+
* DevHandle filed must be non-zero. If DevHandle is zero
1476+
* then it means that this smid is free at driver level,
1477+
* so return NULL.
1478+
*/
1479+
if (!mpi_request->DevHandle)
1480+
return scmd;
1481+
14701482
scmd = scsi_host_find_tag(ioc->shost, unique_tag);
14711483
if (scmd) {
14721484
st = scsi_cmd_priv(scmd);

drivers/scsi/qla4xxx/ql4_os.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3203,6 +3203,8 @@ static int qla4xxx_conn_bind(struct iscsi_cls_session *cls_session,
32033203
if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
32043204
return -EINVAL;
32053205
ep = iscsi_lookup_endpoint(transport_fd);
3206+
if (!ep)
3207+
return -EINVAL;
32063208
conn = cls_conn->dd_data;
32073209
qla_conn = conn->dd_data;
32083210
qla_conn->qla_ep = ep->dd_data;

drivers/scsi/scsi_sysfs.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,12 @@ store_state_field(struct device *dev, struct device_attribute *attr,
771771

772772
mutex_lock(&sdev->state_mutex);
773773
ret = scsi_device_set_state(sdev, state);
774+
/*
775+
* If the device state changes to SDEV_RUNNING, we need to run
776+
* the queue to avoid I/O hang.
777+
*/
778+
if (ret == 0 && state == SDEV_RUNNING)
779+
blk_mq_run_hw_queues(sdev->request_queue, true);
774780
mutex_unlock(&sdev->state_mutex);
775781

776782
return ret == 0 ? count : -EINVAL;

drivers/scsi/sd.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,11 +1415,6 @@ static void sd_release(struct gendisk *disk, fmode_t mode)
14151415
scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
14161416
}
14171417

1418-
/*
1419-
* XXX and what if there are packets in flight and this close()
1420-
* XXX is followed by a "rmmod sd_mod"?
1421-
*/
1422-
14231418
scsi_disk_put(sdkp);
14241419
}
14251420

@@ -3076,6 +3071,9 @@ static bool sd_validate_opt_xfer_size(struct scsi_disk *sdkp,
30763071
unsigned int opt_xfer_bytes =
30773072
logical_to_bytes(sdp, sdkp->opt_xfer_blocks);
30783073

3074+
if (sdkp->opt_xfer_blocks == 0)
3075+
return false;
3076+
30793077
if (sdkp->opt_xfer_blocks > dev_max) {
30803078
sd_first_printk(KERN_WARNING, sdkp,
30813079
"Optimal transfer size %u logical blocks " \
@@ -3505,9 +3503,21 @@ static void scsi_disk_release(struct device *dev)
35053503
{
35063504
struct scsi_disk *sdkp = to_scsi_disk(dev);
35073505
struct gendisk *disk = sdkp->disk;
3508-
3506+
struct request_queue *q = disk->queue;
3507+
35093508
ida_free(&sd_index_ida, sdkp->index);
35103509

3510+
/*
3511+
* Wait until all requests that are in progress have completed.
3512+
* This is necessary to avoid that e.g. scsi_end_request() crashes
3513+
* due to clearing the disk->private_data pointer. Wait from inside
3514+
* scsi_disk_release() instead of from sd_release() to avoid that
3515+
* freezing and unfreezing the request queue affects user space I/O
3516+
* in case multiple processes open a /dev/sd... node concurrently.
3517+
*/
3518+
blk_mq_freeze_queue(q);
3519+
blk_mq_unfreeze_queue(q);
3520+
35113521
disk->private_data = NULL;
35123522
put_disk(disk);
35133523
put_device(&sdkp->device->sdev_gendev);

0 commit comments

Comments
 (0)