diff options
author | Kyle Moffett <Kyle.D.Moffett@boeing.com> | 2011-12-20 07:41:13 +0000 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2012-01-05 20:10:37 +0100 |
commit | 46236b1407946aaed319551357703d487f82572e (patch) | |
tree | 2546a1cb136c09ad8bd3264bb184fa31da4e8839 | |
parent | 9813b750f32c0056f0a35813b9a9ec0f68b664af (diff) | |
download | u-boot-46236b1407946aaed319551357703d487f82572e.zip u-boot-46236b1407946aaed319551357703d487f82572e.tar.gz u-boot-46236b1407946aaed319551357703d487f82572e.tar.bz2 |
fs/fat: Improve error handling
The FAT filesystem fails silently in inexplicable ways when given a
filesystem with a block-size that does not match the device sector size.
In theory this is not an unsupportable combination but requires a major
rewrite of a lot of the filesystem. Until that occurs, the filesystem
should detect that scenario and display a helpful error message.
This scenario in particular occurred on a 512-byte blocksize FAT fs
stored in an El-Torito boot volume on a CD-ROM (2048-byte sector size).
Additionally, in many circumstances the ->block_read method will not
return a negative number to indicate an error but instead return 0 to
indicate the number of blocks successfully read (IE: None).
The FAT filesystem should defensively check to ensure that it got all of
the sectors that it asked for when reading.
Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
-rw-r--r-- | fs/fat/fat.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 2bb7adf..1f95eb4 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -274,6 +274,8 @@ get_cluster (fsdata *mydata, __u32 clustnum, __u8 *buffer, { __u32 idx = 0; __u32 startsect; + __u32 nr_sect; + int ret; if (clustnum > 0) { startsect = mydata->data_begin + @@ -284,16 +286,19 @@ get_cluster (fsdata *mydata, __u32 clustnum, __u8 *buffer, debug("gc - clustnum: %d, startsect: %d\n", clustnum, startsect); - if (disk_read(startsect, size / mydata->sect_size, buffer) < 0) { - debug("Error reading data\n"); + nr_sect = size / mydata->sect_size; + ret = disk_read(startsect, nr_sect, buffer); + if (ret != nr_sect) { + debug("Error reading data (got %d)\n", ret); return -1; } if (size % mydata->sect_size) { __u8 tmpbuf[mydata->sect_size]; idx = size / mydata->sect_size; - if (disk_read(startsect + idx, 1, tmpbuf) < 0) { - debug("Error reading data\n"); + ret = disk_read(startsect + idx, 1, tmpbuf); + if (ret != 1) { + debug("Error reading data (got %d)\n", ret); return -1; } buffer += idx * mydata->sect_size; @@ -803,6 +808,11 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize, mydata->sect_size = (bs.sector_size[1] << 8) + bs.sector_size[0]; mydata->clust_size = bs.cluster_size; + if (mydata->sect_size != cur_part_info.blksz) { + printf("Error: FAT sector size mismatch (fs=%hu, dev=%lu)\n", + mydata->sect_size, cur_part_info.blksz); + return -1; + } if (mydata->fatsize == 32) { mydata->data_begin = mydata->rootdir_sect - |