aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@suse.de>2010-05-04 16:51:40 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-05-05 12:15:57 -0400
commit77a4229719e511a0d38d9c355317ae1469adeb54 (patch)
tree6547272402fca49cde94fd5cb7842eea08b45dd7
parentc213e1407be6b04b144794399a91472e0ef92aec (diff)
[SCSI] Retry commands with UNIT_ATTENTION sense codes to fix ext3/ext4 I/O error
There's nastyness in the way we currently handle barriers (and discards): They're effectively filesystem commands, but they get processed as BLOCK_PC commands. Unfortunately BLOCK_PC commands are taken by SCSI to be SG_IO commands and the issuer expects to see and handle any returned errors, however trivial. This leads to a huge problem, because the block layer doesn't expect this to happen and any trivially retryable error on a barrier causes an immediate I/O error to the filesystem. The only real way to hack around this is to take the usual class of offending errors (unit attentions) and make them all retryable in the case of a REQ_HARDBARRIER. A correct fix would involve a rework of the entire block and SCSI submit system, and so is out of scope for a quick fix. Cc: Hannes Reinecke <hare@suse.de> Cc: Stable Tree <stable@kernel.org> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/scsi_error.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index d45c69ca5737..7ad53fa42766 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -302,7 +302,20 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
302 if (scmd->device->allow_restart && 302 if (scmd->device->allow_restart &&
303 (sshdr.asc == 0x04) && (sshdr.ascq == 0x02)) 303 (sshdr.asc == 0x04) && (sshdr.ascq == 0x02))
304 return FAILED; 304 return FAILED;
305 return SUCCESS; 305
306 if (blk_barrier_rq(scmd->request))
307 /*
308 * barrier requests should always retry on UA
309 * otherwise block will get a spurious error
310 */
311 return NEEDS_RETRY;
312 else
313 /*
314 * for normal (non barrier) commands, pass the
315 * UA upwards for a determination in the
316 * completion functions
317 */
318 return SUCCESS;
306 319
307 /* these three are not supported */ 320 /* these three are not supported */
308 case COPY_ABORTED: 321 case COPY_ABORTED: