aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@suse.de>2010-05-04 16:51:40 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-12 18:03:16 -0400
commit79d1e78997cd0030d4b449f4b8df46f933c480d7 (patch)
treec5f4d4dbf23723ddadf8e7b9b2431309713150b6
parent7c18009f1822fd261cb7549560b44e1ebad51a11 (diff)
SCSI: Retry commands with UNIT_ATTENTION sense codes to fix ext3/ext4 I/O error
commit 77a4229719e511a0d38d9c355317ae1469adeb54 upstream. 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> Signed-off-by: James Bottomley <James.Bottomley@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@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 08ed506e6059..e46155b006dc 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -301,7 +301,20 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
301 if (scmd->device->allow_restart && 301 if (scmd->device->allow_restart &&
302 (sshdr.asc == 0x04) && (sshdr.ascq == 0x02)) 302 (sshdr.asc == 0x04) && (sshdr.ascq == 0x02))
303 return FAILED; 303 return FAILED;
304 return SUCCESS; 304
305 if (blk_barrier_rq(scmd->request))
306 /*
307 * barrier requests should always retry on UA
308 * otherwise block will get a spurious error
309 */
310 return NEEDS_RETRY;
311 else
312 /*
313 * for normal (non barrier) commands, pass the
314 * UA upwards for a determination in the
315 * completion functions
316 */
317 return SUCCESS;
305 318
306 /* these three are not supported */ 319 /* these three are not supported */
307 case COPY_ABORTED: 320 case COPY_ABORTED: