Codebase list libatasmart / 351d8fa
Add 0001-Speed-up-get_overall-and-get_bad.patch: Speed up get_overall() and get_bad(). (fd.o #26834) Martin Pitt 14 years ago
3 changed file(s) with 182 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
00 libatasmart (0.17+git20100219-2) UNRELEASED; urgency=low
11
22 * debian/local/apport-hook.py: Update for udisks.
3 * Add 0001-Speed-up-get_overall-and-get_bad.patch: Speed up get_overall()
4 and get_bad(). (fd.o #26834)
35
46 -- Martin Pitt <mpitt@debian.org> Tue, 16 Mar 2010 17:11:55 +0100
57
0 From 2b24de1dc2314c28bce6e89050f16aa0dcac8031 Mon Sep 17 00:00:00 2001
1 From: Martin Pitt <martin.pitt@ubuntu.com>
2 Date: Tue, 2 Mar 2010 09:58:59 +0100
3 Subject: [PATCH 1/2] Speed up get_overall() and get_bad()
4
5 Instead of iterating through all attributes four times for an
6 sk_disk_smart_get_overall() call, just do it once and store the results in
7 SkDisk. This considerably speeds up libatasmart for common operations like
8 smart_get_overall() and smart_get_bad().
9
10 https://bugs.freedesktop.org/show_bug.cgi?id=26834
11 ---
12 atasmart.c | 97 +++++++++++++++++++++++++++--------------------------------
13 1 files changed, 44 insertions(+), 53 deletions(-)
14
15 diff --git a/atasmart.c b/atasmart.c
16 index a4b60c0..13d55ff 100644
17 --- a/atasmart.c
18 +++ b/atasmart.c
19 @@ -122,6 +122,15 @@ struct SkDisk {
20 SkIdentifyParsedData identify_parsed_data;
21 SkSmartParsedData smart_parsed_data;
22
23 + /* cache for commonly used attributes */
24 + SkBool attribute_cache_valid:1;
25 + SkBool bad_attribute_now:1;
26 + SkBool bad_attribute_in_the_past:1;
27 + SkBool reallocated_sector_count_found:1;
28 + SkBool current_pending_sector_found:1;
29 + uint64_t reallocated_sector_count;
30 + uint64_t current_pending_sector;
31 +
32 void *blob;
33 };
34
35 @@ -2015,64 +2024,61 @@ int sk_disk_smart_get_power_cycle(SkDisk *d, uint64_t *count) {
36 return 0;
37 }
38
39 -static void reallocated_cb(SkDisk *d, const SkSmartAttributeParsedData *a, struct attr_helper *ah) {
40 -
41 - if (a->pretty_unit != SK_SMART_ATTRIBUTE_UNIT_SECTORS)
42 - return;
43 -
44 - if (!strcmp(a->name, "reallocated-sector-count")) {
45 +static void fill_cache_cb(SkDisk *d, const SkSmartAttributeParsedData *a, void* userdata) {
46
47 - if (!ah->found || a->pretty_value > *ah->value)
48 - *ah->value = a->pretty_value;
49 + if (a->prefailure) {
50 + if (a->good_now_valid && !a->good_now)
51 + d->bad_attribute_now = TRUE;
52
53 - ah->found = TRUE;
54 + if (a->good_in_the_past_valid && !a->good_in_the_past)
55 + d->bad_attribute_in_the_past = TRUE;
56 }
57 -}
58 -
59 -static void pending_cb(SkDisk *d, const SkSmartAttributeParsedData *a, struct attr_helper *ah) {
60
61 if (a->pretty_unit != SK_SMART_ATTRIBUTE_UNIT_SECTORS)
62 return;
63
64 + if (!strcmp(a->name, "reallocated-sector-count")) {
65 + if (a->pretty_value > d->reallocated_sector_count)
66 + d->reallocated_sector_count = a->pretty_value;
67 + d->reallocated_sector_count_found = TRUE;
68 + }
69 +
70 if (!strcmp(a->name, "current-pending-sector")) {
71 + if (a->pretty_value > d->current_pending_sector)
72 + d->current_pending_sector = a->pretty_value;
73 + d->current_pending_sector_found = TRUE;
74 + }
75 +}
76
77 - if (!ah->found || a->pretty_value > *ah->value)
78 - *ah->value = a->pretty_value;
79 +static int fill_cache(SkDisk *d) {
80 + if (d->attribute_cache_valid)
81 + return 0;
82
83 - ah->found = TRUE;
84 - }
85 + if (sk_disk_smart_parse_attributes(d, (SkSmartAttributeParseCallback) fill_cache_cb, NULL) >= 0) {
86 + d->attribute_cache_valid = TRUE;
87 + return 0;
88 + } else
89 + return -1;
90 }
91
92 int sk_disk_smart_get_bad(SkDisk *d, uint64_t *sectors) {
93 - struct attr_helper ah1, ah2;
94 - uint64_t sectors1, sectors2;
95 -
96 assert(d);
97 assert(sectors);
98
99 - ah1.found = FALSE;
100 - ah1.value = &sectors1;
101 -
102 - if (sk_disk_smart_parse_attributes(d, (SkSmartAttributeParseCallback) reallocated_cb, &ah1) < 0)
103 + if (fill_cache (d) < 0)
104 return -1;
105
106 - ah2.found = FALSE;
107 - ah2.value = &sectors2;
108 -
109 - if (sk_disk_smart_parse_attributes(d, (SkSmartAttributeParseCallback) pending_cb, &ah2) < 0)
110 - return -1;
111 -
112 - if (!ah1.found && !ah2.found) {
113 + if (!d->reallocated_sector_count_found && !d->current_pending_sector_found) {
114 errno = ENOENT;
115 return -1;
116 }
117
118 - if (ah1.found && ah2.found)
119 - *sectors = sectors1 + sectors2;
120 - else if (ah1.found)
121 - *sectors = sectors1;
122 + if (d->reallocated_sector_count_found && d->current_pending_sector_found)
123 + *sectors = d->reallocated_sector_count + d->current_pending_sector;
124 + else if (d->reallocated_sector_count_found)
125 + *sectors = d->reallocated_sector_count;
126 else
127 - *sectors = sectors2;
128 + *sectors = d->current_pending_sector;
129
130 return 0;
131 }
132 @@ -2096,16 +2102,6 @@ const char* sk_smart_overall_to_string(SkSmartOverall overall) {
133 return _P(map[overall]);
134 }
135
136 -static void bad_attribute_now_cb(SkDisk *d, const SkSmartAttributeParsedData *a, SkBool *good) {
137 - if (a->prefailure && a->good_now_valid && !a->good_now)
138 - *good = FALSE;
139 -}
140 -
141 -static void bad_attribute_in_the_past_cb(SkDisk *d, const SkSmartAttributeParsedData *a, SkBool *good) {
142 - if (a->prefailure && a->good_in_the_past_valid && !a->good_in_the_past)
143 - *good = FALSE;
144 -}
145 -
146 static uint64_t u64log2(uint64_t n) {
147 unsigned r;
148
149 @@ -2156,11 +2152,10 @@ int sk_disk_smart_get_overall(SkDisk *d, SkSmartOverall *overall) {
150 }
151
152 /* Third, check if any of the SMART attributes is bad */
153 - good = TRUE;
154 - if (sk_disk_smart_parse_attributes(d, (SkSmartAttributeParseCallback) bad_attribute_now_cb, &good) < 0)
155 + if (fill_cache (d) < 0)
156 return -1;
157
158 - if (!good) {
159 + if (d->bad_attribute_now) {
160 *overall = SK_SMART_OVERALL_BAD_ATTRIBUTE_NOW;
161 return 0;
162 }
163 @@ -2172,11 +2167,7 @@ int sk_disk_smart_get_overall(SkDisk *d, SkSmartOverall *overall) {
164 }
165
166 /* Fifth, check if any of the SMART attributes ever was bad */
167 - good = TRUE;
168 - if (sk_disk_smart_parse_attributes(d, (SkSmartAttributeParseCallback) bad_attribute_in_the_past_cb, &good) < 0)
169 - return -1;
170 -
171 - if (!good) {
172 + if (d->bad_attribute_in_the_past) {
173 *overall = SK_SMART_OVERALL_BAD_ATTRIBUTE_IN_THE_PAST;
174 return 0;
175 }
176 --
177 1.7.0
178
00 # Debian patches for libatasmart
1 0001-Speed-up-get_overall-and-get_bad.patch