fs/fat: merge readwrite get_fatent_value() with readonly get_fatent()
authorStefan Brüns <stefan.bruens@rwth-aachen.de>
Fri, 16 Dec 2016 23:27:51 +0000 (00:27 +0100)
committerTom Rini <trini@konsulko.com>
Tue, 27 Dec 2016 16:24:14 +0000 (11:24 -0500)
get_fatent_value(...) flushes changed FAT entries to disk when fetching
the next FAT blocks, in every other aspect it is identical to
get_fatent(...).

Provide a stub implementation for flush_dirty_fat_buffer if
CONFIG_FAT_WRITE is not set. Calling flush_dirty_fat_buffer during read
only operation is fine as it checks if any buffers needs flushing.

Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Reviewed-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
fs/fat/fat.c
fs/fat/fat_write.c

index 6319581..73c3dd7 100644 (file)
@@ -162,6 +162,16 @@ static void get_name(dir_entry *dirent, char *s_name)
        downcase(s_name);
 }
 
+static int flush_dirty_fat_buffer(fsdata *mydata);
+#if !defined(CONFIG_FAT_WRITE)
+/* Stub for read only operation */
+int flush_dirty_fat_buffer(fsdata *mydata)
+{
+       (void)(mydata);
+       return 0;
+}
+#endif
+
 /*
  * Get the entry at index 'entry' in a FAT (12/16/32) table.
  * On failure 0x00 is returned.
@@ -173,6 +183,11 @@ static __u32 get_fatent(fsdata *mydata, __u32 entry)
        __u32 ret = 0x00;
        __u16 val1, val2;
 
+       if (CHECK_CLUST(entry, mydata->fatsize)) {
+               printf("Error: Invalid FAT entry: 0x%08x\n", entry);
+               return ret;
+       }
+
        switch (mydata->fatsize) {
        case 32:
                bufnum = entry / FAT32BUFSIZE;
@@ -192,7 +207,7 @@ static __u32 get_fatent(fsdata *mydata, __u32 entry)
                return ret;
        }
 
-       debug("FAT%d: entry: 0x%04x = %d, offset: 0x%04x = %d\n",
+       debug("FAT%d: entry: 0x%08x = %d, offset: 0x%04x = %d\n",
               mydata->fatsize, entry, entry, offset, offset);
 
        /* Read a new block of FAT entries into the cache. */
@@ -208,6 +223,10 @@ static __u32 get_fatent(fsdata *mydata, __u32 entry)
 
                startblock += mydata->fat_sect; /* Offset from start of disk */
 
+               /* Write back the fatbuf to the disk */
+               if (flush_dirty_fat_buffer(mydata) < 0)
+                       return -1;
+
                if (disk_read(startblock, getsize, bufptr) < 0) {
                        debug("Error reading FAT blocks\n");
                        return ret;
@@ -254,8 +273,8 @@ static __u32 get_fatent(fsdata *mydata, __u32 entry)
                }
                break;
        }
-       debug("FAT%d: ret: %08x, offset: %04x\n",
-              mydata->fatsize, ret, offset);
+       debug("FAT%d: ret: 0x%08x, entry: 0x%08x, offset: 0x%04x\n",
+              mydata->fatsize, ret, entry, offset);
 
        return ret;
 }
index 4605020..f6f0628 100644 (file)
@@ -143,114 +143,6 @@ static int flush_dirty_fat_buffer(fsdata *mydata)
 }
 
 /*
- * Get the entry at index 'entry' in a FAT (12/16/32) table.
- * On failure 0x00 is returned.
- * When bufnum is changed, write back the previous fatbuf to the disk.
- */
-static __u32 get_fatent_value(fsdata *mydata, __u32 entry)
-{
-       __u32 bufnum;
-       __u32 off16, offset;
-       __u32 ret = 0x00;
-       __u16 val1, val2;
-
-       if (CHECK_CLUST(entry, mydata->fatsize)) {
-               printf("Error: Invalid FAT entry: 0x%08x\n", entry);
-               return ret;
-       }
-
-       switch (mydata->fatsize) {
-       case 32:
-               bufnum = entry / FAT32BUFSIZE;
-               offset = entry - bufnum * FAT32BUFSIZE;
-               break;
-       case 16:
-               bufnum = entry / FAT16BUFSIZE;
-               offset = entry - bufnum * FAT16BUFSIZE;
-               break;
-       case 12:
-               bufnum = entry / FAT12BUFSIZE;
-               offset = entry - bufnum * FAT12BUFSIZE;
-               break;
-
-       default:
-               /* Unsupported FAT size */
-               return ret;
-       }
-
-       debug("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 = FATBUFBLOCKS;
-               __u8 *bufptr = mydata->fatbuf;
-               __u32 fatlength = mydata->fatlength;
-               __u32 startblock = bufnum * FATBUFBLOCKS;
-
-               /* Cap length if fatlength is not a multiple of FATBUFBLOCKS */
-               if (startblock + getsize > fatlength)
-                       getsize = fatlength - startblock;
-
-               startblock += mydata->fat_sect; /* Offset from start of disk */
-
-               /* Write back the fatbuf to the disk */
-               if (flush_dirty_fat_buffer(mydata) < 0)
-                       return -1;
-
-               if (disk_read(startblock, getsize, bufptr) < 0) {
-                       debug("Error reading FAT blocks\n");
-                       return ret;
-               }
-               mydata->fatbufnum = bufnum;
-       }
-
-       /* Get the actual entry from the table */
-       switch (mydata->fatsize) {
-       case 32:
-               ret = FAT2CPU32(((__u32 *) mydata->fatbuf)[offset]);
-               break;
-       case 16:
-               ret = FAT2CPU16(((__u16 *) mydata->fatbuf)[offset]);
-               break;
-       case 12:
-               off16 = (offset * 3) / 4;
-
-               switch (offset & 0x3) {
-               case 0:
-                       ret = FAT2CPU16(((__u16 *) mydata->fatbuf)[off16]);
-                       ret &= 0xfff;
-                       break;
-               case 1:
-                       val1 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
-                       val1 &= 0xf000;
-                       val2 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16 + 1]);
-                       val2 &= 0x00ff;
-                       ret = (val2 << 4) | (val1 >> 12);
-                       break;
-               case 2:
-                       val1 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
-                       val1 &= 0xff00;
-                       val2 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16 + 1]);
-                       val2 &= 0x000f;
-                       ret = (val2 << 8) | (val1 >> 8);
-                       break;
-               case 3:
-                       ret = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
-                       ret = (ret & 0xfff0) >> 4;
-                       break;
-               default:
-                       break;
-               }
-               break;
-       }
-       debug("FAT%d: ret: %08x, entry: %08x, offset: %04x\n",
-              mydata->fatsize, ret, entry, offset);
-
-       return ret;
-}
-
-/*
  * Set the file name information from 'name' into 'slotptr',
  */
 static int str2slot(dir_slot *slotptr, const char *name, int *idx)
@@ -407,7 +299,7 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster,
        if ((__u8 *)slotptr >= buflimit) {
                if (curclust == 0)
                        return -1;
-               curclust = get_fatent_value(mydata, dir_curclust);
+               curclust = get_fatent(mydata, dir_curclust);
                if (CHECK_CLUST(curclust, mydata->fatsize)) {
                        debug("curclust: 0x%x\n", curclust);
                        printf("Invalid FAT entry\n");
@@ -583,7 +475,7 @@ static __u32 determine_fatent(fsdata *mydata, __u32 entry)
        __u32 next_fat, next_entry = entry + 1;
 
        while (1) {
-               next_fat = get_fatent_value(mydata, next_entry);
+               next_fat = get_fatent(mydata, next_entry);
                if (next_fat == 0) {
                        /* found free entry, link to entry */
                        set_fatent_value(mydata, entry, next_entry);
@@ -669,7 +561,7 @@ static int find_empty_cluster(fsdata *mydata)
        __u32 fat_val, entry = 3;
 
        while (1) {
-               fat_val = get_fatent_value(mydata, entry);
+               fat_val = get_fatent(mydata, entry);
                if (fat_val == 0)
                        break;
                entry++;
@@ -719,7 +611,7 @@ static int clear_fatent(fsdata *mydata, __u32 entry)
        __u32 fat_val;
 
        while (!CHECK_CLUST(entry, mydata->fatsize)) {
-               fat_val = get_fatent_value(mydata, entry);
+               fat_val = get_fatent(mydata, entry);
                if (fat_val != 0)
                        set_fatent_value(mydata, entry, 0);
                else
@@ -996,7 +888,7 @@ static dir_entry *find_directory_entry(fsdata *mydata, int startsect,
                        return NULL;
                }
 
-               curclust = get_fatent_value(mydata, dir_curclust);
+               curclust = get_fatent(mydata, dir_curclust);
                if (IS_LAST_CLUST(curclust, mydata->fatsize)) {
                        empty_dentptr = dentptr;
                        return NULL;