diff options
Diffstat (limited to 'fs/fat/fat.c')
-rw-r--r-- | fs/fat/fat.c | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 5b9ec2a4ac0..18b291ccb14 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -201,6 +201,9 @@ get_fatent(fsdata *mydata, __u32 entry) return ret; } + FAT_DPRINT("FAT%d: entry: 0x%04x = %d, offset: 0x%04x = %d\n", + mydata->fatsize, entry, entry, offset, offset); + /* Read a new block of FAT entries into the cache. */ if (bufnum != mydata->fatbufnum) { int getsize = FATBUFSIZE/FS_BLOCK_SIZE; @@ -260,7 +263,8 @@ get_fatent(fsdata *mydata, __u32 entry) } break; } - FAT_DPRINT("ret: %d, offset: %d\n", ret, offset); + FAT_DPRINT("FAT%d: ret: %08x, offset: %04x\n", + mydata->fatsize, ret, offset); return ret; } @@ -323,7 +327,7 @@ get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer, if (maxsize > 0 && filesize > maxsize) filesize = maxsize; - FAT_DPRINT("Reading: %ld bytes\n", filesize); + FAT_DPRINT("%ld bytes\n", filesize); actsize=bytesperclust; endclust=curclust; @@ -719,16 +723,19 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize, dir_entry *dentptr; __u16 prevcksum = 0xffff; char *subname = ""; - int rootdir_size, cursect; + int cursect; int idx, isdir = 0; int files = 0, dirs = 0; long ret = 0; int firsttime; + int root_cluster; + int j; if (read_bootsectandvi (&bs, &volinfo, &mydata->fatsize)) { FAT_DPRINT ("Error: reading boot sector\n"); return -1; } + root_cluster = bs.root_cluster; if (mydata->fatsize == 32) { mydata->fatlength = bs.fat32_length; } else { @@ -739,10 +746,11 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize, = mydata->fat_sect + mydata->fatlength * bs.fats; mydata->clust_size = bs.cluster_size; if (mydata->fatsize == 32) { - rootdir_size = mydata->clust_size; - mydata->data_begin = mydata->rootdir_sect /* + rootdir_size */ + mydata->data_begin = mydata->rootdir_sect - (mydata->clust_size * 2); } else { + int rootdir_size; + rootdir_size = ((bs.dir_entries[1] * (int) 256 + bs.dir_entries[0]) * sizeof (dir_entry)) / SECTOR_SIZE; mydata->data_begin = mydata->rootdir_sect + rootdir_size @@ -750,12 +758,19 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize, } mydata->fatbufnum = -1; - FAT_DPRINT ("FAT%d, fatlength: %d\n", mydata->fatsize, +#ifdef CONFIG_SUPPORT_VFAT + FAT_DPRINT ("VFAT Support enabled\n"); +#endif + FAT_DPRINT ("FAT%d, fat_sect: %d, fatlength: %d\n", + mydata->fatsize, + mydata->fat_sect, mydata->fatlength); - FAT_DPRINT ("Rootdir begins at sector: %d, offset: %x, size: %d\n" + FAT_DPRINT ("Rootdir begins at cluster: %d, sector: %d, offset: %x\n" "Data begins at: %d\n", - mydata->rootdir_sect, mydata->rootdir_sect * SECTOR_SIZE, - rootdir_size, mydata->data_begin); + root_cluster, + mydata->rootdir_sect, + mydata->rootdir_sect * SECTOR_SIZE, + mydata->data_begin); FAT_DPRINT ("Cluster size: %d\n", mydata->clust_size); /* "cwd" is always the root... */ @@ -779,9 +794,12 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize, isdir = 1; } + j=0; while (1) { int i; + FAT_DPRINT ("FAT read sect=%d, clust_size=%d, DIRENTSPERBLOCK=%d\n", + cursect, mydata->clust_size, DIRENTSPERBLOCK); if (disk_read (cursect, mydata->clust_size, do_fat_read_block) < 0) { FAT_DPRINT ("Error: reading rootdir block\n"); return -1; @@ -894,7 +912,29 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize, goto rootdir_done; /* We got a match */ } - cursect++; + FAT_DPRINT ("END LOOP: j=%d clust_size=%d\n", j, mydata->clust_size); + + /* + * On FAT32 we must fetch the FAT entries for the next + * root directory clusters when a cluster has been + * completely processed. + */ + if ((mydata->fatsize == 32) && (++j == mydata->clust_size)) { + int nxtsect; + int cur_clust, nxt_clust; + + cur_clust = (cursect - mydata->data_begin) / mydata->clust_size; + nxt_clust = get_fatent(mydata, root_cluster); + nxtsect = mydata->data_begin + (nxt_clust * mydata->clust_size); + FAT_DPRINT ("END LOOP: sect=%d, clust=%d, root_clust=%d, n_sect=%d, n_clust=%d\n", + cursect, cur_clust, root_cluster, nxtsect, nxt_clust); + root_cluster = nxt_clust; + + cursect = nxtsect; + j = 0; + } else { + cursect++; + } } rootdir_done: |