diff options
author | Jamie Wellnitz <Jamie.Wellnitz@emulex.com> | 2008-09-11 21:39:36 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-10-23 12:42:17 -0400 |
commit | 10dab22664914505dcb804d9ad09cad6bc94d349 (patch) | |
tree | 11c7737944fbe10147d4ef335ba91bd5d7b8f937 /drivers/scsi | |
parent | 6c5121b78ba5c70a9990e2af6cb4d6bbffe0d4d8 (diff) |
[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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/sd.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 7c4d2e68df1c..55e6ed4b886d 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1054,7 +1054,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1054 | good_bytes = sd_completed_bytes(SCpnt); | 1054 | good_bytes = sd_completed_bytes(SCpnt); |
1055 | break; | 1055 | break; |
1056 | case RECOVERED_ERROR: | 1056 | case RECOVERED_ERROR: |
1057 | case NO_SENSE: | ||
1058 | /* Inform the user, but make sure that it's not treated | 1057 | /* Inform the user, but make sure that it's not treated |
1059 | * as a hard error. | 1058 | * as a hard error. |
1060 | */ | 1059 | */ |
@@ -1063,6 +1062,15 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1063 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | 1062 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); |
1064 | good_bytes = scsi_bufflen(SCpnt); | 1063 | good_bytes = scsi_bufflen(SCpnt); |
1065 | break; | 1064 | break; |
1065 | case NO_SENSE: | ||
1066 | /* This indicates a false check condition, so ignore it. An | ||
1067 | * unknown amount of data was transferred so treat it as an | ||
1068 | * error. | ||
1069 | */ | ||
1070 | scsi_print_sense("sd", SCpnt); | ||
1071 | SCpnt->result = 0; | ||
1072 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | ||
1073 | break; | ||
1066 | case ABORTED_COMMAND: | 1074 | case ABORTED_COMMAND: |
1067 | if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */ | 1075 | if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */ |
1068 | scsi_print_result(SCpnt); | 1076 | scsi_print_result(SCpnt); |