aboutsummaryrefslogtreecommitdiffstats
path: root/fs/partitions/check.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/partitions/check.c')
-rw-r--r--fs/partitions/check.c46
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 *
153check_partition(struct gendisk *hd, struct block_device *bdev) 153check_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
281static 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}
291static ssize_t part_fail_read(struct hd_struct * p, char *page)
292{
293 return sprintf(page, "%d\n", p->make_it_fail);
294}
295static 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
268static struct attribute * default_attrs[] = { 303static 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;