Commit 8d24677e authored by Mike Christie's avatar Mike Christie Committed by Martin K. Petersen
Browse files

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: default avatarMike Christie <michael.christie@oracle.com>
Link: https://lore.kernel.org/r/20240123002220.129141-14-michael.christie@oracle.com


Acked-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 21bdff48
Loading
Loading
Loading
Loading
+33 −24
Original line number Diff line number Diff line
@@ -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 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
	 * should come through as a check condition, and will not generate
	 * a retry.
	 */
	for (retries = 0; retries < 3; retries++) {
	scsi_failures_reset_retries(&failures);

	SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
				"scsi scan: Sending REPORT LUNS to (try %d)\n",
				retries));
			  "scsi scan: Sending REPORT LUNS\n"));

		result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN,
					  lun_data, length,
					  SCSI_REPORT_LUNS_TIMEOUT, 3,
	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 (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;
		}
	}

			  "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