summaryrefslogtreecommitdiffstats
path: root/fs/fat/fat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fat/fat.c')
-rw-r--r--fs/fat/fat.c60
1 files changed, 50 insertions, 10 deletions
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 5b9ec2a4ac..18b291ccb1 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:
OpenPOWER on IntegriCloud