From f0c65da00060fcc8c4ac9667d29b2d46557de42e Mon Sep 17 00:00:00 2001 From: Bill Greiman Date: Tue, 18 Dec 2018 07:11:05 -0800 Subject: [PATCH] Fix allocation algorithm --- examples/AnalogBinLogger/AnalogBinLogger.ino | 4 +- library.properties | 2 +- src/FatLib/FatApiConstants.h | 10 +++ src/FatLib/FatVolume.cpp | 71 +++++++++++--------- src/FatLib/FatVolume.h | 2 +- src/SdFat.h | 2 +- 6 files changed, 54 insertions(+), 37 deletions(-) diff --git a/examples/AnalogBinLogger/AnalogBinLogger.ino b/examples/AnalogBinLogger/AnalogBinLogger.ino index 48c1a61d..f104b9f3 100644 --- a/examples/AnalogBinLogger/AnalogBinLogger.ino +++ b/examples/AnalogBinLogger/AnalogBinLogger.ino @@ -436,7 +436,7 @@ void binaryToCsv() { return; } binFile.rewind(); - if (!binFile.read(&buf , 512) == 512) { + if (binFile.read(&buf , 512) != 512) { error("Read metadata failed"); } // Create a new csv file. @@ -517,7 +517,7 @@ void checkOverrun() { binFile.rewind(); Serial.println(); Serial.println(F("Checking overrun errors - type any character to stop")); - if (!binFile.read(&buf , 512) == 512) { + if (binFile.read(&buf , 512) != 512) { error("Read metadata failed"); } bn++; diff --git a/library.properties b/library.properties index 51e326e1..858ef098 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SdFat -version=1.0.7 +version=1.0.8 author=Bill Greiman maintainer=Bill Greiman sentence=FAT16/FAT32 file system for SD cards. diff --git a/src/FatLib/FatApiConstants.h b/src/FatLib/FatApiConstants.h index 33e4e64a..a8dd1104 100644 --- a/src/FatLib/FatApiConstants.h +++ b/src/FatLib/FatApiConstants.h @@ -24,6 +24,16 @@ */ #ifndef FatApiConstants_h #define FatApiConstants_h +// Temp fix for particle mesh. +#ifdef O_RDONLY +#undef O_RDONLY +#endif // O_RDONLY +#ifdef O_RDWR +#undef O_RDWR +#endif // O_RDWR +#ifdef O_WRONLY +#undef O_WRONLY +#endif // O_WRONLY //------------------------------------------------------------------------------ // use the gnu style oflag in open() /** open() oflag for reading */ diff --git a/src/FatLib/FatVolume.cpp b/src/FatLib/FatVolume.cpp index 76ed3647..6dd61cf8 100644 --- a/src/FatLib/FatVolume.cpp +++ b/src/FatLib/FatVolume.cpp @@ -71,14 +71,33 @@ bool FatCache::sync() { } //------------------------------------------------------------------------------ bool FatVolume::allocateCluster(uint32_t current, uint32_t* next) { - uint32_t find = current ? current : m_allocSearchStart; - uint32_t start = find; + uint32_t find; + bool setStart; + if (m_allocSearchStart < current) { + // Try to keep file contiguous. Start just after current cluster. + find = current; + setStart = false; + } else { + find = m_allocSearchStart; + setStart = true; + } while (1) { find++; - // If at end of FAT go to beginning of FAT. if (find > m_lastCluster) { - find = 2; + if (setStart) { + // Can't find space, checked all clusters. + DBG_FAIL_MACRO; + goto fail; + } + find = m_allocSearchStart; + setStart = true; + continue; } + if (find == current) { + // Can't find space, already searched clusters after current. + DBG_FAIL_MACRO; + goto fail; + } uint32_t f; int8_t fg = fatGet(find, &f); if (fg < 0) { @@ -88,27 +107,22 @@ bool FatVolume::allocateCluster(uint32_t current, uint32_t* next) { if (fg && f == 0) { break; } - if (find == start) { - // Can't find space checked all clusters. - DBG_FAIL_MACRO; - goto fail; - } } - // mark end of chain + if (setStart) { + m_allocSearchStart = find; + } + // Mark end of chain. if (!fatPutEOC(find)) { DBG_FAIL_MACRO; goto fail; } if (current) { - // link clusters + // Link clusters. if (!fatPut(current, find)) { DBG_FAIL_MACRO; goto fail; } - } else { - // Remember place for search start. - m_allocSearchStart = find; - } + } updateFreeClusterCount(-1); *next = find; return true; @@ -126,14 +140,14 @@ bool FatVolume::allocContiguous(uint32_t count, uint32_t* firstCluster) { // end of group uint32_t endCluster; // Start at cluster after last allocated cluster. - uint32_t startCluster = m_allocSearchStart; - endCluster = bgnCluster = startCluster + 1; + endCluster = bgnCluster = m_allocSearchStart + 1; // search the FAT for free clusters while (1) { - // If past end - start from beginning of FAT. if (endCluster > m_lastCluster) { - bgnCluster = endCluster = 2; + // Can't find space. + DBG_FAIL_MACRO; + goto fail; } uint32_t f; int8_t fg = fatGet(endCluster, &f); @@ -142,29 +156,22 @@ bool FatVolume::allocContiguous(uint32_t count, uint32_t* firstCluster) { goto fail; } if (f || fg == 0) { - // cluster in use try next cluster as bgnCluster - bgnCluster = endCluster + 1; - // don't update search start if unallocated clusters before endCluster. if (bgnCluster != endCluster) { setStart = false; } + // cluster in use try next cluster as bgnCluster + bgnCluster = endCluster + 1; } else if ((endCluster - bgnCluster + 1) == count) { // done - found space break; } - // Can't find space if all clusters checked. - if (startCluster == endCluster) { - DBG_FAIL_MACRO; - goto fail; - } endCluster++; } - // remember possible next free cluster + // Remember possible next free cluster. if (setStart) { - m_allocSearchStart = endCluster + 1; + m_allocSearchStart = endCluster; } - // mark end of chain if (!fatPutEOC(endCluster)) { DBG_FAIL_MACRO; @@ -355,8 +362,8 @@ bool FatVolume::freeChain(uint32_t cluster) { // Add one to count of free clusters. updateFreeClusterCount(1); - if (cluster < m_allocSearchStart) { - m_allocSearchStart = cluster; + if (cluster <= m_allocSearchStart) { + m_allocSearchStart = cluster - 1; } cluster = next; } while (fg); diff --git a/src/FatLib/FatVolume.h b/src/FatLib/FatVolume.h index 9b0227b7..2f15adab 100644 --- a/src/FatLib/FatVolume.h +++ b/src/FatLib/FatVolume.h @@ -255,7 +255,7 @@ class FatVolume { * * \param[in] n cluster number. * \param[out] v value of entry - * \return true for success or false for failure + * \return -1 error, 0 EOC, else 1. */ int8_t dbgFat(uint32_t n, uint32_t* v) { return fatGet(n, v); diff --git a/src/SdFat.h b/src/SdFat.h index 7dd75edf..2bd7ca93 100644 --- a/src/SdFat.h +++ b/src/SdFat.h @@ -37,7 +37,7 @@ #endif // INCLUDE_SDIOS //------------------------------------------------------------------------------ /** SdFat version */ -#define SD_FAT_VERSION "1.0.7" +#define SD_FAT_VERSION "1.0.8" //============================================================================== /** * \class SdBaseFile