Messages in this thread Patch in this message | | | Date | Tue, 26 May 2009 00:47:55 +0300 | From | "Michael S. Tsirkin" <> | Subject | Re: 2.a.30-rc7: fat filesystem misdetected as amiga |
| |
On Mon, May 25, 2009 at 05:08:12PM -0400, Alan Stern wrote: > On Mon, 25 May 2009, Michael S. Tsirkin wrote: > > > > So apparently this is a bug in the device; it doesn't respond correctly > > > to the first READ command. But since it does respond correctly to > > > later commands, everything works okay thereafter. You ought to be able > > > to recover from the error by running > > > > > > blockdev --rereadpt /dev/sdb > > > > > > manually. > > > > Yes, this helps. > > Would it make sense for kernel to retry automatically? > > Why doesn't it? > > I don't know the details in this case. Most likely the error code > (Logical Block Address Out of Range) is interpreted as a fatal > non-retryable error. For other sorts of errors, the kernel does retry. > > > > As far as I can tell, this has nothing to do with any user programs in > > > the distribution. It appears to be entirely the device's fault. > > > > > > Alan Stern > > > > BTW, any idea how come I later get errors apparently from amiga fs? > > Not a clue. Unless it was some odd side effect of the partition code > trying to interpret an uninitialized buffer. > > Alan Stern
So, the following works for me as a work-around. But it's probably not the appropriate way to solve the problem. Or is it? Can someone who understands partitions and filesystems tell?
block: retry on I/O error when reading partition table
Retry once on an I/O error when reading the partition table: there's no much to loose, and this helps with some disk on key devices I have.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 99e33ef..28b857a 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -510,25 +510,34 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) struct hd_struct *part; struct parsed_partitions *state; int p, highest, res; + int i; if (bdev->bd_part_count) return -EBUSY; - res = invalidate_partition(disk, 0); - if (res) - return res; - - disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY); - while ((part = disk_part_iter_next(&piter))) - delete_partition(disk, part->partno); - disk_part_iter_exit(&piter); - if (disk->fops->revalidate_disk) - disk->fops->revalidate_disk(disk); - check_disk_size_change(disk, bdev); - bdev->bd_invalidated = 0; - if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) - return 0; - if (IS_ERR(state)) /* I/O error reading the partition table */ + /* Michael S. Tsirkin has a disk on key where rescanning helps. */ +#define RESCAN_RETRY_CNT 2 + for (i = 0; i < RESCAN_RETRY_CNT; ++i) { + res = invalidate_partition(disk, 0); + if (res) + return res; + + disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY); + while ((part = disk_part_iter_next(&piter))) + delete_partition(disk, part->partno); + disk_part_iter_exit(&piter); + + if (disk->fops->revalidate_disk) + disk->fops->revalidate_disk(disk); + check_disk_size_change(disk, bdev); + bdev->bd_invalidated = 0; + if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) + return 0; + if (!IS_ERR(state)) + break; + /* I/O error reading the partition table. Retry. */ + } + if (IS_ERR(state)) /* I/O error reading the partition table */ return -EIO; /* tell userspace that the media / partition table may have changed */ -- MST
| |