From 3bc78202700194a93605b7a7c5d387b303932f49 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Wed, 2 May 2012 15:22:52 -0400 Subject: [PATCH] --- yaml --- r: 305870 b: refs/heads/master c: 8d899e70c1b3afff04104eebc09a629ac8dd4b32 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/ata/libata-eh.c | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 99d53f628cd2..d2fbd324f1bc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cd006086fa5d91414d8ff9ff2b78fbb593878e3c +refs/heads/master: 8d899e70c1b3afff04104eebc09a629ac8dd4b32 diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index d1fbd59ead16..6d53cf9b3b6e 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -2046,6 +2046,26 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, return action; } +/** + * ata_eh_worth_retry - analyze error and decide whether to retry + * @qc: qc to possibly retry + * + * Look at the cause of the error and decide if a retry + * might be useful or not. We don't want to retry media errors + * because the drive itself has probably already taken 10-30 seconds + * doing its own internal retries before reporting the failure. + */ +static inline int ata_eh_worth_retry(struct ata_queued_cmd *qc) +{ + if (qc->flags & AC_ERR_MEDIA) + return 0; /* don't retry media errors */ + if (qc->flags & ATA_QCFLAG_IO) + return 1; /* otherwise retry anything from fs stack */ + if (qc->err_mask & AC_ERR_INVALID) + return 0; /* don't retry these */ + return qc->err_mask != AC_ERR_DEV; /* retry if not dev error */ +} + /** * ata_eh_link_autopsy - analyze error and determine recovery action * @link: host link to perform autopsy on @@ -2120,9 +2140,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); /* determine whether the command is worth retrying */ - if (qc->flags & ATA_QCFLAG_IO || - (!(qc->err_mask & AC_ERR_INVALID) && - qc->err_mask != AC_ERR_DEV)) + if (ata_eh_worth_retry(qc)) qc->flags |= ATA_QCFLAG_RETRY; /* accumulate error info */