FATFileSystem fork with fixes

Dependents:   SDFileSystem

Fork of FATFileSystem by mbed official

Revision:
4:3ff2606d5713
Parent:
3:e960e2b81a3c
Child:
5:b3b3370574cf
--- a/ChaN/ff.cpp	Mon Mar 17 14:09:00 2014 +0000
+++ b/ChaN/ff.cpp	Thu Aug 28 13:15:31 2014 +0100
@@ -527,16 +527,14 @@
 
 /* Copy memory to memory */
 static
-void mem_cpy (void* dst, const void* src, UINT cnt)
-{
+void mem_cpy (void* dst, const void* src, UINT cnt) {
     BYTE *d = (BYTE*)dst;
     const BYTE *s = (const BYTE*)src;
 
 #if _WORD_ACCESS == 1
     while (cnt >= sizeof (int)) {
         *(int*)d = *(int*)s;
-        d += sizeof (int);
-        s += sizeof (int);
+        d += sizeof (int); s += sizeof (int);
         cnt -= sizeof (int);
     }
 #endif
@@ -546,8 +544,7 @@
 
 /* Fill memory */
 static
-void mem_set (void* dst, int val, UINT cnt)
-{
+void mem_set (void* dst, int val, UINT cnt) {
     BYTE *d = (BYTE*)dst;
 
     while (cnt--)
@@ -556,8 +553,7 @@
 
 /* Compare memory to memory */
 static
-int mem_cmp (const void* dst, const void* src, UINT cnt)
-{
+int mem_cmp (const void* dst, const void* src, UINT cnt) {
     const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src;
     int r = 0;
 
@@ -567,8 +563,7 @@
 
 /* Check if chr is contained in the string */
 static
-int chk_chr (const char* str, int chr)
-{
+int chk_chr (const char* str, int chr) {
     while (*str && *str != chr) str++;
     return *str;
 }
@@ -596,10 +591,10 @@
 )
 {
     if (fs &&
-            res != FR_NOT_ENABLED &&
-            res != FR_INVALID_DRIVE &&
-            res != FR_INVALID_OBJECT &&
-            res != FR_TIMEOUT) {
+        res != FR_NOT_ENABLED &&
+        res != FR_INVALID_DRIVE &&
+        res != FR_INVALID_OBJECT &&
+        res != FR_TIMEOUT) {
         ff_rel_grant(fs->sobj);
     }
 }
@@ -624,8 +619,8 @@
     for (i = be = 0; i < _FS_LOCK; i++) {
         if (Files[i].fs) {  /* Existing entry */
             if (Files[i].fs == dj->fs &&        /* Check if the file matched with an open file */
-                    Files[i].clu == dj->sclust &&
-                    Files[i].idx == dj->index) break;
+                Files[i].clu == dj->sclust &&
+                Files[i].idx == dj->index) break;
         } else {            /* Blank entry */
             be++;
         }
@@ -659,8 +654,8 @@
 
     for (i = 0; i < _FS_LOCK; i++) {    /* Find the file */
         if (Files[i].fs == dj->fs &&
-                Files[i].clu == dj->sclust &&
-                Files[i].idx == dj->index) break;
+            Files[i].clu == dj->sclust &&
+            Files[i].idx == dj->index) break;
     }
 
     if (i == _FS_LOCK) {                /* Not opened. Register it as new. */
@@ -836,25 +831,23 @@
         return 1;
 
     switch (fs->fs_type) {
-        case FS_FAT12 :
-            bc = (UINT)clst;
-            bc += bc / 2;
-            if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
-            wc = fs->win[bc % SS(fs)];
-            bc++;
-            if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
-            wc |= fs->win[bc % SS(fs)] << 8;
-            return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
-
-        case FS_FAT16 :
-            if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break;
-            p = &fs->win[clst * 2 % SS(fs)];
-            return LD_WORD(p);
-
-        case FS_FAT32 :
-            if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break;
-            p = &fs->win[clst * 4 % SS(fs)];
-            return LD_DWORD(p) & 0x0FFFFFFF;
+    case FS_FAT12 :
+        bc = (UINT)clst; bc += bc / 2;
+        if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
+        wc = fs->win[bc % SS(fs)]; bc++;
+        if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
+        wc |= fs->win[bc % SS(fs)] << 8;
+        return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
+
+    case FS_FAT16 :
+        if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break;
+        p = &fs->win[clst * 2 % SS(fs)];
+        return LD_WORD(p);
+
+    case FS_FAT32 :
+        if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break;
+        p = &fs->win[clst * 4 % SS(fs)];
+        return LD_DWORD(p) & 0x0FFFFFFF;
     }
 
     return 0xFFFFFFFF;  /* An error occurred at the disk I/O layer */
@@ -884,38 +877,37 @@
 
     } else {
         switch (fs->fs_type) {
-            case FS_FAT12 :
-                bc = (UINT)clst;
-                bc += bc / 2;
-                res = move_window(fs, fs->fatbase + (bc / SS(fs)));
-                if (res != FR_OK) break;
-                p = &fs->win[bc % SS(fs)];
-                *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
-                bc++;
-                fs->wflag = 1;
-                res = move_window(fs, fs->fatbase + (bc / SS(fs)));
-                if (res != FR_OK) break;
-                p = &fs->win[bc % SS(fs)];
-                *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
-                break;
-
-            case FS_FAT16 :
-                res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));
-                if (res != FR_OK) break;
-                p = &fs->win[clst * 2 % SS(fs)];
-                ST_WORD(p, (WORD)val);
-                break;
-
-            case FS_FAT32 :
-                res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));
-                if (res != FR_OK) break;
-                p = &fs->win[clst * 4 % SS(fs)];
-                val |= LD_DWORD(p) & 0xF0000000;
-                ST_DWORD(p, val);
-                break;
-
-            default :
-                res = FR_INT_ERR;
+        case FS_FAT12 :
+            bc = (UINT)clst; bc += bc / 2;
+            res = move_window(fs, fs->fatbase + (bc / SS(fs)));
+            if (res != FR_OK) break;
+            p = &fs->win[bc % SS(fs)];
+            *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
+            bc++;
+            fs->wflag = 1;
+            res = move_window(fs, fs->fatbase + (bc / SS(fs)));
+            if (res != FR_OK) break;
+            p = &fs->win[bc % SS(fs)];
+            *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
+            break;
+
+        case FS_FAT16 :
+            res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));
+            if (res != FR_OK) break;
+            p = &fs->win[clst * 2 % SS(fs)];
+            ST_WORD(p, (WORD)val);
+            break;
+
+        case FS_FAT32 :
+            res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));
+            if (res != FR_OK) break;
+            p = &fs->win[clst * 4 % SS(fs)];
+            val |= LD_DWORD(p) & 0xF0000000;
+            ST_DWORD(p, val);
+            break;
+
+        default :
+            res = FR_INT_ERR;
         }
         fs->wflag = 1;
     }
@@ -951,14 +943,8 @@
         while (clst < fs->n_fatent) {           /* Not a last link? */
             nxt = get_fat(fs, clst);            /* Get cluster status */
             if (nxt == 0) break;                /* Empty cluster? */
-            if (nxt == 1) {
-                res = FR_INT_ERR;    /* Internal error? */
-                break;
-            }
-            if (nxt == 0xFFFFFFFF) {
-                res = FR_DISK_ERR;    /* Disk error? */
-                break;
-            }
+            if (nxt == 1) { res = FR_INT_ERR; break; }  /* Internal error? */
+            if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }    /* Disk error? */
             res = put_fat(fs, clst, 0);         /* Mark the cluster "empty" */
             if (res != FR_OK) break;
             if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */
@@ -1003,7 +989,8 @@
     if (clst == 0) {        /* Create a new chain */
         scl = fs->last_clust;           /* Get suggested start point */
         if (!scl || scl >= fs->n_fatent) scl = 1;
-    } else {                /* Stretch the current chain */
+    }
+    else {                  /* Stretch the current chain */
         cs = get_fat(fs, clst);         /* Check the cluster status */
         if (cs < 2) return 1;           /* It is an invalid cluster */
         if (cs < fs->n_fatent) return cs;   /* It is already followed by next cluster */
@@ -1064,8 +1051,7 @@
         ncl = *tbl++;           /* Number of cluters in the fragment */
         if (!ncl) return 0;     /* End of table? (error) */
         if (cl < ncl) break;    /* In this fragment? */
-        cl -= ncl;
-        tbl++;       /* Next fragment */
+        cl -= ncl; tbl++;       /* Next fragment */
     }
     return cl + *tbl;   /* Return the cluster number */
 }
@@ -1099,7 +1085,8 @@
         if (idx >= dj->fs->n_rootdir)       /* Index is out of range */
             return FR_INT_ERR;
         dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / SZ_DIR);   /* Sector# */
-    } else {            /* Dynamic table (sub-dirs or root-dir in FAT32) */
+    }
+    else {              /* Dynamic table (sub-dirs or root-dir in FAT32) */
         ic = SS(dj->fs) / SZ_DIR * dj->fs->csize;   /* Entries per cluster */
         while (idx >= ic) { /* Follow cluster chain */
             clst = get_fat(dj->fs, clst);               /* Get next cluster */
@@ -1145,7 +1132,8 @@
         if (dj->clust == 0) {   /* Static table */
             if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */
                 return FR_NO_FILE;
-        } else {                /* Dynamic table */
+        }
+        else {                  /* Dynamic table */
             if (((i / (SS(dj->fs) / SZ_DIR)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */
                 clst = get_fat(dj->fs, dj->clust);              /* Get next cluster */
                 if (clst <= 1) return FR_INT_ERR;
@@ -1240,8 +1228,7 @@
 
 
     i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13;  /* Get offset in the LFN buffer */
-    s = 0;
-    wc = 1;
+    s = 0; wc = 1;
     do {
         uc = LD_WORD(dir+LfnOfs[s]);    /* Pick an LFN character from the entry */
         if (wc) {   /* Last char has not been processed */
@@ -1273,8 +1260,7 @@
 
     i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13;  /* Offset in the LFN buffer */
 
-    s = 0;
-    wc = 1;
+    s = 0; wc = 1;
     do {
         uc = LD_WORD(dir+LfnOfs[s]);        /* Pick an LFN character from the entry */
         if (wc) {   /* Last char has not been processed */
@@ -1346,8 +1332,7 @@
     mem_cpy(dst, src, 11);
 
     if (seq > 5) {  /* On many collisions, generate a hash number instead of sequential number */
-        do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++;
-        while (*lfn);
+        do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++; while (*lfn);
     }
 
     /* itoa (hexdecimal) */
@@ -1388,8 +1373,7 @@
     BYTE sum = 0;
     UINT n = 11;
 
-    do sum = (sum >> 1) + (sum << 7) + *dir++;
-    while (--n);
+    do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n);
     return sum;
 }
 #endif
@@ -1423,10 +1407,7 @@
         if (res != FR_OK) break;
         dir = dj->dir;                  /* Ptr to the directory entry of current index */
         c = dir[DIR_Name];
-        if (c == 0) {
-            res = FR_NO_FILE;    /* Reached to end of table */
-            break;
-        }
+        if (c == 0) { res = FR_NO_FILE; break; }    /* Reached to end of table */
 #if _USE_LFN    /* LFN configuration */
         a = dir[DIR_Attr] & AM_MASK;
         if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) {    /* An entry without valid data */
@@ -1436,8 +1417,7 @@
                 if (dj->lfn) {
                     if (c & LLE) {      /* Is it start of LFN sequence? */
                         sum = dir[LDIR_Chksum];
-                        c &= ~LLE;
-                        ord = c; /* LFN start order */
+                        c &= ~LLE; ord = c; /* LFN start order */
                         dj->lfn_idx = dj->index;
                     }
                     /* Check validity of the LFN entry and compare it with given name */
@@ -1445,8 +1425,7 @@
                 }
             } else {                    /* An SFN entry is found */
                 if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */
-                ord = 0xFF;
-                dj->lfn_idx = 0xFFFF;   /* Reset LFN sequence */
+                ord = 0xFF; dj->lfn_idx = 0xFFFF;   /* Reset LFN sequence */
                 if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break;    /* SFN matched? */
             }
         }
@@ -1484,10 +1463,7 @@
         if (res != FR_OK) break;
         dir = dj->dir;                  /* Ptr to the directory entry of current index */
         c = dir[DIR_Name];
-        if (c == 0) {
-            res = FR_NO_FILE;    /* Reached to end of table */
-            break;
-        }
+        if (c == 0) { res = FR_NO_FILE; break; }    /* Reached to end of table */
 #if _USE_LFN    /* LFN configuration */
         a = dir[DIR_Attr] & AM_MASK;
         if (c == DDE || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) {    /* An entry without valid data */
@@ -1496,8 +1472,7 @@
             if (a == AM_LFN) {          /* An LFN entry is found */
                 if (c & LLE) {          /* Is it start of LFN sequence? */
                     sum = dir[LDIR_Chksum];
-                    c &= ~LLE;
-                    ord = c;
+                    c &= ~LLE; ord = c;
                     dj->lfn_idx = dj->index;
                 }
                 /* Check LFN validity and capture it */
@@ -1541,16 +1516,14 @@
     WCHAR *lfn;
 
 
-    fn = dj->fn;
-    lfn = dj->lfn;
+    fn = dj->fn; lfn = dj->lfn;
     mem_cpy(sn, fn, 12);
 
     if (_FS_RPATH && (sn[NS] & NS_DOT))     /* Cannot create dot entry */
         return FR_INVALID_NAME;
 
     if (sn[NS] & NS_LOSS) {         /* When LFN is out of 8.3 format, generate a numbered name */
-        fn[NS] = 0;
-        dj->lfn = 0;            /* Find only SFN */
+        fn[NS] = 0; dj->lfn = 0;            /* Find only SFN */
         for (n = 1; n < 100; n++) {
             gen_numname(fn, sn, lfn, n);    /* Generate a numbered name */
             res = dir_find(dj);             /* Check if the name collides with existing SFN */
@@ -1558,8 +1531,7 @@
         }
         if (n == 100) return FR_DENIED;     /* Abort if too many collisions */
         if (res != FR_NO_FILE) return res;  /* Abort if the result is other than 'not collided' */
-        fn[NS] = sn[NS];
-        dj->lfn = lfn;
+        fn[NS] = sn[NS]; dj->lfn = lfn;
     }
 
     if (sn[NS] & NS_LFN) {          /* When LFN is to be created, reserve an SFN + LFN entries. */
@@ -1714,8 +1686,7 @@
             b = (BYTE)p[si++];          /* Get 2nd byte */
             if (!IsDBCS2(b))
                 return FR_INVALID_NAME; /* Reject invalid sequence */
-            else
-                w = (w << 8) + b;           /* Create a DBC */
+            w = (w << 8) + b;           /* Create a DBC */
         }
         w = ff_convert(w, 1);           /* Convert ANSI/OEM to Unicode */
         if (!w) return FR_INVALID_NAME; /* Reject invalid code */
@@ -1728,7 +1699,7 @@
     cf = (w < ' ') ? NS_LAST : 0;       /* Set last segment flag if end of path */
 #if _FS_RPATH
     if ((di == 1 && lfn[di-1] == '.') || /* Is this a dot entry? */
-            (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) {
+        (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) {
         lfn[di] = 0;
         for (i = 0; i < 11; i++)
             dj->fn[i] = (i < di) ? '.' : ' ';
@@ -1751,28 +1722,22 @@
     if (si) cf |= NS_LOSS | NS_LFN;
     while (di && lfn[di - 1] != '.') di--;  /* Find extension (di<=si: no extension) */
 
-    b = i = 0;
-    ni = 8;
+    b = i = 0; ni = 8;
     for (;;) {
         w = lfn[si++];                  /* Get an LFN char */
         if (!w) break;                  /* Break on end of the LFN */
         if (w == ' ' || (w == '.' && si != di)) {   /* Remove spaces and dots */
-            cf |= NS_LOSS | NS_LFN;
-            continue;
+            cf |= NS_LOSS | NS_LFN; continue;
         }
 
         if (i >= ni || si == di) {      /* Extension or end of SFN */
             if (ni == 11) {             /* Long extension */
-                cf |= NS_LOSS | NS_LFN;
-                break;
+                cf |= NS_LOSS | NS_LFN; break;
             }
             if (si != di) cf |= NS_LOSS | NS_LFN;   /* Out of 8.3 format */
             if (si > di) break;         /* No extension */
-            si = di;
-            i = 8;
-            ni = 11;    /* Enter extension section */
-            b <<= 2;
-            continue;
+            si = di; i = 8; ni = 11;    /* Enter extension section */
+            b <<= 2; continue;
         }
 
         if (w >= 0x80) {                /* Non ASCII char */
@@ -1787,22 +1752,18 @@
 
         if (_DF1S && w >= 0x100) {      /* Double byte char (always false on SBCS cfg) */
             if (i >= ni - 1) {
-                cf |= NS_LOSS | NS_LFN;
-                i = ni;
-                continue;
+                cf |= NS_LOSS | NS_LFN; i = ni; continue;
             }
             dj->fn[i++] = (BYTE)(w >> 8);
         } else {                        /* Single byte char */
             if (!w || chk_chr("+,;=[]", w)) {   /* Replace illegal chars for SFN */
-                w = '_';
-                cf |= NS_LOSS | NS_LFN;/* Lossy conversion */
+                w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */
             } else {
                 if (IsUpper(w)) {       /* ASCII large capital */
                     b |= 2;
                 } else {
                     if (IsLower(w)) {   /* ASCII small capital */
-                        b |= 1;
-                        w -= 0x20;
+                        b |= 1; w -= 0x20;
                     }
                 }
             }
@@ -1834,8 +1795,7 @@
     for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */
     sfn = dj->fn;
     mem_set(sfn, ' ', 11);
-    si = i = b = 0;
-    ni = 8;
+    si = i = b = 0; ni = 8;
 #if _FS_RPATH
     if (p[si] == '.') { /* Is this a dot entry? */
         for (;;) {
@@ -1854,10 +1814,8 @@
         if (c <= ' ' || c == '/' || c == '\\') break;   /* Break on end of segment */
         if (c == '.' || i >= ni) {
             if (ni != 8 || c != '.') return FR_INVALID_NAME;
-            i = 8;
-            ni = 11;
-            b <<= 2;
-            continue;
+            i = 8; ni = 11;
+            b <<= 2; continue;
         }
         if (c >= 0x80) {                /* Extended char? */
             b |= 3;                     /* Eliminate NT flag */
@@ -1882,8 +1840,7 @@
                 b |= 2;
             } else {
                 if (IsLower(c)) {       /* ASCII small capital? */
-                    b |= 1;
-                    c -= 0x20;
+                    b |= 1; c -= 0x20;
                 }
             }
             sfn[i++] = c;
@@ -1973,17 +1930,11 @@
             while ((w = *lfn++) != 0) {         /* Get an LFN char */
 #if !_LFN_UNICODE
                 w = ff_convert(w, 0);           /* Unicode -> OEM conversion */
-                if (!w) {
-                    i = 0;    /* Could not convert, no LFN */
-                    break;
-                }
+                if (!w) { i = 0; break; }       /* Could not convert, no LFN */
                 if (_DF1S && w >= 0x100)        /* Put 1st byte if it is a DBC (always false on SBCS cfg) */
                     tp[i++] = (TCHAR)(w >> 8);
 #endif
-                if (i >= fno->lfsize - 1) {
-                    i = 0;    /* Buffer overflow, no LFN */
-                    break;
-                }
+                if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overflow, no LFN */
                 tp[i++] = (TCHAR)w;
             }
         }
@@ -2012,8 +1963,7 @@
 
 #if _FS_RPATH
     if (*path == '/' || *path == '\\') { /* There is a heading separator */
-        path++;
-        dj->sclust = 0;     /* Strip it and start from the root dir */
+        path++; dj->sclust = 0;     /* Strip it and start from the root dir */
     } else {                            /* No heading separator */
         dj->sclust = dj->fs->cdir;  /* Start from the current dir */
     }
@@ -2036,8 +1986,7 @@
                 if (res != FR_NO_FILE) break;   /* Abort if any hard error occurred */
                 /* Object not found */
                 if (_FS_RPATH && (ns & NS_DOT)) {   /* If dot entry is not exit */
-                    dj->sclust = 0;
-                    dj->dir = 0;    /* It is the root dir */
+                    dj->sclust = 0; dj->dir = 0;    /* It is the root dir */
                     res = FR_OK;
                     if (!(ns & NS_LAST)) continue;
                 } else {                            /* Could not find the object */
@@ -2048,8 +1997,7 @@
             if (ns & NS_LAST) break;            /* Last segment match. Function completed. */
             dir = dj->dir;                      /* There is next segment. Follow the sub directory */
             if (!(dir[DIR_Attr] & AM_DIR)) {    /* Cannot follow because it is a file */
-                res = FR_NO_PATH;
-                break;
+                res = FR_NO_PATH; break;
             }
             dj->sclust = ld_clust(dj->fs, dir);
         }
@@ -2110,8 +2058,7 @@
     /* Get logical drive number from the path name */
     vol = p[0] - '0';                   /* Is there a drive number? */
     if (vol <= 9 && p[1] == ':') {      /* Found a drive number, get and strip it */
-        p += 2;
-        *path = p;              /* Return pointer to the path name */
+        p += 2; *path = p;              /* Return pointer to the path name */
     } else {                            /* No drive number is given */
 #if _FS_RPATH
         vol = CurrVol;                  /* Use current drive */
@@ -2215,7 +2162,7 @@
         if (!fs->n_rootdir) return FR_NO_FILESYSTEM;    /* (BPB_RootEntCnt must not be 0) */
         fs->dirbase = fs->fatbase + fasize;             /* Root directory start sector */
         szbfat = (fmt == FS_FAT16) ?                    /* (Required FAT size) */
-                 fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
+            fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
     }
     if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs))   /* (BPB_FATSz must not be less than required) */
         return FR_NO_FILESYSTEM;
@@ -2230,11 +2177,11 @@
         fs->fsi_flag = 0;
         fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo);
         if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK &&
-                LD_WORD(fs->win+BS_55AA) == 0xAA55 &&
-                LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 &&
-                LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) {
-            fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free);
-            fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count);
+            LD_WORD(fs->win+BS_55AA) == 0xAA55 &&
+            LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 &&
+            LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) {
+                fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free);
+                fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count);
         }
     }
 #endif
@@ -2382,7 +2329,8 @@
 #endif
                 mode |= FA_CREATE_ALWAYS;       /* File is created */
                 dir = dj.dir;                   /* New entry */
-            } else {                            /* Any object is already existing */
+            }
+            else {                              /* Any object is already existing */
                 if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) {    /* Cannot overwrite it (R/O or DIR) */
                     res = FR_DENIED;
                 } else {
@@ -2407,7 +2355,8 @@
                     }
                 }
             }
-        } else { /* Open an existing file */
+        }
+        else {  /* Open an existing file */
             if (res == FR_OK) {                     /* Follow succeeded */
                 if (dir[DIR_Attr] & AM_DIR) {       /* It is a directory */
                     res = FR_NO_FILE;
@@ -2450,8 +2399,7 @@
 #if _USE_FASTSEEK
             fp->cltbl = 0;                      /* Normal seek mode */
 #endif
-            fp->fs = dj.fs;
-            fp->id = dj.fs->id; /* Validate file object */
+            fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */
         }
     }
 
@@ -2490,7 +2438,7 @@
     if (btr > remain) btr = (UINT)remain;       /* Truncate btr by remaining bytes */
 
     for ( ;  btr;                               /* Repeat until all data read */
-            rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
+        rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
         if ((fp->fptr % SS(fp->fs)) == 0) {     /* On the sector boundary? */
             csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));    /* Sector offset in the cluster */
             if (!csect) {                       /* On the cluster boundary? */
@@ -2578,7 +2526,7 @@
     UINT wcnt, cc;
     const BYTE *wbuff = (const BYTE *)buff;
     BYTE csect;
-
+    bool need_sync = false;
 
     *bw = 0;    /* Clear write byte counter */
 
@@ -2591,7 +2539,7 @@
     if ((DWORD)(fp->fsize + btw) < fp->fsize) btw = 0;  /* File size cannot reach 4GB */
 
     for ( ;  btw;                           /* Repeat until all data written */
-            wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
+        wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
         if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */
             csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));    /* Sector offset in the cluster */
             if (!csect) {                   /* On the cluster boundary? */
@@ -2611,6 +2559,13 @@
                 if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
                 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
                 fp->clust = clst;           /* Update current cluster */
+
+#ifdef FLUSH_ON_NEW_CLUSTER
+                // We do not need to flush for the first cluster
+                if (fp->fptr != 0) {
+                    need_sync = true;
+                }
+#endif
             }
 #if _FS_TINY
             if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write-back sector cache */
@@ -2643,6 +2598,9 @@
                 }
 #endif
                 wcnt = SS(fp->fs) * cc;     /* Number of bytes transferred */
+#ifdef FLUSH_ON_NEW_SECTOR
+                need_sync = true;
+#endif
                 continue;
             }
 #if _FS_TINY
@@ -2653,8 +2611,8 @@
 #else
             if (fp->dsect != sect) {        /* Fill sector cache with file data */
                 if (fp->fptr < fp->fsize &&
-                        disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
-                    ABORT(fp->fs, FR_DISK_ERR);
+                    disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
+                        ABORT(fp->fs, FR_DISK_ERR);
             }
 #endif
             fp->dsect = sect;
@@ -2675,6 +2633,10 @@
     if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */
     fp->flag |= FA__WRITTEN;                        /* Set file change flag */
 
+    if (need_sync) {
+        f_sync (fp);
+    }
+
     LEAVE_FF(fp->fs, FR_OK);
 }
 
@@ -2869,8 +2831,7 @@
             if (_USE_LFN && *path) tp = path;
             for (n = 0; tp[n]; n++) ;
             if (i < n + 3) {
-                res = FR_NOT_ENOUGH_CORE;
-                break;
+                res = FR_NOT_ENOUGH_CORE; break;
             }
             while (n) path[--i] = tp[--n];
             path[--i] = '/';
@@ -2922,25 +2883,20 @@
 
         if (ofs == CREATE_LINKMAP) {    /* Create CLMT */
             tbl = fp->cltbl;
-            tlen = *tbl++;
-            ulen = 2;    /* Given table size and required table size */
+            tlen = *tbl++; ulen = 2;    /* Given table size and required table size */
             cl = fp->sclust;            /* Top of the chain */
             if (cl) {
                 do {
                     /* Get a fragment */
-                    tcl = cl;
-                    ncl = 0;
-                    ulen += 2;   /* Top, length and used items */
+                    tcl = cl; ncl = 0; ulen += 2;   /* Top, length and used items */
                     do {
-                        pcl = cl;
-                        ncl++;
+                        pcl = cl; ncl++;
                         cl = get_fat(fp->fs, cl);
                         if (cl <= 1) ABORT(fp->fs, FR_INT_ERR);
                         if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
                     } while (cl == pcl + 1);
                     if (ulen <= tlen) {     /* Store the length and top of the fragment */
-                        *tbl++ = ncl;
-                        *tbl++ = tcl;
+                        *tbl++ = ncl; *tbl++ = tcl;
                     }
                 } while (cl < fp->fs->n_fatent);    /* Repeat until end of chain */
             }
@@ -2978,22 +2934,22 @@
     } else
 #endif
 
-        /* Normal Seek */
+    /* Normal Seek */
     {
         DWORD clst, bcs, nsect, ifptr;
 
         if (ofs > fp->fsize                 /* In read-only mode, clip offset with the file size */
 #if !_FS_READONLY
-                && !(fp->flag & FA_WRITE)
+             && !(fp->flag & FA_WRITE)
 #endif
-           ) ofs = fp->fsize;
+            ) ofs = fp->fsize;
 
         ifptr = fp->fptr;
         fp->fptr = nsect = 0;
         if (ofs) {
             bcs = (DWORD)fp->fs->csize * SS(fp->fs);    /* Cluster size (byte) */
             if (ifptr > 0 &&
-                    (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
+                (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
                 fp->fptr = (ifptr - 1) & ~(bcs - 1);    /* start from the current cluster */
                 ofs -= fp->fptr;
                 clst = fp->clust;
@@ -3015,8 +2971,7 @@
                     if (fp->flag & FA_WRITE) {          /* Check if in write mode or not */
                         clst = create_chain(fp->fs, clst);  /* Force stretch if in write mode */
                         if (clst == 0) {                /* When disk gets full, clip file size */
-                            ofs = bcs;
-                            break;
+                            ofs = bcs; break;
                         }
                     } else
 #endif
@@ -3217,21 +3172,14 @@
                 clst = 2;
                 do {
                     stat = get_fat(fs, clst);
-                    if (stat == 0xFFFFFFFF) {
-                        res = FR_DISK_ERR;
-                        break;
-                    }
-                    if (stat == 1) {
-                        res = FR_INT_ERR;
-                        break;
-                    }
+                    if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }
+                    if (stat == 1) { res = FR_INT_ERR; break; }
                     if (stat == 0) n++;
                 } while (++clst < fs->n_fatent);
             } else {
                 clst = fs->n_fatent;
                 sect = fs->fatbase;
-                i = 0;
-                p = 0;
+                i = 0; p = 0;
                 do {
                     if (!i) {
                         res = move_window(fs, sect++);
@@ -3241,12 +3189,10 @@
                     }
                     if (fat == FS_FAT16) {
                         if (LD_WORD(p) == 0) n++;
-                        p += 2;
-                        i -= 2;
+                        p += 2; i -= 2;
                     } else {
                         if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++;
-                        p += 4;
-                        i -= 4;
+                        p += 4; i -= 4;
                     }
                 } while (--clst);
             }
@@ -3355,9 +3301,9 @@
                         res = dir_read(&sdj);
                         if (res == FR_OK        /* Not empty dir */
 #if _FS_RPATH
-                                || dclst == dj.fs->cdir /* Current dir */
+                        || dclst == dj.fs->cdir /* Current dir */
 #endif
-                           ) res = FR_DENIED;
+                        ) res = FR_DENIED;
                         if (res == FR_NO_FILE) res = FR_OK; /* Empty */
                     }
                 }
@@ -3419,8 +3365,7 @@
                 ST_DWORD(dir+DIR_WrtTime, tim);
                 st_clust(dir, dcl);
                 mem_cpy(dir+SZ_DIR, dir, SZ_DIR);   /* Create ".." entry */
-                dir[33] = '.';
-                pcl = dj.sclust;
+                dir[33] = '.'; pcl = dj.sclust;
                 if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase)
                     pcl = 0;
                 st_clust(dir+SZ_DIR, pcl);
@@ -3571,7 +3516,7 @@
                 res = follow_path(&djn, path_new);
                 if (res == FR_OK) res = FR_EXIST;       /* The new object name is already existing */
                 if (res == FR_NO_FILE) {                /* Is it a valid path and no name collision? */
-                    /* Start critical section that an interruption or error can cause cross-link */
+/* Start critical section that an interruption or error can cause cross-link */
                     res = dir_register(&djn);           /* Register the new entry */
                     if (res == FR_OK) {
                         dir = djn.dir;                  /* Copy object information except for name */
@@ -3598,7 +3543,7 @@
                                 res = sync(djo.fs);
                         }
                     }
-                    /* End critical section */
+/* End critical section */
                 }
             }
         }
@@ -3647,12 +3592,12 @@
     if (btr > remain) btr = (UINT)remain;           /* Truncate btr by remaining bytes */
 
     for ( ;  btr && (*func)(0, 0);                  /* Repeat until all data transferred or stream becomes busy */
-            fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) {
+        fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) {
         csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));    /* Sector offset in the cluster */
         if ((fp->fptr % SS(fp->fs)) == 0) {         /* On the sector boundary? */
             if (!csect) {                           /* On the cluster boundary? */
                 clst = (fp->fptr == 0) ?            /* On the top of the file? */
-                       fp->sclust : get_fat(fp->fs, fp->clust);
+                    fp->sclust : get_fat(fp->fs, fp->clust);
                 if (clst <= 1) ABORT(fp->fs, FR_INT_ERR);
                 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
                 fp->clust = clst;                   /* Update current cluster */
@@ -3780,18 +3725,13 @@
     /* Determine number of clusters and final check of validity of the FAT sub-type */
     n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au;
     if (   (fmt == FS_FAT16 && n_clst < MIN_FAT16)
-            || (fmt == FS_FAT32 && n_clst < MIN_FAT32))
+        || (fmt == FS_FAT32 && n_clst < MIN_FAT32))
         return FR_MKFS_ABORTED;
 
     switch (fmt) {  /* Determine system ID for partition table */
-        case FS_FAT12:
-            sys = 0x01;
-            break;
-        case FS_FAT16:
-            sys = (n_vol < 0x10000) ? 0x04 : 0x06;
-            break;
-        default:
-            sys = 0x0C;
+    case FS_FAT12:  sys = 0x01; break;
+    case FS_FAT16:  sys = (n_vol < 0x10000) ? 0x04 : 0x06; break;
+    default:        sys = 0x0C;
     }
 
     if (_MULTI_PARTITION && part) {
@@ -3900,8 +3840,7 @@
     {
         DWORD eb[2];
 
-        eb[0] = wsect;
-        eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;
+        eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;
         disk_ioctl(pdrv, CTRL_ERASE_SECTOR, eb);
     }
 #endif
@@ -3952,8 +3891,7 @@
 
     /* Create partition table */
     mem_set(buf, 0, _MAX_SS);
-    p = buf + MBR_Table;
-    b_cyl = 0;
+    p = buf + MBR_Table; b_cyl = 0;
     for (i = 0; i < 4; i++, p += SZ_PTE) {
         p_cyl = (szt[i] <= 100) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl;
         if (!p_cyl) continue;
@@ -3961,8 +3899,7 @@
         sz_part = (DWORD)sz_cyl * p_cyl;
         if (i == 0) {   /* Exclude first track of cylinder 0 */
             s_hd = 1;
-            s_part += 63;
-            sz_part -= 63;
+            s_part += 63; sz_part -= 63;
         } else {
             s_hd = 0;
         }
@@ -4144,12 +4081,10 @@
         w = f = 0;
         c = *str++;
         if (c == '0') {             /* Flag: '0' padding */
-            f = 1;
-            c = *str++;
+            f = 1; c = *str++;
         } else {
             if (c == '-') {         /* Flag: left justified */
-                f = 2;
-                c = *str++;
+                f = 2; c = *str++;
             }
         }
         while (IsDigit(c)) {        /* Precision */
@@ -4157,43 +4092,36 @@
             c = *str++;
         }
         if (c == 'l' || c == 'L') { /* Prefix: Size is long int */
-            f |= 4;
-            c = *str++;
+            f |= 4; c = *str++;
         }
         if (!c) break;
         d = c;
         if (IsLower(d)) d -= 0x20;
         switch (d) {                /* Type is... */
-            case 'S' :                  /* String */
-                p = va_arg(arp, TCHAR*);
-                for (j = 0; p[j]; j++) ;
-                chc = 0;
-                if (!(f & 2)) {
-                    while (j++ < w) chc += (cc = f_putc(' ', fil));
-                }
-                chc += (cc = f_puts(p, fil));
+        case 'S' :                  /* String */
+            p = va_arg(arp, TCHAR*);
+            for (j = 0; p[j]; j++) ;
+            chc = 0;
+            if (!(f & 2)) {
                 while (j++ < w) chc += (cc = f_putc(' ', fil));
-                if (cc != EOF) cc = chc;
-                continue;
-            case 'C' :                  /* Character */
-                cc = f_putc((TCHAR)va_arg(arp, int), fil);
-                continue;
-            case 'B' :                  /* Binary */
-                r = 2;
-                break;
-            case 'O' :                  /* Octal */
-                r = 8;
-                break;
-            case 'D' :                  /* Signed decimal */
-            case 'U' :                  /* Unsigned decimal */
-                r = 10;
-                break;
-            case 'X' :                  /* Hexdecimal */
-                r = 16;
-                break;
-            default:                    /* Unknown type (pass-through) */
-                cc = f_putc(c, fil);
-                continue;
+            }
+            chc += (cc = f_puts(p, fil));
+            while (j++ < w) chc += (cc = f_putc(' ', fil));
+            if (cc != EOF) cc = chc;
+            continue;
+        case 'C' :                  /* Character */
+            cc = f_putc((TCHAR)va_arg(arp, int), fil); continue;
+        case 'B' :                  /* Binary */
+            r = 2; break;
+        case 'O' :                  /* Octal */
+            r = 8; break;
+        case 'D' :                  /* Signed decimal */
+        case 'U' :                  /* Unsigned decimal */
+            r = 10; break;
+        case 'X' :                  /* Hexdecimal */
+            r = 16; break;
+        default:                    /* Unknown type (pass-through) */
+            cc = f_putc(c, fil); continue;
         }
 
         /* Get an argument and put it in numeral */
@@ -4204,18 +4132,15 @@
         }
         i = 0;
         do {
-            d = (TCHAR)(v % r);
-            v /= r;
+            d = (TCHAR)(v % r); v /= r;
             if (d > 9) d += (c == 'x') ? 0x27 : 0x07;
             s[i++] = d + '0';
         } while (v && i < sizeof s / sizeof s[0]);
         if (f & 8) s[i++] = '-';
-        j = i;
-        d = (f & 1) ? '0' : ' ';
+        j = i; d = (f & 1) ? '0' : ' ';
         res = 0;
         while (!(f & 2) && j++ < w) res += (cc = f_putc(d, fil));
-        do res += (cc = f_putc(s[--i], fil));
-        while(i);
+        do res += (cc = f_putc(s[--i], fil)); while(i);
         while (j++ < w) res += (cc = f_putc(' ', fil));
         if (cc != EOF) cc = res;
     }