[SCSI] sd: Fix handling of NO_SENSE check condition
The current handling of NO_SENSE check condition is the same as RECOVERED_ERROR, and assumes that in both cases, the I/O was fully transferred. We have seen cases of arrays returning with NO_SENSE (no error), but the I/O was not completely transferred, thus residual set. Thus, rather than return good_bytes as the entire transfer, set good_bytes to 0, so that the midlayer then applies the residual in calculating the transfer, and for sd, will fail the I/O and fall into a retry path. Signed-off-by: Jamie Wellnitz <Jamie.Wellnitz@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
6c5121b78b
commit
10dab22664
|
@ -1054,7 +1054,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
|
|||
good_bytes = sd_completed_bytes(SCpnt);
|
||||
break;
|
||||
case RECOVERED_ERROR:
|
||||
case NO_SENSE:
|
||||
/* Inform the user, but make sure that it's not treated
|
||||
* as a hard error.
|
||||
*/
|
||||
|
@ -1063,6 +1062,15 @@ static int sd_done(struct scsi_cmnd *SCpnt)
|
|||
memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
|
||||
good_bytes = scsi_bufflen(SCpnt);
|
||||
break;
|
||||
case NO_SENSE:
|
||||
/* This indicates a false check condition, so ignore it. An
|
||||
* unknown amount of data was transferred so treat it as an
|
||||
* error.
|
||||
*/
|
||||
scsi_print_sense("sd", SCpnt);
|
||||
SCpnt->result = 0;
|
||||
memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
|
||||
break;
|
||||
case ABORTED_COMMAND:
|
||||
if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */
|
||||
scsi_print_result(SCpnt);
|
||||
|
|
Loading…
Reference in New Issue