diff options
author | Martin K. Petersen <martin.petersen@oracle.com> | 2009-01-04 03:04:31 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-01-05 10:02:28 -0500 |
commit | 3e695f89c5debb735e4ff051e9e58d8fb4e95110 (patch) | |
tree | febd0af71641b72a1c27115bc1b93c0e44cd11ea /drivers/scsi/scsi_lib.c | |
parent | 4f5299ac4e3a03d5c596c00d726fa932c600609d (diff) |
[SCSI] Fix error handling for DIF/DIX
patch
commit b60af5b0adf0da24c673598c8d3fb4d4189a15ce
Author: Alan Stern <stern@rowland.harvard.edu>
Date: Mon Nov 3 15:56:47 2008 -0500
[SCSI] simplify scsi_io_completion()
broke DIX error handling. Also, we are now using EILSEQ to indicate
integrity errors to the upper layers (as opposed to regular EIO
failures). This allows filesystems to inspect buffers and decide
whether to retry the I/O. Update scsi_io_completion() accordingly.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 911514c1fea7..cc613bae4ad3 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -980,6 +980,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
980 | return; | 980 | return; |
981 | this_count = blk_rq_bytes(req); | 981 | this_count = blk_rq_bytes(req); |
982 | 982 | ||
983 | error = -EIO; | ||
984 | |||
983 | if (host_byte(result) == DID_RESET) { | 985 | if (host_byte(result) == DID_RESET) { |
984 | /* Third party bus reset or reset for error recovery | 986 | /* Third party bus reset or reset for error recovery |
985 | * reasons. Just retry the command and see what | 987 | * reasons. Just retry the command and see what |
@@ -1021,13 +1023,18 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
1021 | /* This will issue a new 6-byte command. */ | 1023 | /* This will issue a new 6-byte command. */ |
1022 | cmd->device->use_10_for_rw = 0; | 1024 | cmd->device->use_10_for_rw = 0; |
1023 | action = ACTION_REPREP; | 1025 | action = ACTION_REPREP; |
1026 | } else if (sshdr.asc == 0x10) /* DIX */ { | ||
1027 | description = "Host Data Integrity Failure"; | ||
1028 | action = ACTION_FAIL; | ||
1029 | error = -EILSEQ; | ||
1024 | } else | 1030 | } else |
1025 | action = ACTION_FAIL; | 1031 | action = ACTION_FAIL; |
1026 | break; | 1032 | break; |
1027 | case ABORTED_COMMAND: | 1033 | case ABORTED_COMMAND: |
1028 | if (sshdr.asc == 0x10) { /* DIF */ | 1034 | if (sshdr.asc == 0x10) { /* DIF */ |
1035 | description = "Target Data Integrity Failure"; | ||
1029 | action = ACTION_FAIL; | 1036 | action = ACTION_FAIL; |
1030 | description = "Data Integrity Failure"; | 1037 | error = -EILSEQ; |
1031 | } else | 1038 | } else |
1032 | action = ACTION_RETRY; | 1039 | action = ACTION_RETRY; |
1033 | break; | 1040 | break; |