* The 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 the 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 Index: linux-2.6.18/fs/partitions/check.c =================================================================== --- linux-2.6.18.orig/fs/partitions/check.c 2006-10-07 06:10:16.000000000 +0530 +++ linux-2.6.18/fs/partitions/check.c 2006-10-07 06:21:39.000000000 +0530 @@ -153,7 +153,7 @@ check_partition(struct gendisk *hd, struct block_device *bdev) { struct parsed_partitions *state; - int i, res; + int i, res, err; state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL); if (!state) @@ -165,13 +165,24 @@ sprintf(state->name, "p"); state->limit = hd->minors; - i = res = 0; + i = res = err = 0; while (!res && check_part[i]) { memset(&state->parts, 0, sizeof(state->parts)); res = check_part[i++](state, bdev); + if (res < 0) { + /* We have hit an I/O error which we don't report now. + * But record it, and let the others do their job. + */ + err = res; + res = 0; + } + } if (res > 0) return state; + if (!err) + /* The partition is unrecognized. So report I/O errors if there were any */ + res = err; if (!res) printk(" unknown partition table\n"); else if (warn_no_part) Index: linux-2.6.18/fs/partitions/amiga.c =================================================================== --- linux-2.6.18.orig/fs/partitions/amiga.c 2006-09-20 09:12:06.000000000 +0530 +++ linux-2.6.18/fs/partitions/amiga.c 2006-10-07 06:57:44.000000000 +0530 @@ -43,6 +43,7 @@ if (warn_no_part) printk("Dev %s: unable to read RDB block %d\n", bdevname(bdev, b), blk); + res = -1; goto rdb_done; } if (*(__be32 *)data != cpu_to_be32(IDNAME_RIGIDDISK)) @@ -79,6 +80,7 @@ if (warn_no_part) printk("Dev %s: unable to read partition block %d\n", bdevname(bdev, b), blk); + res = -1; goto rdb_done; } pb = (struct PartitionBlock *)data; Index: linux-2.6.18/fs/partitions/ibm.c =================================================================== --- linux-2.6.18.orig/fs/partitions/ibm.c 2006-09-20 09:12:06.000000000 +0530 +++ linux-2.6.18/fs/partitions/ibm.c 2006-10-07 06:55:23.000000000 +0530 @@ -43,7 +43,7 @@ int ibm_partition(struct parsed_partitions *state, struct block_device *bdev) { - int blocksize, offset, size; + int blocksize, offset, size,res; loff_t i_size; dasd_information_t *info; struct hd_geometry *geo; @@ -55,16 +55,17 @@ } *label; unsigned char *data; Sector sect; - + + res = 0; blocksize = bdev_hardsect_size(bdev); if (blocksize <= 0) - return 0; + goto out_exit; i_size = i_size_read(bdev->bd_inode); if (i_size == 0) - return 0; + goto out_exit; if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) - goto out_noinfo; + goto out_exit; if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) goto out_nogeo; if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) @@ -72,7 +73,7 @@ if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) - goto out_noioctl; + goto out_freeall; /* * Get volume label, extract name and type. @@ -91,6 +92,8 @@ EBCASC(type, 4); EBCASC(name, 6); + + res = 1; /* * Three different types: CMS1, VOL1 and LNX1/unlabeled @@ -156,6 +159,9 @@ counter++; blk++; } + if (!data) + /* Are we not supposed to report this ? */ + goto out_readerr; } else { /* * Old style LNX1 or unlabeled disk @@ -171,18 +177,17 @@ } printk("\n"); - kfree(label); - kfree(geo); - kfree(info); - return 1; + goto out_freeall; + out_readerr: -out_noioctl: + res = -1; +out_freeall: kfree(label); out_nolab: kfree(geo); out_nogeo: kfree(info); -out_noinfo: - return 0; +out_exit: + return res; } Index: linux-2.6.18/fs/partitions/atari.c =================================================================== --- linux-2.6.18.orig/fs/partitions/atari.c 2006-09-20 09:12:06.000000000 +0530 +++ linux-2.6.18/fs/partitions/atari.c 2006-10-07 06:58:22.000000000 +0530 @@ -88,7 +88,7 @@ if (!xrs) { printk (" block %ld read failed\n", partsect); put_dev_sector(sect); - return 0; + return -1; } /* ++roman: sanity check: bit 0 of flg field must be set */