scsi: core: Have SCSI midlayer retry scsi_report_lun_scan() errors

This has scsi_report_lun_scan() have the SCSI midlayer retry errors instead
of driving them itself.

There is one behavior change where we no longer retry when
scsi_execute_cmd() returns < 0, but we should be ok. We don't need to retry
for failures like the queue being removed, and for the case where there are
no tags/reqs the block layer waits/retries for us. For possible memory
allocation failures from blk_rq_map_kern() we use GFP_NOIO, so retrying
will probably not help.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
Link: https://lore.kernel.org/r/20240123002220.129141-14-michael.christie@oracle.com
Acked-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Mike Christie 2024-01-22 18:22:14 -06:00 committed by Martin K. Petersen
parent 21bdff48e1
commit 8d24677ebb

View File

@ -1416,14 +1416,34 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
unsigned int length;
u64 lun;
unsigned int num_luns;
unsigned int retries;
int result;
struct scsi_lun *lunp, *lun_data;
struct scsi_sense_hdr sshdr;
struct scsi_device *sdev;
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
struct scsi_failure failure_defs[] = {
{
.sense = UNIT_ATTENTION,
.asc = SCMD_FAILURE_ASC_ANY,
.ascq = SCMD_FAILURE_ASCQ_ANY,
.result = SAM_STAT_CHECK_CONDITION,
},
/* Fail all CCs except the UA above */
{
.sense = SCMD_FAILURE_SENSE_ANY,
.result = SAM_STAT_CHECK_CONDITION,
},
/* Retry any other errors not listed above */
{
.result = SCMD_FAILURE_RESULT_ANY,
},
{}
};
struct scsi_failures failures = {
.total_allowed = 3,
.failure_definitions = failure_defs,
};
const struct scsi_exec_args exec_args = {
.sshdr = &sshdr,
.failures = &failures,
};
int ret = 0;
@ -1494,29 +1514,18 @@ retry:
* should come through as a check condition, and will not generate
* a retry.
*/
for (retries = 0; retries < 3; retries++) {
SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
"scsi scan: Sending REPORT LUNS to (try %d)\n",
retries));
scsi_failures_reset_retries(&failures);
result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN,
lun_data, length,
SCSI_REPORT_LUNS_TIMEOUT, 3,
&exec_args);
SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
"scsi scan: Sending REPORT LUNS\n"));
SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
"scsi scan: REPORT LUNS"
" %s (try %d) result 0x%x\n",
result ? "failed" : "successful",
retries, result));
if (result == 0)
break;
else if (scsi_sense_valid(&sshdr)) {
if (sshdr.sense_key != UNIT_ATTENTION)
break;
}
}
result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN, lun_data,
length, SCSI_REPORT_LUNS_TIMEOUT, 3,
&exec_args);
SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
"scsi scan: REPORT LUNS %s result 0x%x\n",
result ? "failed" : "successful", result));
if (result) {
/*
* The device probably does not support a REPORT LUN command