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.

scsi: core: Add error codes for internal SCSI midlayer use

If a driver returns:

- DID_TARGET_FAILURE

- DID_NEXUS_FAILURE

- DID_ALLOC_FAILURE

- DID_MEDIUM_ERROR

we hit a couple bugs:

1. The SCSI error handler runs because scsi_decide_disposition() has no
case statements for them and we return FAILED.

2. For SG IO the userspace app gets a success status instead of failed,
because scsi_result_to_blk_status() clears those errors.

This patch adds a new internal error code byte for use by the SCSI
midlayer. This will be used instead of the above error codes, so we don't
have to play that clearing the host code game in
scsi_result_to_blk_status() and drivers cannot accidentally use them.

A subsequent commit will then remove the internal users of the above codes
and convert us to use the new ones.

Link: https://lore.kernel.org/r/20220812010027.8251-9-michael.christie@oracle.com
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Mike Christie and committed by
Martin K. Petersen
36ebf1e2 ebb54b20

+38
+5
drivers/scsi/scsi_error.c
··· 514 514 } 515 515 } 516 516 517 + static inline void set_scsi_ml_byte(struct scsi_cmnd *cmd, u8 status) 518 + { 519 + cmd->result = (cmd->result & 0xffff00ff) | (status << 8); 520 + } 521 + 517 522 /** 518 523 * scsi_check_sense - Examine scsi cmd sense 519 524 * @scmd: Cmd to have sense checked.
+22
drivers/scsi/scsi_lib.c
··· 576 576 return false; 577 577 } 578 578 579 + static inline u8 get_scsi_ml_byte(int result) 580 + { 581 + return (result >> 8) & 0xff; 582 + } 583 + 579 584 /** 580 585 * scsi_result_to_blk_status - translate a SCSI result code into blk_status_t 581 586 * @cmd: SCSI command ··· 591 586 */ 592 587 static blk_status_t scsi_result_to_blk_status(struct scsi_cmnd *cmd, int result) 593 588 { 589 + /* 590 + * Check the scsi-ml byte first in case we converted a host or status 591 + * byte. 592 + */ 593 + switch (get_scsi_ml_byte(result)) { 594 + case SCSIML_STAT_OK: 595 + break; 596 + case SCSIML_STAT_RESV_CONFLICT: 597 + return BLK_STS_NEXUS; 598 + case SCSIML_STAT_NOSPC: 599 + return BLK_STS_NOSPC; 600 + case SCSIML_STAT_MED_ERROR: 601 + return BLK_STS_MEDIUM; 602 + case SCSIML_STAT_TGT_FAILURE: 603 + return BLK_STS_TARGET; 604 + } 605 + 594 606 switch (host_byte(result)) { 595 607 case DID_OK: 596 608 if (scsi_status_is_good(result))
+11
drivers/scsi/scsi_priv.h
··· 19 19 #define SCSI_CMD_RETRIES_NO_LIMIT -1 20 20 21 21 /* 22 + * Error codes used by scsi-ml internally. These must not be used by drivers. 23 + */ 24 + enum scsi_ml_status { 25 + SCSIML_STAT_OK = 0x00, 26 + SCSIML_STAT_RESV_CONFLICT = 0x01, /* Reservation conflict */ 27 + SCSIML_STAT_NOSPC = 0x02, /* Space allocation on the dev failed */ 28 + SCSIML_STAT_MED_ERROR = 0x03, /* Medium error */ 29 + SCSIML_STAT_TGT_FAILURE = 0x04, /* Permanent target failure */ 30 + }; 31 + 32 + /* 22 33 * Scsi Error Handler Flags 23 34 */ 24 35 #define SCSI_EH_ABORT_SCHEDULED 0x0002 /* Abort has been scheduled */