aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-eh.c
diff options
context:
space:
mode:
authorMark Lord <kernel@teksavvy.com>2012-05-02 15:22:52 -0400
committerJeff Garzik <jgarzik@redhat.com>2012-05-07 15:40:34 -0400
commit8d899e70c1b3afff04104eebc09a629ac8dd4b32 (patch)
tree65091f65021d685a64a7ed846811dbd0f0301668 /drivers/ata/libata-eh.c
parentcd006086fa5d91414d8ff9ff2b78fbb593878e3c (diff)
libata-eh don't waste time retrying media errors (v3)
ATA and SATA drives have had built-in retries for media errors for as long as they've been commonplace in computers (early 1990s). When libata stumbles across a bad sector, it can waste minutes sitting there doing retry after retry before finally giving up and letting the higher layers deal with it. This patch removes retries for media errors only. Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r--drivers/ata/libata-eh.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index d1fbd59ead16..6d53cf9b3b6e 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2047,6 +2047,26 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,
2047} 2047}
2048 2048
2049/** 2049/**
2050 * ata_eh_worth_retry - analyze error and decide whether to retry
2051 * @qc: qc to possibly retry
2052 *
2053 * Look at the cause of the error and decide if a retry
2054 * might be useful or not. We don't want to retry media errors
2055 * because the drive itself has probably already taken 10-30 seconds
2056 * doing its own internal retries before reporting the failure.
2057 */
2058static inline int ata_eh_worth_retry(struct ata_queued_cmd *qc)
2059{
2060 if (qc->flags & AC_ERR_MEDIA)
2061 return 0; /* don't retry media errors */
2062 if (qc->flags & ATA_QCFLAG_IO)
2063 return 1; /* otherwise retry anything from fs stack */
2064 if (qc->err_mask & AC_ERR_INVALID)
2065 return 0; /* don't retry these */
2066 return qc->err_mask != AC_ERR_DEV; /* retry if not dev error */
2067}
2068
2069/**
2050 * ata_eh_link_autopsy - analyze error and determine recovery action 2070 * ata_eh_link_autopsy - analyze error and determine recovery action
2051 * @link: host link to perform autopsy on 2071 * @link: host link to perform autopsy on
2052 * 2072 *
@@ -2120,9 +2140,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)
2120 qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); 2140 qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
2121 2141
2122 /* determine whether the command is worth retrying */ 2142 /* determine whether the command is worth retrying */
2123 if (qc->flags & ATA_QCFLAG_IO || 2143 if (ata_eh_worth_retry(qc))
2124 (!(qc->err_mask & AC_ERR_INVALID) &&
2125 qc->err_mask != AC_ERR_DEV))
2126 qc->flags |= ATA_QCFLAG_RETRY; 2144 qc->flags |= ATA_QCFLAG_RETRY;
2127 2145
2128 /* accumulate error info */ 2146 /* accumulate error info */