Codebase list libatasmart / debian/0.17+git20100219-3 debian / patches / 0002-Drop-our-own-many-bad-sectors-heuristic.patch
debian/0.17+git20100219-3

Tree @debian/0.17+git20100219-3 (Download .tar.gz)

0002-Drop-our-own-many-bad-sectors-heuristic.patch @debian/0.17+git20100219-3raw · history · blame

From 6846b7c2431dbeaddd9f931c609b522c04e55732 Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin.pitt@ubuntu.com>
Date: Fri, 19 Mar 2010 14:56:06 +0100
Subject: [PATCH 2/2] Drop our own "many bad sectors" heuristic

This currently causes a lot of false positives, because in many cases our
threshold is either overly pessimistically low, or the raw value is implausibly
high. Just use the normalized values vs. threshold for now.

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=25772
Bug-Ubuntu: https://launchpad.net/bugs/438136
---
 atasmart.c |   33 +++++++++++----------------------
 1 files changed, 11 insertions(+), 22 deletions(-)

diff --git a/atasmart.c b/atasmart.c
index 13d55ff..beb57b2 100644
--- a/atasmart.c
+++ b/atasmart.c
@@ -130,6 +130,8 @@ struct SkDisk {
         SkBool current_pending_sector_found:1;
         uint64_t reallocated_sector_count;
         uint64_t current_pending_sector;
+        SkBool reallocated_sector_count_bad:1;
+        SkBool current_pending_sector_bad:1;
 
         void *blob;
 };
@@ -2037,16 +2039,23 @@ static void fill_cache_cb(SkDisk *d, const SkSmartAttributeParsedData *a, void*
         if (a->pretty_unit != SK_SMART_ATTRIBUTE_UNIT_SECTORS)
                 return;
 
+        if (!a->current_value_valid)
+                return;
+
         if (!strcmp(a->name, "reallocated-sector-count")) {
                 if (a->pretty_value > d->reallocated_sector_count)
                         d->reallocated_sector_count = a->pretty_value;
                 d->reallocated_sector_count_found = TRUE;
+                if (a->good_now_valid && !a->good_now)
+                        d->reallocated_sector_count_bad = TRUE;
         }
 
         if (!strcmp(a->name, "current-pending-sector")) {
                 if (a->pretty_value > d->current_pending_sector)
                         d->current_pending_sector = a->pretty_value;
                 d->current_pending_sector_found = TRUE;
+                if (a->good_now_valid && !a->good_now)
+                        d->current_pending_sector_bad = TRUE;
         }
 }
 
@@ -2102,24 +2111,9 @@ const char* sk_smart_overall_to_string(SkSmartOverall overall) {
         return _P(map[overall]);
 }
 
-static uint64_t u64log2(uint64_t n) {
-        unsigned r;
-
-        if (n <= 1)
-                return 0;
-
-        r = 0;
-        for (;;) {
-                n = n >> 1;
-                if (!n)
-                        return r;
-                r++;
-        }
-}
-
 int sk_disk_smart_get_overall(SkDisk *d, SkSmartOverall *overall) {
         SkBool good;
-        uint64_t sectors, sector_threshold;
+        uint64_t sectors;
 
         assert(d);
         assert(overall);
@@ -2140,12 +2134,7 @@ int sk_disk_smart_get_overall(SkDisk *d, SkSmartOverall *overall) {
                         return -1;
                 sectors = 0;
         } else {
-
-                /* We use log2(n_sectors) as a threshold here. We had to pick
-                 * something, and this makes a bit of sense, or doesn't it? */
-                sector_threshold = u64log2(d->size/512);
-
-                if (sectors >= sector_threshold) {
+                if (d->reallocated_sector_count_bad || d->current_pending_sector_bad) {
                         *overall = SK_SMART_OVERALL_BAD_SECTOR_MANY;
                         return 0;
                 }
-- 
1.7.0