diff options
Diffstat (limited to 'fs/partitions/check.c')
-rw-r--r-- | fs/partitions/check.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 6fb4b6150d77..3d73d94d93a7 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -153,7 +153,7 @@ static struct parsed_partitions * | |||
153 | check_partition(struct gendisk *hd, struct block_device *bdev) | 153 | check_partition(struct gendisk *hd, struct block_device *bdev) |
154 | { | 154 | { |
155 | struct parsed_partitions *state; | 155 | struct parsed_partitions *state; |
156 | int i, res; | 156 | int i, res, err; |
157 | 157 | ||
158 | state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL); | 158 | state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL); |
159 | if (!state) | 159 | if (!state) |
@@ -165,19 +165,30 @@ check_partition(struct gendisk *hd, struct block_device *bdev) | |||
165 | sprintf(state->name, "p"); | 165 | sprintf(state->name, "p"); |
166 | 166 | ||
167 | state->limit = hd->minors; | 167 | state->limit = hd->minors; |
168 | i = res = 0; | 168 | i = res = err = 0; |
169 | while (!res && check_part[i]) { | 169 | while (!res && check_part[i]) { |
170 | memset(&state->parts, 0, sizeof(state->parts)); | 170 | memset(&state->parts, 0, sizeof(state->parts)); |
171 | res = check_part[i++](state, bdev); | 171 | res = check_part[i++](state, bdev); |
172 | if (res < 0) { | ||
173 | /* We have hit an I/O error which we don't report now. | ||
174 | * But record it, and let the others do their job. | ||
175 | */ | ||
176 | err = res; | ||
177 | res = 0; | ||
178 | } | ||
179 | |||
172 | } | 180 | } |
173 | if (res > 0) | 181 | if (res > 0) |
174 | return state; | 182 | return state; |
183 | if (!err) | ||
184 | /* The partition is unrecognized. So report I/O errors if there were any */ | ||
185 | res = err; | ||
175 | if (!res) | 186 | if (!res) |
176 | printk(" unknown partition table\n"); | 187 | printk(" unknown partition table\n"); |
177 | else if (warn_no_part) | 188 | else if (warn_no_part) |
178 | printk(" unable to read partition table\n"); | 189 | printk(" unable to read partition table\n"); |
179 | kfree(state); | 190 | kfree(state); |
180 | return NULL; | 191 | return ERR_PTR(res); |
181 | } | 192 | } |
182 | 193 | ||
183 | /* | 194 | /* |
@@ -265,12 +276,39 @@ static struct part_attribute part_attr_stat = { | |||
265 | .show = part_stat_read | 276 | .show = part_stat_read |
266 | }; | 277 | }; |
267 | 278 | ||
279 | #ifdef CONFIG_FAIL_MAKE_REQUEST | ||
280 | |||
281 | static ssize_t part_fail_store(struct hd_struct * p, | ||
282 | const char *buf, size_t count) | ||
283 | { | ||
284 | int i; | ||
285 | |||
286 | if (count > 0 && sscanf(buf, "%d", &i) > 0) | ||
287 | p->make_it_fail = (i == 0) ? 0 : 1; | ||
288 | |||
289 | return count; | ||
290 | } | ||
291 | static ssize_t part_fail_read(struct hd_struct * p, char *page) | ||
292 | { | ||
293 | return sprintf(page, "%d\n", p->make_it_fail); | ||
294 | } | ||
295 | static struct part_attribute part_attr_fail = { | ||
296 | .attr = {.name = "make-it-fail", .mode = S_IRUGO | S_IWUSR }, | ||
297 | .store = part_fail_store, | ||
298 | .show = part_fail_read | ||
299 | }; | ||
300 | |||
301 | #endif | ||
302 | |||
268 | static struct attribute * default_attrs[] = { | 303 | static struct attribute * default_attrs[] = { |
269 | &part_attr_uevent.attr, | 304 | &part_attr_uevent.attr, |
270 | &part_attr_dev.attr, | 305 | &part_attr_dev.attr, |
271 | &part_attr_start.attr, | 306 | &part_attr_start.attr, |
272 | &part_attr_size.attr, | 307 | &part_attr_size.attr, |
273 | &part_attr_stat.attr, | 308 | &part_attr_stat.attr, |
309 | #ifdef CONFIG_FAIL_MAKE_REQUEST | ||
310 | &part_attr_fail.attr, | ||
311 | #endif | ||
274 | NULL, | 312 | NULL, |
275 | }; | 313 | }; |
276 | 314 | ||
@@ -494,6 +532,8 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) | |||
494 | disk->fops->revalidate_disk(disk); | 532 | disk->fops->revalidate_disk(disk); |
495 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) | 533 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) |
496 | return 0; | 534 | return 0; |
535 | if (IS_ERR(state)) /* I/O error reading the partition table */ | ||
536 | return PTR_ERR(state); | ||
497 | for (p = 1; p < state->limit; p++) { | 537 | for (p = 1; p < state->limit; p++) { |
498 | sector_t size = state->parts[p].size; | 538 | sector_t size = state->parts[p].size; |
499 | sector_t from = state->parts[p].from; | 539 | sector_t from = state->parts[p].from; |