fix recovered error handling
James Bottomley
maintainerPATCH 1/1 fix recovered error handling
We have a problem with recovered error handling in that any command which goes down as BLOCK_PC but which returns a sense code of RECOVERED ERROR gets completed with -EIO. For actual SG_IO commands, this doesn't matter at all, since the error return code gets dropped in favour of req->errors which contain the SCSI completion code.
However, if this command is part of the block system, then it will pay attention to the returned error code. In particularly if a SYNCHRONIZE CACHE from a barrier command completes with RECOVERED ERROR, the resulting -EIO on the barrier causes block to error the request and return it to the filesystem. Fix this by converting the -EIO for recovered error to zero, plus remove the printing of this from sd and sr so the message isn't double printed.
James
---
drivers/scsi/scsi_lib.c +14 -0
@@ -791,6 +791,20 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)"%d bytes done.\n" , req->nr_sectors, good_bytes)); +/* +* Recovered errors need reporting, but they're always treated +* as success, so fiddle the result code here. For BLOCK_PC +* we already took a copy of the original into rq->errors which +* is what gets returned to the user +*/ +if (sense_valid && sshdr.sense_key ==RECOVERED_ERROR ) { +if (!(req->cmd_flags &REQ_QUIET )) +scsi_print_sense ("" , cmd); + result =0 ; +/* BLOCK_PC may have set error */ + error =0 ; + } +/* A number of bytes were successfully read. If there * are leftovers and there is some kind of error * (result != 0), retry the rest.
drivers/scsi/sd.c +0 -6
@@ -1051,12 +1051,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) good_bytes =sd_completed_bytes (SCpnt);break ;case RECOVERED_ERROR : -/* Inform the user, but make sure that it's not treated -* as a hard error. -*/ -scsi_print_sense ("sd" , SCpnt); - SCpnt->result =0 ; -memset (SCpnt->sense_buffer,0 ,SCSI_SENSE_BUFFERSIZE ); good_bytes =scsi_bufflen (SCpnt);break ;case NO_SENSE :
drivers/scsi/sr.c +0 -9
@@ -309,15 +309,6 @@ static int sr_done(struct scsi_cmnd *SCpnt)break ;case RECOVERED_ERROR : - -/* -* An error occured, but it recovered. Inform the -* user, but make sure that it's not treated as a -* hard error. -*/ -scsi_print_sense ("sr" , SCpnt); - SCpnt->result =0 ; - SCpnt->sense_buffer[0 ] =0x0 ; good_bytes = this_count;break ;