scsi: More detailed I/O errors
Subsystems (3)
cover scsi: More detailed I/O errors
As discussed at LSF the SCSI stack already knows about several error conditions, it's just not well documented. Also there are some more conditions upper layers might be interested in.
This patchset improves the documentation of the existing I/O error codes and adds two more error codes, ENOSPC for thin provisioning failure and ENODATA for medium error.
Hannes Reinecke (3):
scsi: Document enhanced error codes
scsi: Return ENOSPC on thin provisioning failure
scsi: Return ENODATA on medium error
drivers/scsi/scsi_error.c | 26 ++++++++++++++++++++++---- drivers/scsi/scsi_lib.c | 21 +++++++++++++++++++++ include/scsi/scsi.h | 4 ++++ 3 files changed, 47 insertions(+), 4 deletions(-)
Signature · 1 line
1.7.12.4
PATCH 1/3 scsi: Document enhanced error codes
Document the various error codes returned on I/O failure.
--- drivers/scsi/scsi_error.c | 7 +++++-- drivers/scsi/scsi_lib.c | 11 +++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-)
drivers/scsi/scsi_error.c +5 -2
@@ -229,8 +229,11 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost,* scsi_check_sense - Examine scsi cmd sense * @scmd: Cmd to have sense checked. * -* Return value: -* SUCCESS or FAILED or NEEDS_RETRY or TARGET_ERROR +* Possible return values: +* SUCCESS +* FAILED +* NEEDS_RETRY +* TARGET_ERROR * * Notes: * When a deferred error is detected the current command has
drivers/scsi/scsi_lib.c +11 -0
@@ -700,6 +700,17 @@ void scsi_release_buffers(struct scsi_cmnd *cmd) }EXPORT_SYMBOL (scsi_release_buffers); +/** +* __scsi_error_from_host_byte - translate SCSI error code into errno +* @cmd: SCSI command (unused) +* @result: scsi error code +* +* Translate SCSI error code into standard UNIX errno. +* Return values: +* -ENOLINK temporary transport failure +* -EREMOTEIO permanent target failure, do not retry +* -EBADE permanent nexus failure, retry on other path +*/ static int __scsi_error_from_host_byte (struct scsi_cmnd *cmd,int result) {int error =0 ;
Signature · 1 line
1.7.12.4
Re: [PATCH 1/3] scsi: Document enhanced error codes
Hi, Hannes:
I have two questions about the comments:
Quoted 13 lines · Hannes Reinecke
Document the various error codes returned on I/O failure.
Signed-off-by Hannes Reinecke<[email protected]>--- drivers/scsi/scsi_error.c | 7 +++++-- drivers/scsi/scsi_lib.c | 11 +++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-)drivers/scsi/scsi_error.c +0
-0
drivers/scsi/scsi_error.c static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost, · line 236
Quoted 10 lines
drivers/scsi/scsi_error.c +5
-2@@ -229,8 +229,11 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost,* scsi_check_sense - Examine scsi cmd sense * @scmd: Cmd to have sense checked. * -* Return value: -* SUCCESS or FAILED or NEEDS_RETRY or TARGET_ERROR +* Possible return values: +* SUCCESS +* FAILED +* NEEDS_RETRY +* TARGET_ERROR
This is more likely to be a historical non-update issue - there is another possible return value 'ADD_TO_MLQUEUE' which may be returned by the handler check_sense() or the case of this scsi_check_sense() below, right?
switch (sshdr.sense_key) {
case HARDWARE_ERROR:
if (scmd->device->retry_hwerror)
return ADD_TO_MLQUEUE;Quoted 12 lines
drivers/scsi/scsi_error.c +0
-0* * Notes: * When a deferred error is detected the current command has drivers/scsi/scsi_lib.c +0
-0@@ -700,6 +700,17 @@ void scsi_release_buffers(struct scsi_cmnd *cmd) }EXPORT_SYMBOL (scsi_release_buffers);
drivers/scsi/scsi_lib.c void scsi_release_buffers(struct scsi_cmnd *cmd) · line 712
Quoted 10 lines
drivers/scsi/scsi_lib.c +10
-0+/** +* __scsi_error_from_host_byte - translate SCSI error code into errno +* @cmd: SCSI command (unused) +* @result: scsi error code +* +* Translate SCSI error code into standard UNIX errno. +* Return values: +* -ENOLINK temporary transport failure +* -EREMOTEIO permanent target failure, do not retry +* -EBADE permanent nexus failure, retry on other path
Sorry, I'm afraid that I'm not clear why '-EIO' is not listed here...
Perhaps some of them are not necessary to document for some reasons?
Thanks,
Ren
Quoted 4 lines
drivers/scsi/scsi_lib.c +1
-0+*/ static int __scsi_error_from_host_byte (struct scsi_cmnd *cmd,int result) {int error =0 ;
Re: [PATCH 1/3] scsi: Document enhanced error codes
Quoted 35 lines · Ren Mingxin
Hi, Hannes:
I have two questions about the comments:
Quoted 14 lines · Hannes Reinecke
Document the various error codes returned on I/O failure.
Signed-off-by Hannes Reinecke<[email protected]>--- drivers/scsi/scsi_error.c | 7 +++++-- drivers/scsi/scsi_lib.c | 11 +++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-)drivers/scsi/scsi_error.c +0
-0@@ -229,8 +229,11 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost,drivers/scsi/scsi_error.c static inline void scsi_eh_prt_fail_stats(struct · line 237
Quoted 10 lines
drivers/scsi/scsi_error.c +5
-2* scsi_check_sense - Examine scsi cmd sense * @scmd: Cmd to have sense checked. * -* Return value: -* SUCCESS or FAILED or NEEDS_RETRY or TARGET_ERROR +* Possible return values: +* SUCCESS +* FAILED +* NEEDS_RETRY +* TARGET_ERROR This is more likely to be a historical non-update issue - there is another possible return value '
ADD_TO_MLQUEUE' which may be returned by the handlercheck_sense()or the case of thisscsi_check_sense()below, right?
Quoted 5 lines
switch (sshdr.sense_key) {
case HARDWARE_ERROR:
if (scmd->device->retry_hwerror)
return ADD_TO_MLQUEUE;Blast. You are correct. Will be fixing it up.
Quoted 25 lines
Quoted 12 lines
drivers/scsi/scsi_error.c +0
-0* * Notes: * When a deferred error is detected the current command has
drivers/scsi/scsi_lib.c +0
-0@@ -700,6 +700,17 @@ void scsi_release_buffers(struct scsi_cmnd *cmd) }EXPORT_SYMBOL (scsi_release_buffers);drivers/scsi/scsi_lib.c void scsi_release_buffers(struct scsi_cmnd *cmd) · line 712
Quoted 10 lines
drivers/scsi/scsi_lib.c +10
-0+/** +* __scsi_error_from_host_byte - translate SCSI error code into errno +* @cmd: SCSI command (unused) +* @result: scsi error code +* +* Translate SCSI error code into standard UNIX errno. +* Return values: +* -ENOLINK temporary transport failure +* -EREMOTEIO permanent target failure, do not retry +* -EBADE permanent nexus failure, retry on other path Sorry, I'm afraid that I'm not clear why '
-EIO' is not listed here...
Quoted 2 lines
Perhaps some of them are not necessary to document for some reasons?
Hmm. What with EIO being the default I've seen no need to document this. But yes, you are right, it should be documented.
Cheers,
Hannes
PATCH 2/3 scsi: Return ENOSPC on thin provisioning failure
In reply to Hannes ReineckeWhen the thin provisioning hard threshold is reached we should return ENOSPC to inform upper layers about this fact.
--- drivers/scsi/scsi_error.c | 12 +++++++++++- drivers/scsi/scsi_lib.c | 5 +++++ include/scsi/scsi.h | 2 ++ 3 files changed, 18 insertions(+), 1 deletion(-)
drivers/scsi/scsi_error.c +11 -1
@@ -234,6 +234,7 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost,* FAILED * NEEDS_RETRY * TARGET_ERROR +* ALLOC_ERROR * * Notes: * When a deferred error is detected the current command has
@@ -359,11 +360,15 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)return SUCCESS ;/* these are not supported */ +case DATA_PROTECT : +if (sshdr.asc ==0x27 && sshdr.ascq ==0x07 ) { +/* Thin provisioning hard threshold reached */ +return ALLOC_ERROR ; + }case COPY_ABORTED :case VOLUME_OVERFLOW :case MISCOMPARE :case BLANK_CHECK : -case DATA_PROTECT :return TARGET_ERROR ;case MEDIUM_ERROR :
@@ -849,6 +854,7 @@ retry:case NEEDS_RETRY :case FAILED :case TARGET_ERROR : +case ALLOC_ERROR :break ;case ADD_TO_MLQUEUE : rtn =NEEDS_RETRY ;
@@ -1588,6 +1594,10 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)*/ set_host_byte (scmd,DID_TARGET_FAILURE ); rtn =SUCCESS ; + }else if (rtn ==ALLOC_ERROR ) { +/* target hit out-of-space condition */ +set_host_byte (scmd,DID_ALLOC_FAILURE ); + rtn =SUCCESS ; }/* if rtn == FAILED, we have no sense information; * returning FAILED will wake the error handler thread
drivers/scsi/scsi_lib.c +5 -0
@@ -710,6 +710,7 @@ EXPORT_SYMBOL(scsi_release_buffers);* -ENOLINK temporary transport failure * -EREMOTEIO permanent target failure, do not retry * -EBADE permanent nexus failure, retry on other path +* -ENOSPC No write space available */ static int __scsi_error_from_host_byte (struct scsi_cmnd *cmd,int result) {
@@ -727,6 +728,10 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)set_host_byte (cmd,DID_OK ); error = -EBADE ;break ; +case DID_ALLOC_FAILURE : +set_host_byte (cmd,DID_OK ); + error = -ENOSPC ; +break ;default : error = -EIO ;break ;
include/scsi/scsi.h +2 -0
@@ -452,6 +452,7 @@ static inline int scsi_is_wlun(unsigned int lun)* other paths */ #define DID_NEXUS_FAILURE 0x11/* Permanent nexus failure, retry on other * paths might yield different results */ +#define DID_ALLOC_FAILURE 0x12/* Space allocation on the device failed */ #define DRIVER_OK 0x00/* Driver status */ /*
@@ -482,6 +483,7 @@ static inline int scsi_is_wlun(unsigned int lun)#define SCSI_RETURN_NOT_HANDLED 0x2008#define FAST_IO_FAIL 0x2009#define TARGET_ERROR 0x200A +#define ALLOC_ERROR 0x200B/* * Midlevel queue return values.
Signature · 1 line
1.7.12.4
PATCH 3/3 scsi: Return ENODATA on medium error
In reply to Hannes ReineckeWhen a medium error is detected the SCSI stack should return ENODATA to the upper layers.
--- drivers/scsi/scsi_error.c | 7 ++++++- drivers/scsi/scsi_lib.c | 5 +++++ include/scsi/scsi.h | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-)
drivers/scsi/scsi_error.c +6 -1
@@ -235,6 +235,7 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost,* NEEDS_RETRY * TARGET_ERROR * ALLOC_ERROR +* MEDIA_FAILURE * * Notes: * When a deferred error is detected the current command has
@@ -375,7 +376,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)if (sshdr.asc ==0x11 ||/* UNRECOVERED READ ERR */ sshdr.asc ==0x13 ||/* AMNF DATA FIELD */ sshdr.asc ==0x14 ) {/* RECORD NOT FOUND */ -return TARGET_ERROR ; +return MEDIA_FAILURE ; }return NEEDS_RETRY ;
@@ -1598,6 +1599,10 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)/* target hit out-of-space condition */ set_host_byte (scmd,DID_ALLOC_FAILURE ); rtn =SUCCESS ; + }else if (rtn ==MEDIA_FAILURE ) { +/* medium error */ +set_host_byte (scmd,DID_MEDIUM_ERROR ); + rtn =SUCCESS ; }/* if rtn == FAILED, we have no sense information; * returning FAILED will wake the error handler thread
drivers/scsi/scsi_lib.c +5 -0
@@ -711,6 +711,7 @@ EXPORT_SYMBOL(scsi_release_buffers);* -EREMOTEIO permanent target failure, do not retry * -EBADE permanent nexus failure, retry on other path * -ENOSPC No write space available +* -ENODATA Medium error */ static int __scsi_error_from_host_byte (struct scsi_cmnd *cmd,int result) {
@@ -732,6 +733,10 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)set_host_byte (cmd,DID_OK ); error = -ENOSPC ;break ; +case DID_MEDIUM_ERROR : +set_host_byte (cmd,DID_OK ); + error = -ENODATA ; +break ;default : error = -EIO ;break ;
include/scsi/scsi.h +2 -0
@@ -453,6 +453,7 @@ static inline int scsi_is_wlun(unsigned int lun)#define DID_NEXUS_FAILURE 0x11/* Permanent nexus failure, retry on other * paths might yield different results */ #define DID_ALLOC_FAILURE 0x12/* Space allocation on the device failed */ +#define DID_MEDIUM_ERROR 0x13/* Medium error */ #define DRIVER_OK 0x00/* Driver status */ /*
@@ -484,6 +485,7 @@ static inline int scsi_is_wlun(unsigned int lun)#define FAST_IO_FAIL 0x2009#define TARGET_ERROR 0x200A#define ALLOC_ERROR 0x200B +#define MEDIA_FAILURE 0x200C/* * Midlevel queue return values.
Signature · 1 line
1.7.12.4
Re: [PATCH 3/3] scsi: Return ENODATA on medium error
Hi, Hannes:
Quoted 55 lines · Hannes Reinecke
When a medium error is detected the SCSI stack should return ENODATA to the upper layers.
Signed-off-by Hannes Reinecke<[email protected]>--- drivers/scsi/scsi_error.c | 7 ++++++- drivers/scsi/scsi_lib.c | 5 +++++ include/scsi/scsi.h | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-)drivers/scsi/scsi_error.c +6
-1@@ -235,6 +235,7 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost,* NEEDS_RETRY * TARGET_ERROR * ALLOC_ERROR +* MEDIA_FAILURE * * Notes: * When a deferred error is detected the current command has @@ -375,7 +376,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)if (sshdr.asc ==0x11 ||/* UNRECOVERED READ ERR */ sshdr.asc ==0x13 ||/* AMNF DATA FIELD */ sshdr.asc ==0x14 ) {/* RECORD NOT FOUND */ -return TARGET_ERROR ; +return MEDIA_FAILURE ; }return NEEDS_RETRY ;@@ -1598,6 +1599,10 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)/* target hit out-of-space condition */ set_host_byte (scmd,DID_ALLOC_FAILURE ); rtn =SUCCESS ; + }else if (rtn ==MEDIA_FAILURE ) { +/* medium error */ +set_host_byte (scmd,DID_MEDIUM_ERROR ); + rtn =SUCCESS ; }/* if rtn == FAILED, we have no sense information; * returning FAILED will wake the error handler thread drivers/scsi/scsi_lib.c +1
-0@@ -711,6 +711,7 @@ EXPORT_SYMBOL(scsi_release_buffers);* -EREMOTEIO permanent target failure, do not retry * -EBADE permanent nexus failure, retry on other path * -ENOSPC No write space available +* -ENODATA Medium error */ static int __scsi_error_from_host_byte (struct scsi_cmnd *cmd,int result) {
drivers/scsi/scsi_lib.c static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result) · line 739
Quoted 7 lines
drivers/scsi/scsi_lib.c +4
-0@@ -732,6 +733,10 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)set_host_byte (cmd,DID_OK ); error = -ENOSPC ;break ; +case DID_MEDIUM_ERROR : +set_host_byte (cmd,DID_OK ); + error = -ENODATA ; +break ;
It seems that there is a debugging requirement to announce the meaning of these new added error codes in the function blk_update_request()like this:
block/blk-core.c +6 -0
@@ -2315,6 +2315,12 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)case -EBADE : error_type ="critical nexus" ;break ; +case -ENOSPC : + error_type ="critical space allocation" ; +break ; +case -ENODATA : + error_type ="critical medium" ; +break ;case -EIO :default : error_type ="I/O" ;
# To tell the truth, I'm not understand why this patchset is needed
# in practice for I've only just got limited info about LSF. I guess # this is one of the improvements for SCSI EH. Could you give an # example/condition the upper layers interest in?
Thanks,
Ren
Quoted 23 lines
drivers/scsi/scsi_lib.c +0
-0default : error = -EIO ;break ;include/scsi/scsi.h +2
-0@@ -453,6 +453,7 @@ static inline int scsi_is_wlun(unsigned int lun)#define DID_NEXUS_FAILURE 0x11/* Permanent nexus failure, retry on other * paths might yield different results */ #define DID_ALLOC_FAILURE 0x12/* Space allocation on the device failed */ +#define DID_MEDIUM_ERROR 0x13/* Medium error */ #define DRIVER_OK 0x00/* Driver status */ /* @@ -484,6 +485,7 @@ static inline int scsi_is_wlun(unsigned int lun)#define FAST_IO_FAIL 0x2009#define TARGET_ERROR 0x200A#define ALLOC_ERROR 0x200B +#define MEDIA_FAILURE 0x200C/* * Midlevel queue return values.
Re: [PATCH 3/3] scsi: Return ENODATA on medium error
Quoted 92 lines · Ren Mingxin
Hi, Hannes:
Quoted 59 lines · Hannes Reinecke
When a medium error is detected the SCSI stack should return ENODATA to the upper layers.
Signed-off-by Hannes Reinecke<[email protected]>--- drivers/scsi/scsi_error.c | 7 ++++++- drivers/scsi/scsi_lib.c | 5 +++++ include/scsi/scsi.h | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-)drivers/scsi/scsi_error.c +1
-0@@ -235,6 +235,7 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost, * NEEDS_RETRY *TARGET_ERROR *ALLOC_ERROR + *MEDIA_FAILURE * * Notes:* When a deferred error is detected the current command has
drivers/scsi/scsi_error.c +5
-1@@ -375,7 +376,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)if (sshdr.asc ==0x11 ||/* UNRECOVERED READ ERR */ sshdr.asc ==0x13 ||/* AMNF DATA FIELD */ sshdr.asc ==0x14 ) {/* RECORD NOT FOUND */ -return TARGET_ERROR ; +return MEDIA_FAILURE ; }return NEEDS_RETRY ;@@ -1598,6 +1599,10 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)/* target hit out-of-space condition */ set_host_byte (scmd ,DID_ALLOC_FAILURE ); rtn =SUCCESS ; + }else if (rtn ==MEDIA_FAILURE ) { +/* medium error */ +set_host_byte (scmd,DID_MEDIUM_ERROR ); + rtn =SUCCESS ; }/* if rtn == FAILED, we have no sense information; * returning FAILED will wake the error handler thread
drivers/scsi/scsi_lib.c +1
-0@@ -711,6 +711,7 @@ EXPORT_SYMBOL(scsi_release_buffers);* -EREMOTEIO permanent target failure, do not retry * -EBADE permanent nexus failure, retry on other path * -ENOSPC No write space available +* -ENODATA Medium error */ static int __scsi_error_from_host_byte (struct scsi_cmnd *cmd,int result){drivers/scsi/scsi_lib.c static int __scsi_error_from_host_byte(struct · line 740
Quoted 8 lines
drivers/scsi/scsi_lib.c +4
-0@@ -732,6 +733,10 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)set_host_byte (cmd ,DID_OK ); error = -ENOSPC ;break ; +case DID_MEDIUM_ERROR : +set_host_byte (cmd,DID_OK ); + error = -ENODATA ; +break ;It seems that there is a debugging requirement to announce the meaning of these new added error codes in the function blk_update_request()like this:
block/blk-core.c +6
-0@@ -2315,6 +2315,12 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)case -EBADE : error_type ="critical nexus" ;break ; +case -ENOSPC : + error_type ="critical space allocation" ; +break ; +case -ENODATA : + error_type ="critical medium" ; +break ;case -EIO :default :
Quoted 2 lines
error_type = "I/O";
And indeed, that's true. I'll be updating the patches.
Quoted 5 lines
# To tell the truth, I'm not understand why this patchset is needed
# in practice for I've only just got limited info about LSF. I guess # this is one of the improvements for SCSI EH. Could you give an # example/condition the upper layers interest in?
No, this is actually related, but independent of the SCSI EH rework. Filesystem folks expressed their interest in these kind of errors. 'ENODATA' is especially of interest, as this mean you will _never_ get the data back. Any other type of error has at least a theoretical chance to recover the data.
And ENOSPC needs to be differentiated, too, as this is some sort of 'temporary write error'. So when the fs is able to free-up some space this error might actually be fixed, so it's worth inform the filesystem about it.
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html