On 10/3/22 10:52, Mike Christie wrote:
+static enum scsi_disposition scsi_check_passthrough(struct scsi_cmnd *scmd) +{ + struct scsi_failure *failure; + struct scsi_sense_hdr sshdr; + enum scsi_disposition ret; + u8 status; + int i; + + + if (!scmd->result || !scmd->failures) + return SCSI_RETURN_NOT_HANDLED; + + for (i = 0, failure = &scmd->failures[i]; failure->result; + failure = &scmd->failures[++i]) { + if (failure->result == SCMD_FAILURE_ANY) + goto maybe_retry; + + if (host_byte(scmd->result) && + host_byte(scmd->result) == host_byte(failure->result)) + goto maybe_retry; + + status = get_status_byte(scmd); + if (!status) + continue; + + if (failure->result == SCMD_FAILURE_STAT_ANY && + !scsi_status_is_good(scmd->result)) + goto maybe_retry; + + if (status != __get_status_byte(failure->result)) + continue; + + if (((__get_status_byte(failure->result)) != + SAM_STAT_CHECK_CONDITION) || + (failure->sense == SCMD_FAILURE_SENSE_ANY)) + goto maybe_retry; + + ret = scsi_start_sense_processing(scmd, &sshdr); + if (ret == NEEDS_RETRY) + goto maybe_retry; + else if (ret != SUCCESS) + return ret; + + if (failure->sense != sshdr.sense_key) + continue; + + if (failure->asc == SCMD_FAILURE_ASC_ANY) + goto maybe_retry; + + if (failure->asc != sshdr.asc) + continue; + + if (failure->ascq == SCMD_FAILURE_ASCQ_ANY || + failure->ascq == sshdr.ascq) + goto maybe_retry; + } + + return SCSI_RETURN_NOT_HANDLED; + +maybe_retry: + if (failure->allowed == SCMD_FAILURE_NO_LIMIT || + ++failure->retries <= failure->allowed) + return NEEDS_RETRY; + + return SUCCESS; +}
Since the logic in the above function is nontrivial and since injecting errors may also be nontrivial, please add unit tests for this function. An example is available in commit addbeea6f50b ("testing/selftests: Add tests for the is_signed_type() macro"). Thanks, Bart.