diff options
author | Suzuki K P <suzuki@in.ibm.com> | 2006-12-06 23:35:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 11:39:30 -0500 |
commit | 57881dd9df40b76dc7fc6a0d13fd75f337accb32 (patch) | |
tree | 088010827c14fbe75628c64848839616175bb9d6 /fs/partitions | |
parent | 5127d002f9769ba6b1691de78dd3a5c14635e183 (diff) |
[PATCH] Fix check_partition routines
check_partition() stops its probe once it hits an I/O error from the
partition checkers. This would prevent the actual partition checker
getting a chance to verify the partition.
So this patch lets check_partition() continue probing untill it hits a
success while recording the I/O error which might have been reported by the
checking routines.
Also, it does some cleanup of the partition methods for ibm, atari and
amiga to return -1 upon hitting an I/O error.
Signed-off-by: Suzuki K P <suzuki@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/partitions')
-rw-r--r-- | fs/partitions/amiga.c | 2 | ||||
-rw-r--r-- | fs/partitions/atari.c | 2 | ||||
-rw-r--r-- | fs/partitions/check.c | 15 | ||||
-rw-r--r-- | fs/partitions/ibm.c | 29 |
4 files changed, 33 insertions, 15 deletions
diff --git a/fs/partitions/amiga.c b/fs/partitions/amiga.c index 3068528890a6..9917a8c360f2 100644 --- a/fs/partitions/amiga.c +++ b/fs/partitions/amiga.c | |||
@@ -43,6 +43,7 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
43 | if (warn_no_part) | 43 | if (warn_no_part) |
44 | printk("Dev %s: unable to read RDB block %d\n", | 44 | printk("Dev %s: unable to read RDB block %d\n", |
45 | bdevname(bdev, b), blk); | 45 | bdevname(bdev, b), blk); |
46 | res = -1; | ||
46 | goto rdb_done; | 47 | goto rdb_done; |
47 | } | 48 | } |
48 | if (*(__be32 *)data != cpu_to_be32(IDNAME_RIGIDDISK)) | 49 | if (*(__be32 *)data != cpu_to_be32(IDNAME_RIGIDDISK)) |
@@ -79,6 +80,7 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
79 | if (warn_no_part) | 80 | if (warn_no_part) |
80 | printk("Dev %s: unable to read partition block %d\n", | 81 | printk("Dev %s: unable to read partition block %d\n", |
81 | bdevname(bdev, b), blk); | 82 | bdevname(bdev, b), blk); |
83 | res = -1; | ||
82 | goto rdb_done; | 84 | goto rdb_done; |
83 | } | 85 | } |
84 | pb = (struct PartitionBlock *)data; | 86 | pb = (struct PartitionBlock *)data; |
diff --git a/fs/partitions/atari.c b/fs/partitions/atari.c index 192a6adfdefd..1f3572d5b755 100644 --- a/fs/partitions/atari.c +++ b/fs/partitions/atari.c | |||
@@ -88,7 +88,7 @@ int atari_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
88 | if (!xrs) { | 88 | if (!xrs) { |
89 | printk (" block %ld read failed\n", partsect); | 89 | printk (" block %ld read failed\n", partsect); |
90 | put_dev_sector(sect); | 90 | put_dev_sector(sect); |
91 | return 0; | 91 | return -1; |
92 | } | 92 | } |
93 | 93 | ||
94 | /* ++roman: sanity check: bit 0 of flg field must be set */ | 94 | /* ++roman: sanity check: bit 0 of flg field must be set */ |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 0b6113ba3b79..1901137f4eca 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,13 +165,24 @@ 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) |
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index d352a7381fed..9f7ad4244f63 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c | |||
@@ -43,7 +43,7 @@ cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) { | |||
43 | int | 43 | int |
44 | ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | 44 | ibm_partition(struct parsed_partitions *state, struct block_device *bdev) |
45 | { | 45 | { |
46 | int blocksize, offset, size; | 46 | int blocksize, offset, size,res; |
47 | loff_t i_size; | 47 | loff_t i_size; |
48 | dasd_information_t *info; | 48 | dasd_information_t *info; |
49 | struct hd_geometry *geo; | 49 | struct hd_geometry *geo; |
@@ -56,15 +56,16 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
56 | unsigned char *data; | 56 | unsigned char *data; |
57 | Sector sect; | 57 | Sector sect; |
58 | 58 | ||
59 | res = 0; | ||
59 | blocksize = bdev_hardsect_size(bdev); | 60 | blocksize = bdev_hardsect_size(bdev); |
60 | if (blocksize <= 0) | 61 | if (blocksize <= 0) |
61 | return 0; | 62 | goto out_exit; |
62 | i_size = i_size_read(bdev->bd_inode); | 63 | i_size = i_size_read(bdev->bd_inode); |
63 | if (i_size == 0) | 64 | if (i_size == 0) |
64 | return 0; | 65 | goto out_exit; |
65 | 66 | ||
66 | if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) | 67 | if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) |
67 | goto out_noinfo; | 68 | goto out_exit; |
68 | if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) | 69 | if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) |
69 | goto out_nogeo; | 70 | goto out_nogeo; |
70 | if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) | 71 | if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) |
@@ -72,7 +73,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
72 | 73 | ||
73 | if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || | 74 | if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || |
74 | ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) | 75 | ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) |
75 | goto out_noioctl; | 76 | goto out_freeall; |
76 | 77 | ||
77 | /* | 78 | /* |
78 | * Get volume label, extract name and type. | 79 | * Get volume label, extract name and type. |
@@ -92,6 +93,8 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
92 | EBCASC(type, 4); | 93 | EBCASC(type, 4); |
93 | EBCASC(name, 6); | 94 | EBCASC(name, 6); |
94 | 95 | ||
96 | res = 1; | ||
97 | |||
95 | /* | 98 | /* |
96 | * Three different types: CMS1, VOL1 and LNX1/unlabeled | 99 | * Three different types: CMS1, VOL1 and LNX1/unlabeled |
97 | */ | 100 | */ |
@@ -156,6 +159,9 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
156 | counter++; | 159 | counter++; |
157 | blk++; | 160 | blk++; |
158 | } | 161 | } |
162 | if (!data) | ||
163 | /* Are we not supposed to report this ? */ | ||
164 | goto out_readerr; | ||
159 | } else { | 165 | } else { |
160 | /* | 166 | /* |
161 | * Old style LNX1 or unlabeled disk | 167 | * Old style LNX1 or unlabeled disk |
@@ -171,18 +177,17 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
171 | } | 177 | } |
172 | 178 | ||
173 | printk("\n"); | 179 | printk("\n"); |
174 | kfree(label); | 180 | goto out_freeall; |
175 | kfree(geo); | 181 | |
176 | kfree(info); | ||
177 | return 1; | ||
178 | 182 | ||
179 | out_readerr: | 183 | out_readerr: |
180 | out_noioctl: | 184 | res = -1; |
185 | out_freeall: | ||
181 | kfree(label); | 186 | kfree(label); |
182 | out_nolab: | 187 | out_nolab: |
183 | kfree(geo); | 188 | kfree(geo); |
184 | out_nogeo: | 189 | out_nogeo: |
185 | kfree(info); | 190 | kfree(info); |
186 | out_noinfo: | 191 | out_exit: |
187 | return 0; | 192 | return res; |
188 | } | 193 | } |