summaryrefslogtreecommitdiff
path: root/fs/fat
diff options
context:
space:
mode:
authorKyle Moffett <Kyle.D.Moffett@boeing.com>2011-12-20 07:41:13 +0000
committerWolfgang Denk <wd@denx.de>2012-01-05 20:10:37 +0100
commit46236b1407946aaed319551357703d487f82572e (patch)
tree2546a1cb136c09ad8bd3264bb184fa31da4e8839 /fs/fat
parent9813b750f32c0056f0a35813b9a9ec0f68b664af (diff)
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>
Diffstat (limited to 'fs/fat')
-rw-r--r--fs/fat/fat.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 2bb7adfcf15..1f95eb4cafe 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 -