| From 10dab22664914505dcb804d9ad09cad6bc94d349 Mon Sep 17 00:00:00 2001 |
| From: Jamie Wellnitz <Jamie.Wellnitz@emulex.com> |
| Date: Thu, 11 Sep 2008 21:39:36 -0400 |
| Subject: SCSI: sd: Fix handling of NO_SENSE check condition |
| |
| From: Jamie Wellnitz <Jamie.Wellnitz@emulex.com> |
| |
| commit 10dab22664914505dcb804d9ad09cad6bc94d349 upstream |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/scsi/sd.c | 10 +++++++++- |
| 1 file changed, 9 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/scsi/sd.c |
| +++ b/drivers/scsi/sd.c |
| @@ -1047,7 +1047,6 @@ static int sd_done(struct scsi_cmnd *SCp |
| 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. |
| */ |
| @@ -1056,6 +1055,15 @@ static int sd_done(struct scsi_cmnd *SCp |
| 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); |