diff -u libatasmart-0.16/debian/changelog libatasmart-0.16/debian/changelog --- libatasmart-0.16/debian/changelog +++ libatasmart-0.16/debian/changelog @@ -1,3 +1,14 @@ +libatasmart (0.16-1ubuntu0.1) karmic-proposed; urgency=low + + * debian/rules: Enable simple-patchsys. + * Add 01_use_manufacturer_bad_blocks.patch: Drop our own "many bad sectors" + heuristic. This currently causes a lot of false positives, because in many + cases our treshold is either overly pessimistically low, or the raw value + is implausibly high. Just use the normalized values vs. treshold for now. + (LP: #438136) + + -- Martin Pitt Fri, 23 Apr 2010 15:05:48 +0200 + libatasmart (0.16-1) unstable; urgency=low * New upstream release. diff -u libatasmart-0.16/debian/rules libatasmart-0.16/debian/rules --- libatasmart-0.16/debian/rules +++ libatasmart-0.16/debian/rules @@ -3,6 +3,7 @@ include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/autotools.mk include /usr/share/cdbs/1/rules/utils.mk +include /usr/share/cdbs/1/rules/simple-patchsys.mk LDFLAGS += -Wl,--as-needed only in patch2: unchanged: --- libatasmart-0.16.orig/debian/patches/01_use_manufacturer_bad_blocks.patch +++ libatasmart-0.16/debian/patches/01_use_manufacturer_bad_blocks.patch @@ -0,0 +1,131 @@ +Author: Martin Pitt +Description: Drop our own "many bad sectors" heuristic + +This currently causes a lot of false positives, because in many cases our +treshold is either overly pessimistically low, or the raw value is implausibly +high. Just use the normalized values vs. treshold for now. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=25772 +Bug-Ubuntu: https://launchpad.net/bugs/438136 + +--- old/atasmart.c 2010-04-23 15:25:40.276637801 +0200 ++++ new/atasmart.c 2010-04-23 16:07:53.776614686 +0200 +@@ -2012,6 +2012,28 @@ + } + } + ++static void reallocated_bad_cb(SkDisk *d, const SkSmartAttributeParsedData *a, SkBool *bad) { ++ ++ if (a->pretty_unit != SK_SMART_ATTRIBUTE_UNIT_SECTORS) ++ return; ++ ++ if (!strcmp(a->name, "reallocated-sector-count")) { ++ if (a->good_now_valid && !a->good_now) ++ *bad = TRUE; ++ } ++} ++ ++static void pending_bad_cb(SkDisk *d, const SkSmartAttributeParsedData *a, SkBool *bad) { ++ ++ if (a->pretty_unit != SK_SMART_ATTRIBUTE_UNIT_SECTORS) ++ return; ++ ++ if (!strcmp(a->name, "current-pending-sector")) { ++ if (a->good_now_valid && !a->good_now) ++ *bad = TRUE; ++ } ++} ++ + int sk_disk_smart_get_bad(SkDisk *d, uint64_t *sectors) { + struct attr_helper ah1, ah2; + uint64_t sectors1, sectors2; +@@ -2046,6 +2068,22 @@ + return 0; + } + ++static int sk_disk_smart_check_many_bad(SkDisk *d, SkBool *good) { ++ SkBool reallocated_sector_count_bad = FALSE, current_pending_sector_bad = FALSE; ++ assert(d); ++ assert(good); ++ ++ if (sk_disk_smart_parse_attributes(d, (SkSmartAttributeParseCallback) reallocated_bad_cb, &reallocated_sector_count_bad) < 0) ++ return -1; ++ ++ if (sk_disk_smart_parse_attributes(d, (SkSmartAttributeParseCallback) pending_bad_cb, ¤t_pending_sector_bad) < 0) ++ return -1; ++ ++ *good = !reallocated_sector_count_bad && !current_pending_sector_bad; ++ ++ return 0; ++} ++ + const char* sk_smart_overall_to_string(SkSmartOverall overall) { + + /* %STRINGPOOLSTART% */ +@@ -2075,24 +2113,9 @@ + *good = FALSE; + } + +-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); +@@ -2107,21 +2130,13 @@ + } + + /* Second, check if the number of bad sectors is greater than +- * a certain threshold */ +- if (sk_disk_smart_get_bad(d, §ors) < 0) { +- if (errno != ENOENT) +- 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) { +- *overall = SK_SMART_OVERALL_BAD_SECTOR_MANY; +- return 0; +- } ++ * the manufacturer threshold */ ++ good = TRUE; ++ if (sk_disk_smart_check_many_bad(d, &good) < 0) ++ return -1; ++ if (!good) { ++ *overall = SK_SMART_OVERALL_BAD_SECTOR_MANY; ++ return 0; + } + + /* Third, check if any of the SMART attributes is bad */ +@@ -2135,6 +2150,11 @@ + } + + /* Fourth, check if there are any bad sectors at all */ ++ if (sk_disk_smart_get_bad(d, §ors) < 0) { ++ if (errno != ENOENT) ++ return -1; ++ sectors = 0; ++ } + if (sectors > 0) { + *overall = SK_SMART_OVERALL_BAD_SECTOR; + return 0;