From cd1b042c5c035719018cffb751714d30513af0a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 20 Jul 2012 15:20:12 +0200 Subject: FAT: Fix redundant sector read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the previous code, the remaining prefetched sectors were read again after each sector. With this patch, each sector is read only once, thus making the prefetch useful. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- fs/fat/fat.c | 59 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 26 deletions(-) (limited to 'fs/fat/fat.c') diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 48c88448a3..fbc2d7de11 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -775,7 +775,7 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) volume_info volinfo; fsdata datablock; fsdata *mydata = &datablock; - dir_entry *dentptr; + dir_entry *dentptr = NULL; __u16 prevcksum = 0xffff; char *subname = ""; __u32 cursect; @@ -874,19 +874,21 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) while (1) { int i; - debug("FAT read sect=%d, clust_size=%d, DIRENTSPERBLOCK=%zd\n", - cursect, mydata->clust_size, DIRENTSPERBLOCK); + if (j == 0) { + debug("FAT read sect=%d, clust_size=%d, DIRENTSPERBLOCK=%zd\n", + cursect, mydata->clust_size, DIRENTSPERBLOCK); - if (disk_read(cursect, - (mydata->fatsize == 32) ? - (mydata->clust_size) : - PREFETCH_BLOCKS, - do_fat_read_block) < 0) { - debug("Error: reading rootdir block\n"); - goto exit; - } + if (disk_read(cursect, + (mydata->fatsize == 32) ? + (mydata->clust_size) : + PREFETCH_BLOCKS, + do_fat_read_block) < 0) { + debug("Error: reading rootdir block\n"); + goto exit; + } - dentptr = (dir_entry *) do_fat_read_block; + dentptr = (dir_entry *) do_fat_read_block; + } for (i = 0; i < DIRENTSPERBLOCK; i++) { char s_name[14], l_name[VFAT_MAXLEN_BYTES]; @@ -1028,28 +1030,33 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) * completely processed. */ ++j; - int fat32_end = 0; - if ((mydata->fatsize == 32) && (j == mydata->clust_size)) { - int nxtsect = 0; - int nxt_clust = 0; + int rootdir_end = 0; + if (mydata->fatsize == 32) { + if (j == mydata->clust_size) { + int nxtsect = 0; + int nxt_clust = 0; - nxt_clust = get_fatent(mydata, root_cluster); - fat32_end = CHECK_CLUST(nxt_clust, 32); + nxt_clust = get_fatent(mydata, root_cluster); + rootdir_end = CHECK_CLUST(nxt_clust, 32); - nxtsect = mydata->data_begin + - (nxt_clust * mydata->clust_size); + nxtsect = mydata->data_begin + + (nxt_clust * mydata->clust_size); - root_cluster = nxt_clust; + root_cluster = nxt_clust; - cursect = nxtsect; - j = 0; + cursect = nxtsect; + j = 0; + } } else { - cursect++; + if (j == PREFETCH_BLOCKS) + j = 0; + + rootdir_end = (++cursect - mydata->rootdir_sect >= + rootdir_size); } /* If end of rootdir reached */ - if ((mydata->fatsize == 32 && fat32_end) || - (mydata->fatsize != 32 && j == rootdir_size)) { + if (rootdir_end) { if (dols == LS_ROOT) { printf("\n%d file(s), %d dir(s)\n\n", files, dirs); -- cgit v1.2.1