From 80ccbaef0dd744dcad1ce7805292be60cb50c143 Mon Sep 17 00:00:00 2001 From: Martin Ayotte Date: Thu, 6 Aug 2015 13:32:02 -0400 Subject: [PATCH 1/6] fix dtostrf() issue using trackerj/odometer fixes along with my own fix for string null character ending --- cores/esp8266/core_esp8266_noniso.c | 37 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/cores/esp8266/core_esp8266_noniso.c b/cores/esp8266/core_esp8266_noniso.c index 40fe5e6dd..fecdd3362 100644 --- a/cores/esp8266/core_esp8266_noniso.c +++ b/cores/esp8266/core_esp8266_noniso.c @@ -162,46 +162,45 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) { strcpy(s, "ovf"); return s; } - char* out = s; - int signInt_Part = 1; - // Handle negative numbers if (number < 0.0) { - signInt_Part = -1; + *out = '-'; + ++out; number = -number; } - // calc left over digits - if (prec > 0) - { - width -= (prec + 1); - } - // Round correctly so that print(1.999, 2) prints as "2.00" - double rounding = 0.5; + // I optimized out most of the divisions + double rounding = 2.0; for (uint8_t i = 0; i < prec; ++i) - rounding /= 10.0; + rounding *= 10.0; + rounding = 1.0 / rounding; number += rounding; // Extract the integer part of the number and print it unsigned long int_part = (unsigned long)number; double remainder = number - (double)int_part; - out += sprintf(out, "%*ld", width, int_part * signInt_Part); + out += sprintf(out, "%d", int_part); // Print the decimal point, but only if there are digits beyond if (prec > 0) { *out = '.'; ++out; - - - for (unsigned char decShift = prec; decShift > 0; decShift--) { - remainder *= 10.0; - } - sprintf(out, "%0*d", prec, (int)remainder); } + // Print the digits after the decimal point + int8_t digit = 0; + while (prec-- > 0) { + remainder *= 10.0; + digit = (int8_t)remainder; + if (digit > 9) digit = 9; // insurance + *out = (char)('0' | digit); + ++out; + remainder -= digit; + } + *out = 0; return s; } From aa6965c1722327b665c49e337c69874ee56a4449 Mon Sep 17 00:00:00 2001 From: Martin Ayotte Date: Fri, 7 Aug 2015 11:06:06 -0400 Subject: [PATCH 2/6] fix the missing minimum width requirement --- cores/esp8266/core_esp8266_noniso.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/cores/esp8266/core_esp8266_noniso.c b/cores/esp8266/core_esp8266_noniso.c index fecdd3362..7fb4fd66a 100644 --- a/cores/esp8266/core_esp8266_noniso.c +++ b/cores/esp8266/core_esp8266_noniso.c @@ -165,8 +165,7 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) { char* out = s; // Handle negative numbers if (number < 0.0) { - *out = '-'; - ++out; + *out++ = '-'; number = -number; } @@ -186,9 +185,12 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) { // Print the decimal point, but only if there are digits beyond if (prec > 0) { - *out = '.'; - ++out; + *out++ = '.'; } + // make sure the string is terminated before mesuring it length + *out = 0; + // Reduce minimum width accordingly + width -= strlen(s); // Print the digits after the decimal point int8_t digit = 0; @@ -196,10 +198,13 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) { remainder *= 10.0; digit = (int8_t)remainder; if (digit > 9) digit = 9; // insurance - *out = (char)('0' | digit); - ++out; + *out++ = (char)('0' | digit); + width--; remainder -= digit; } + // add '0' to fill minimum width requirement + while (width-- > 0) *out++ = '0'; + // make sure the string is terminated *out = 0; return s; } From 659e467141a9738a883d5cc7e9670a4f1b8934f0 Mon Sep 17 00:00:00 2001 From: Martin Ayotte Date: Fri, 7 Aug 2015 21:55:25 -0400 Subject: [PATCH 3/6] padding should be done with space, not with '0' --- cores/esp8266/core_esp8266_noniso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp8266/core_esp8266_noniso.c b/cores/esp8266/core_esp8266_noniso.c index 7fb4fd66a..0b53583fd 100644 --- a/cores/esp8266/core_esp8266_noniso.c +++ b/cores/esp8266/core_esp8266_noniso.c @@ -203,7 +203,7 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) { remainder -= digit; } // add '0' to fill minimum width requirement - while (width-- > 0) *out++ = '0'; + while (width-- > 0) *out++ = ' '; // make sure the string is terminated *out = 0; return s; From 1cd99391c3b31e23a47955e922ffa7a6eac9f867 Mon Sep 17 00:00:00 2001 From: Martin Ayotte Date: Sat, 8 Aug 2015 15:25:08 -0400 Subject: [PATCH 4/6] integrate new version provided by Odometer --- cores/esp8266/core_esp8266_noniso.c | 72 +++++++++++++++++------------ 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/cores/esp8266/core_esp8266_noniso.c b/cores/esp8266/core_esp8266_noniso.c index 0b53583fd..d5b9d82f2 100644 --- a/cores/esp8266/core_esp8266_noniso.c +++ b/cores/esp8266/core_esp8266_noniso.c @@ -148,7 +148,8 @@ char* ultoa(unsigned long value, char* result, int base) { } char * dtostrf(double number, signed char width, unsigned char prec, char *s) { - + bool negative = false; + if (isnan(number)) { strcpy(s, "nan"); return s; @@ -158,14 +159,17 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) { return s; } - if (number > 4294967040.0 || number < -4294967040.0) { - strcpy(s, "ovf"); - return s; - } char* out = s; + + int fillme = width; // how many cells to fill for the integer part + if (prec > 0) { + fillme -= (prec+1); + } + // Handle negative numbers if (number < 0.0) { - *out++ = '-'; + negative = true; + fillme--; number = -number; } @@ -173,39 +177,47 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) { // I optimized out most of the divisions double rounding = 2.0; for (uint8_t i = 0; i < prec; ++i) - rounding *= 10.0; - rounding = 1.0 / rounding; + rounding *= 10.0; + rounding = 1.0 / rounding; number += rounding; - - // Extract the integer part of the number and print it - unsigned long int_part = (unsigned long)number; - double remainder = number - (double)int_part; - out += sprintf(out, "%d", int_part); - - // Print the decimal point, but only if there are digits beyond - if (prec > 0) { - *out++ = '.'; + + // Figure out how big our number really is + double tenpow = 1.0; + int digitcount = 1; + while (number >= 10.0 * tenpow) { + tenpow *= 10.0; + digitcount++; } - // make sure the string is terminated before mesuring it length - *out = 0; - // Reduce minimum width accordingly - width -= strlen(s); - - // Print the digits after the decimal point + + number /= tenpow; + fillme -= digitcount; + + // Pad unused cells with spaces + while (fillme-- > 0) { + *out++ = ' '; + } + + // Handle negative sign + if (negative) *out++ = '-'; + + // Print the digits, and if necessary, the decimal point + digitcount += prec; int8_t digit = 0; - while (prec-- > 0) { - remainder *= 10.0; - digit = (int8_t)remainder; + while (digitcount-- > 0) { + digit = (int8_t)number; if (digit > 9) digit = 9; // insurance *out++ = (char)('0' | digit); - width--; - remainder -= digit; + if ((digitcount == prec) && (prec > 0)) { + *out++ = '.'; + } + number -= digit; + number *= 10.0; } - // add '0' to fill minimum width requirement - while (width-- > 0) *out++ = ' '; + // make sure the string is terminated *out = 0; return s; } + From 568c48b065f3b05f46f4fad3f5dd70d2137be90b Mon Sep 17 00:00:00 2001 From: Martin Ayotte Date: Wed, 12 Aug 2015 22:12:22 -0400 Subject: [PATCH 5/6] add fileSize() method to Dir object --- cores/esp8266/FS.cpp | 8 ++++++++ cores/esp8266/FS.h | 1 + cores/esp8266/FSImpl.h | 1 + cores/esp8266/spiffs_api.cpp | 7 +++++++ 4 files changed, 17 insertions(+) diff --git a/cores/esp8266/FS.cpp b/cores/esp8266/FS.cpp index 7a13dcede..125ac527c 100644 --- a/cores/esp8266/FS.cpp +++ b/cores/esp8266/FS.cpp @@ -144,6 +144,14 @@ String Dir::fileName() { return _impl->fileName(); } +size_t Dir::fileSize() { + if (!_impl) { + return 0; + } + + return _impl->fileSize(); +} + bool Dir::next() { if (!_impl) { return false; diff --git a/cores/esp8266/FS.h b/cores/esp8266/FS.h index 3e1b1b4fc..4009bb2f2 100644 --- a/cores/esp8266/FS.h +++ b/cores/esp8266/FS.h @@ -78,6 +78,7 @@ public: File openFile(const char* mode); String fileName(); + size_t fileSize(); bool next(); protected: diff --git a/cores/esp8266/FSImpl.h b/cores/esp8266/FSImpl.h index 8e48a9fda..20d886e76 100644 --- a/cores/esp8266/FSImpl.h +++ b/cores/esp8266/FSImpl.h @@ -56,6 +56,7 @@ public: virtual ~DirImpl() { } virtual FileImplPtr openFile(OpenMode openMode, AccessMode accessMode) = 0; virtual const char* fileName() = 0; + virtual size_t fileSize() = 0; virtual bool next() = 0; }; diff --git a/cores/esp8266/spiffs_api.cpp b/cores/esp8266/spiffs_api.cpp index 157ae86bc..d9c7c618f 100644 --- a/cores/esp8266/spiffs_api.cpp +++ b/cores/esp8266/spiffs_api.cpp @@ -308,6 +308,13 @@ public: return (const char*) _dirent.name; } + size_t fileSize() override { + if (!_valid) + return 0; + + return _dirent.size; + } + bool next() override { spiffs_dirent* result = SPIFFS_readdir(&_dir, &_dirent); _valid = (result != nullptr); From c363b2d4f6f068d9521e875681552b0f673c73e2 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 14 Aug 2015 01:01:47 +0300 Subject: [PATCH 6/6] Update SPIFFS to 0.2-64-g15e5618 fix some exceptions due to unaligned memory access remove leftover changes from NodeMCU (SPIFFS_eof and SPIFFS_ftell) --- cores/esp8266/spiffs/README | 26 ++++- cores/esp8266/spiffs/spiffs.h | 90 +++++++++++++--- cores/esp8266/spiffs/spiffs_cache.c | 36 +++---- cores/esp8266/spiffs/spiffs_check.c | 100 ++++++++++-------- cores/esp8266/spiffs/spiffs_gc.c | 63 +++++++----- cores/esp8266/spiffs/spiffs_hydrogen.c | 137 +++++++++++++------------ cores/esp8266/spiffs/spiffs_nucleus.c | 89 ++++++++-------- cores/esp8266/spiffs/spiffs_nucleus.h | 28 ++++- cores/esp8266/spiffs_api.cpp | 2 +- 9 files changed, 355 insertions(+), 216 deletions(-) diff --git a/cores/esp8266/spiffs/README b/cores/esp8266/spiffs/README index 6efd656cb..673049d57 100644 --- a/cores/esp8266/spiffs/README +++ b/cores/esp8266/spiffs/README @@ -1,5 +1,5 @@ SPIFFS (SPI Flash File System) -V0.3.0 +V0.3.2 Copyright (c) 2013-2015 Peter Andersson (pelleplutt1976gmail.com) @@ -58,6 +58,30 @@ For testing and contributions, see the docs/IMPLEMENTING file. * HISTORY +0.3.2 + Limit cache size if too much cache is given (thanks pgeiem) + New feature - Controlled erase. #23 + SPIFFS_rename leaks file descriptors #28 (thanks benpicco) + moved dbg print defines in test framework to params_test.h + lseek should return the resulting offset (thanks hefloryd) + fixed type on dbg ifdefs + silence warning about signed/unsigned comparison when spiffs_obj_id is 32 bit (thanks benpicco) + Possible error in test_spiffs.c #21 (thanks yihcdaso-yeskela) + Cache might writethrough too often #16 + even moar testrunner updates + Test framework update and some added tests + Some thoughts for next gen + Test sigsevs when having too many sectors #13 (thanks alonewolfx2) + GC might be suboptimal #11 + Fix eternal readdir when objheader at last block, last entry + + New API functions: + SPIFFS_gc_quick - call a nonintrusive gc + SPIFFS_gc - call a full-scale intrusive gc + +0.3.1 + Removed two return warnings, was too triggerhappy on release + 0.3.0 Added existing namecheck when creating files Lots of static analysis bugs #6 diff --git a/cores/esp8266/spiffs/spiffs.h b/cores/esp8266/spiffs/spiffs.h index 376560436..7b59de9ed 100644 --- a/cores/esp8266/spiffs/spiffs.h +++ b/cores/esp8266/spiffs/spiffs.h @@ -9,7 +9,7 @@ #ifndef SPIFFS_H_ #define SPIFFS_H_ -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif @@ -47,6 +47,9 @@ extern "C" { #define SPIFFS_ERR_ERASE_FAIL -10027 #define SPIFFS_ERR_MAGIC_NOT_POSSIBLE -10028 +#define SPIFFS_ERR_NO_DELETED_BLOCKS -10029 + +#define SPIFFS_ERR_FILE_EXISTS -10030 #define SPIFFS_ERR_INTERNAL -10050 @@ -62,12 +65,25 @@ typedef u16_t spiffs_mode; // object type typedef u8_t spiffs_obj_type; +#if SPIFFS_HAL_CALLBACK_EXTRA +struct spiffs_t; + +/* spi read call function type */ +typedef s32_t (*spiffs_read)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *dst); +/* spi write call function type */ +typedef s32_t (*spiffs_write)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *src); +/* spi erase call function type */ +typedef s32_t (*spiffs_erase)(struct spiffs_t *fs, u32_t addr, u32_t size); + +#else // SPIFFS_HAL_CALLBACK_EXTRA + /* spi read call function type */ typedef s32_t (*spiffs_read)(u32_t addr, u32_t size, u8_t *dst); /* spi write call function type */ typedef s32_t (*spiffs_write)(u32_t addr, u32_t size, u8_t *src); /* spi erase call function type */ typedef s32_t (*spiffs_erase)(u32_t addr, u32_t size); +#endif // SPIFFS_HAL_CALLBACK_EXTRA /* file system check callback report operation */ typedef enum { @@ -88,21 +104,26 @@ typedef enum { } spiffs_check_report; /* file system check callback function */ +#if SPIFFS_HAL_CALLBACK_EXTRA +typedef void (*spiffs_check_callback)(struct spiffs_t *fs, spiffs_check_type type, spiffs_check_report report, + u32_t arg1, u32_t arg2); +#else // SPIFFS_HAL_CALLBACK_EXTRA typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report, u32_t arg1, u32_t arg2); +#endif // SPIFFS_HAL_CALLBACK_EXTRA #ifndef SPIFFS_DBG #define SPIFFS_DBG(...) \ print(__VA_ARGS__) #endif #ifndef SPIFFS_GC_DBG -#define SPIFFS_GC_DBG(...) c_printf(__VA_ARGS__) +#define SPIFFS_GC_DBG(...) printf(__VA_ARGS__) #endif #ifndef SPIFFS_CACHE_DBG -#define SPIFFS_CACHE_DBG(...) c_printf(__VA_ARGS__) +#define SPIFFS_CACHE_DBG(...) printf(__VA_ARGS__) #endif #ifndef SPIFFS_CHECK_DBG -#define SPIFFS_CHECK_DBG(...) c_printf(__VA_ARGS__) +#define SPIFFS_CHECK_DBG(...) printf(__VA_ARGS__) #endif /* Any write to the filehandle is appended to end of the file */ @@ -119,6 +140,8 @@ typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_repor #define SPIFFS_RDWR (SPIFFS_RDONLY | SPIFFS_WRONLY) /* Any writes to the filehandle will never be cached */ #define SPIFFS_DIRECT (1<<5) +/* If SPIFFS_CREAT and SPIFFS_EXCL are set, SPIFFS_open() shall fail if the file exists */ +#define SPIFFS_EXCL (1<<6) #define SPIFFS_SEEK_SET (0) #define SPIFFS_SEEK_CUR (1) @@ -166,7 +189,7 @@ typedef struct { #endif } spiffs_config; -typedef struct { +typedef struct spiffs_t { // file system configuration spiffs_config cfg; // number of logical blocks @@ -224,6 +247,8 @@ typedef struct { // mounted flag u8_t mounted; + // user data + void *user_data; // config magic u32_t config_magic; } spiffs; @@ -387,7 +412,7 @@ s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh); * @param fs the file system struct * @param fh the filehandle of the file to close */ -void SPIFFS_close(spiffs *fs, spiffs_file fh); +s32_t SPIFFS_close(spiffs *fs, spiffs_file fh); /** * Renames a file @@ -440,7 +465,6 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e); */ s32_t SPIFFS_check(spiffs *fs); - /** * Returns number of total bytes available and number of used bytes. * This is an estimation, and depends on if there a many files with little @@ -465,27 +489,60 @@ s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used); * SPIFFS_format. * If SPIFFS_mount fails, SPIFFS_format can be called directly without calling * SPIFFS_unmount first. + * + * @param fs the file system struct */ s32_t SPIFFS_format(spiffs *fs); /** * Returns nonzero if spiffs is mounted, or zero if unmounted. + * @param fs the file system struct */ u8_t SPIFFS_mounted(spiffs *fs); /** - * Check if EOF reached. - * @param fs the file system struct - * @param fh the filehandle of the file to check + * Tries to find a block where most or all pages are deleted, and erase that + * block if found. Does not care for wear levelling. Will not move pages + * around. + * If parameter max_free_pages are set to 0, only blocks with only deleted + * pages will be selected. + * + * NB: the garbage collector is automatically called when spiffs needs free + * pages. The reason for this function is to give possibility to do background + * tidying when user knows the system is idle. + * + * Use with care. + * + * Setting max_free_pages to anything larger than zero will eventually wear + * flash more as a block containing free pages can be erased. + * + * Will set err_no to SPIFFS_OK if a block was found and erased, + * SPIFFS_ERR_NO_DELETED_BLOCK if no matching block was found, + * or other error. + * + * @param fs the file system struct + * @param max_free_pages maximum number allowed free pages in block */ -s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh); +s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages); /** - * Get the current position of the data pointer. + * Will try to make room for given amount of bytes in the filesystem by moving + * pages and erasing blocks. + * If it is physically impossible, err_no will be set to SPIFFS_ERR_FULL. If + * there already is this amount (or more) of free space, SPIFFS_gc will + * silently return. It is recommended to call SPIFFS_info before invoking + * this method in order to determine what amount of bytes to give. + * + * NB: the garbage collector is automatically called when spiffs needs free + * pages. The reason for this function is to give possibility to do background + * tidying when user knows the system is idle. + * + * Use with care. + * * @param fs the file system struct - * @param fh the filehandle of the open file + * @param size amount of bytes that should be freed */ -s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh); +s32_t SPIFFS_gc(spiffs *fs, u32_t size); #if SPIFFS_TEST_VISUALISATION /** @@ -511,8 +568,9 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages); #endif #endif - -#ifdef __cplusplus +#if SPIFFS_CACHE +#endif +#if defined(__cplusplus) } #endif diff --git a/cores/esp8266/spiffs/spiffs_cache.c b/cores/esp8266/spiffs/spiffs_cache.c index 5bfe51e86..ea9bc82c5 100644 --- a/cores/esp8266/spiffs/spiffs_cache.c +++ b/cores/esp8266/spiffs/spiffs_cache.c @@ -20,7 +20,7 @@ static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix) if ((cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && cp->pix == pix ) { - SPIFFS_CACHE_DBG("CACHE_GET: have cache page %d for %04x\n", i, pix); + SPIFFS_CACHE_DBG("CACHE_GET: have cache page %i for %04x\n", i, pix); cp->last_access = cache->last_access; return cp; } @@ -39,16 +39,16 @@ static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) { (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && (cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) { u8_t *mem = spiffs_get_cache_page(fs, cache, ix); - res = fs->cfg.hal_write_f(SPIFFS_PAGE_TO_PADDR(fs, cp->pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem); + res = SPIFFS_HAL_WRITE(fs, SPIFFS_PAGE_TO_PADDR(fs, cp->pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem); } cp->flags = 0; cache->cpage_use_map &= ~(1 << ix); if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) { - SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %d objid %04x\n", ix, cp->obj_id); + SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %i objid %04x\n", ix, cp->obj_id); } else { - SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %d pix %04x\n", ix, cp->pix); + SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %i pix %04x\n", ix, cp->pix); } } @@ -98,7 +98,7 @@ static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) { spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); cache->cpage_use_map |= (1<last_access = cache->last_access; - SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page %d\n", i); + SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page %i\n", i); return cp; } } @@ -137,10 +137,7 @@ s32_t spiffs_phys_rd( } else { if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) { // for second layer lookup functions, we do not cache in order to prevent shredding - return fs->cfg.hal_read_f( - addr , - len, - dst); + return SPIFFS_HAL_READ(fs, addr, len, dst); } #if SPIFFS_CACHE_STATS fs->cache_misses++; @@ -151,8 +148,7 @@ s32_t spiffs_phys_rd( cp->flags = SPIFFS_CACHE_FLAG_WRTHRU; cp->pix = SPIFFS_PADDR_TO_PAGE(fs, addr); } - - s32_t res2 = fs->cfg.hal_read_f( + s32_t res2 = SPIFFS_HAL_READ(fs, addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr), SPIFFS_CFG_LOG_PAGE_SZ(fs), spiffs_get_cache_page(fs, cache, cp->ix)); @@ -161,7 +157,7 @@ s32_t spiffs_phys_rd( } } u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); - c_memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); + memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); return res; } @@ -186,24 +182,24 @@ s32_t spiffs_phys_wr( (op & SPIFFS_OP_TYPE_MASK) != SPIFFS_OP_T_OBJ_LU) { // page is being deleted, wipe from cache - unless it is a lookup page spiffs_cache_page_free(fs, cp->ix, 0); - return fs->cfg.hal_write_f(addr, len, src); + return SPIFFS_HAL_WRITE(fs, addr, len, src); } u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); - c_memcpy(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len); + memcpy(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len); cache->last_access++; cp->last_access = cache->last_access; - if (cp->flags && SPIFFS_CACHE_FLAG_WRTHRU) { + if (cp->flags & SPIFFS_CACHE_FLAG_WRTHRU) { // page is being updated, no write-cache, just pass thru - return fs->cfg.hal_write_f(addr, len, src); + return SPIFFS_HAL_WRITE(fs, addr, len, src); } else { return SPIFFS_OK; } } else { // no cache page, no write cache - just write thru - return fs->cfg.hal_write_f(addr, len, src); + return SPIFFS_HAL_WRITE(fs, addr, len, src); } } @@ -282,17 +278,17 @@ void spiffs_cache_init(spiffs *fs) { } spiffs_cache cache; - c_memset(&cache, 0, sizeof(spiffs_cache)); + memset(&cache, 0, sizeof(spiffs_cache)); cache.cpage_count = cache_entries; cache.cpages = (u8_t *)((u8_t *)fs->cache + sizeof(spiffs_cache)); cache.cpage_use_map = 0xffffffff; cache.cpage_use_mask = cache_mask; - c_memcpy(fs->cache, &cache, sizeof(spiffs_cache)); + memcpy(fs->cache, &cache, sizeof(spiffs_cache)); spiffs_cache *c = spiffs_get_cache(fs); - c_memset(c->cpages, 0, c->cpage_count * SPIFFS_CACHE_PAGE_SIZE(fs)); + memset(c->cpages, 0, c->cpage_count * SPIFFS_CACHE_PAGE_SIZE(fs)); c->cpage_use_map &= ~(c->cpage_use_mask); for (i = 0; i < cache.cpage_count; i++) { diff --git a/cores/esp8266/spiffs/spiffs_check.c b/cores/esp8266/spiffs/spiffs_check.c index 50bbb5c89..180ce345a 100644 --- a/cores/esp8266/spiffs/spiffs_check.c +++ b/cores/esp8266/spiffs/spiffs_check.c @@ -22,6 +22,19 @@ #include "spiffs.h" #include "spiffs_nucleus.h" + +#if SPIFFS_HAL_CALLBACK_EXTRA +#define CHECK_CB(_fs, _type, _rep, _arg1, _arg2) \ + do { \ + if ((_fs)->check_cb_f) (_fs)->check_cb_f((_fs), (_type), (_rep), (_arg1), (_arg2)); \ + } while (0) +#else +#define CHECK_CB(_fs, _type, _rep, _arg1, _arg2) \ + do { \ + if ((_fs)->check_cb_f) (_fs)->check_cb_f((_type), (_rep), (_arg1), (_arg2)); \ + } while (0) +#endif + //--------------------------------------- // Look up consistency @@ -190,13 +203,13 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("LU: FIXUP: index bad %d, cannot mend!\n", res); + SPIFFS_CHECK_DBG("LU: FIXUP: index bad %i, cannot mend!\n", res); res = spiffs_page_delete(fs, new_pix); SPIFFS_CHECK_RES(res); res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); } else { - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, p_hdr->obj_id, p_hdr->span_ix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, p_hdr->obj_id, p_hdr->span_ix); } SPIFFS_CHECK_RES(res); } @@ -216,7 +229,7 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s SPIFFS_CHECK_DBG("LU: FIXUP: ix page with data not found elsewhere, rewriting %04x to new page %04x\n", cur_pix, new_pix); SPIFFS_CHECK_RES(res); *reload_lu = 1; - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); } } else { SPIFFS_CHECK_RES(res); @@ -249,12 +262,12 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("LU: FIXUP: index bad %d, cannot mend!\n", res); + SPIFFS_CHECK_DBG("LU: FIXUP: index bad %i, cannot mend!\n", res); res = spiffs_page_delete(fs, new_pix); SPIFFS_CHECK_RES(res); res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); *reload_lu = 1; - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); } SPIFFS_CHECK_RES(res); } @@ -306,7 +319,7 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s new_ph.obj_id = p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG; res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page %04x as %04x to pix %04x\n", cur_pix, new_ph.obj_id, new_pix); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); SPIFFS_CHECK_RES(res); *reload_lu = 1; } else if ((objix_pix_ph && data_pix_ph && data_pix_lu && objix_pix_lu == 0) || @@ -315,7 +328,7 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s // rewrite as obj_id_lu new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page %04x as %04x\n", cur_pix, new_ph.obj_id); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); SPIFFS_CHECK_RES(res); *reload_lu = 1; @@ -353,7 +366,7 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s // if only data page exists, make this page index if (data_pix && objix_pix_d == 0) { SPIFFS_CHECK_DBG("LU: FIXUP: other data page exists, make this index\n"); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, lu_obj_id, p_hdr->span_ix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, lu_obj_id, p_hdr->span_ix); spiffs_page_header new_ph; spiffs_page_ix new_pix; new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); @@ -369,7 +382,7 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s // if only index exists, make data page if (data_pix == 0 && objix_pix_d) { SPIFFS_CHECK_DBG("LU: FIXUP: other index page exists, make this data\n"); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, lu_obj_id, p_hdr->span_ix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, lu_obj_id, p_hdr->span_ix); spiffs_page_header new_ph; spiffs_page_ix new_pix; new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); @@ -406,7 +419,7 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s // page referenced by object index but not final // just finalize SPIFFS_CHECK_DBG("LU: FIXUP: unfinalized page is referred, finalizing\n"); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); u8_t flags = 0xff & ~SPIFFS_PH_FLAG_FINAL; res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags), @@ -418,7 +431,7 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s if (delete_page) { SPIFFS_CHECK_DBG("LU: FIXUP: deleting page %04x\n", cur_pix); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); res = spiffs_page_delete(fs, cur_pix); SPIFFS_CHECK_RES(res); } @@ -434,7 +447,7 @@ static s32_t spiffs_lookup_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_bloc spiffs_page_header p_hdr; spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, (cur_block * 256)/fs->block_count, 0); // load header @@ -460,7 +473,7 @@ s32_t spiffs_lookup_consistency_check(spiffs *fs, u8_t check_all_objects) { (void)check_all_objects; s32_t res = SPIFFS_OK; - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 0, 0); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 0, 0); res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_lookup_check_v, 0, 0, 0, 0); @@ -469,10 +482,10 @@ s32_t spiffs_lookup_consistency_check(spiffs *fs, u8_t check_all_objects) { } if (res != SPIFFS_OK) { - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_ERROR, res, 0); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_ERROR, res, 0); } - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 256, 0); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 256, 0); return res; } @@ -501,19 +514,22 @@ static s32_t spiffs_page_consistency_check_i(spiffs *fs) { while (pix_offset < SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) { // set this flag to abort all checks and rescan the page range u8_t restart = 0; - c_memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); spiffs_block_ix cur_block = 0; // build consistency bitmap for id range traversing all blocks while (!restart && cur_block < fs->block_count) { - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, (pix_offset*256)/(SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) + ((((cur_block * pages_per_scan * 256)/ (SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count))) / fs->block_count), 0); - // traverse each page except for lookup pages spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_PAGES(fs) + SPIFFS_PAGES_PER_BLOCK(fs) * cur_block; while (!restart && cur_pix < SPIFFS_PAGES_PER_BLOCK(fs) * (cur_block+1)) { + //if ((cur_pix & 0xff) == 0) + // SPIFFS_CHECK_DBG("PA: processing pix %08x, block %08x of pix %08x, block %08x\n", + // cur_pix, cur_block, SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count, fs->block_count); + // read header spiffs_page_header p_hdr; res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, @@ -597,12 +613,12 @@ static s32_t spiffs_page_consistency_check_i(spiffs *fs) { data_spix_offset + i, data_pix, cur_pix); if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad %d, cannot mend - delete object\n", res); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, objix_p_hdr->obj_id, 0); + SPIFFS_CHECK_DBG("PA: FIXUP: index bad %i, cannot mend - delete object\n", res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, objix_p_hdr->obj_id, 0); // delete file res = spiffs_page_delete(fs, cur_pix); } else { - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, objix_p_hdr->obj_id, objix_p_hdr->span_ix); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, objix_p_hdr->obj_id, objix_p_hdr->span_ix); } SPIFFS_CHECK_RES(res); restart = 1; @@ -636,7 +652,7 @@ static s32_t spiffs_page_consistency_check_i(spiffs *fs) { if (data_pix == 0) { // not found, this index is badly borked SPIFFS_CHECK_DBG("PA: FIXUP: index bad, delete object id %04x\n", p_hdr.obj_id); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); SPIFFS_CHECK_RES(res); break; @@ -647,11 +663,11 @@ static s32_t spiffs_page_consistency_check_i(spiffs *fs) { res = spiffs_rewrite_index(fs, p_hdr.obj_id, data_spix_offset + i, data_pix, cur_pix); if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad %d, cannot mend!\n", res); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + SPIFFS_CHECK_DBG("PA: FIXUP: index bad %i, cannot mend!\n", res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); } else { - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); } SPIFFS_CHECK_RES(res); restart = 1; @@ -669,7 +685,7 @@ static s32_t spiffs_page_consistency_check_i(spiffs *fs) { // the object which is referring to this page SPIFFS_CHECK_DBG("PA: FIXUP: removing object %04x and page %04x\n", p_hdr.obj_id, cur_pix); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); SPIFFS_CHECK_RES(res); // extra precaution, delete this page also @@ -763,20 +779,20 @@ static s32_t spiffs_page_consistency_check_i(spiffs *fs) { res = spiffs_rewrite_index(fs, p_hdr.obj_id, p_hdr.span_ix, cur_pix, objix_pix); if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad %d, cannot mend!\n", res); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + SPIFFS_CHECK_DBG("PA: FIXUP: index bad %i, cannot mend!\n", res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); res = spiffs_page_delete(fs, cur_pix); SPIFFS_CHECK_RES(res); res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); } else { - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); } SPIFFS_CHECK_RES(res); restart = 1; continue; } else if (delete_page) { SPIFFS_CHECK_DBG("PA: FIXUP: deleting page %04x\n", cur_pix); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); res = spiffs_page_delete(fs, cur_pix); } SPIFFS_CHECK_RES(res); @@ -818,6 +834,8 @@ static s32_t spiffs_page_consistency_check_i(spiffs *fs) { } } } + + SPIFFS_CHECK_DBG("PA: processed %04x, restart %i\n", pix_offset, restart); // next page range if (!restart) { pix_offset += pages_per_scan; @@ -828,12 +846,12 @@ static s32_t spiffs_page_consistency_check_i(spiffs *fs) { // Checks consistency amongst all pages and fixes irregularities s32_t spiffs_page_consistency_check(spiffs *fs) { - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 0, 0); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 0, 0); s32_t res = spiffs_page_consistency_check_i(fs); if (res != SPIFFS_OK) { - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_ERROR, res, 0); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_ERROR, res, 0); } - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 256, 0); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 256, 0); return res; } @@ -862,7 +880,7 @@ static s32_t spiffs_object_index_consistency_check_v(spiffs *fs, spiffs_obj_id o u32_t *log_ix = (u32_t *)user_p; spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, (cur_block * 256)/fs->block_count, 0); if (obj_id != SPIFFS_OBJ_ID_FREE && obj_id != SPIFFS_OBJ_ID_DELETED && (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) { @@ -879,7 +897,7 @@ static s32_t spiffs_object_index_consistency_check_v(spiffs *fs, spiffs_obj_id o (SPIFFS_PH_FLAG_DELET)) { SPIFFS_CHECK_DBG("IX: pix %04x, obj id:%04x spix:%04x header not fully deleted - deleting\n", cur_pix, obj_id, p_hdr.span_ix); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_PAGE, cur_pix, obj_id); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_PAGE, cur_pix, obj_id); res = spiffs_page_delete(fs, cur_pix); SPIFFS_CHECK_RES(res); return res_c; @@ -935,7 +953,7 @@ static s32_t spiffs_object_index_consistency_check_v(spiffs *fs, spiffs_obj_id o if (delete) { SPIFFS_CHECK_DBG("IX: FIXUP: pix %04x, obj id:%04x spix:%04x is orphan index - deleting\n", cur_pix, obj_id, p_hdr.span_ix); - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_ORPHANED_INDEX, cur_pix, obj_id); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_ORPHANED_INDEX, cur_pix, obj_id); res = spiffs_page_delete(fs, cur_pix); SPIFFS_CHECK_RES(res); } @@ -956,18 +974,18 @@ s32_t spiffs_object_index_consistency_check(spiffs *fs) { // indicating whether they can be reached or not. Acting as a fifo if object ids cannot fit. // In the temporary object index memory, SPIFFS_OBJ_ID_IX_FLAG bit is used to indicate // a reachable/unreachable object id. - c_memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); u32_t obj_id_log_ix = 0; - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 0, 0); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 0, 0); res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_object_index_consistency_check_v, 0, &obj_id_log_ix, 0, 0); if (res == SPIFFS_VIS_END) { res = SPIFFS_OK; } if (res != SPIFFS_OK) { - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_INDEX, SPIFFS_CHECK_ERROR, res, 0); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_ERROR, res, 0); } - if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 256, 0); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 256, 0); return res; } diff --git a/cores/esp8266/spiffs/spiffs_gc.c b/cores/esp8266/spiffs/spiffs_gc.c index fff659e3a..b60d7d3f2 100644 --- a/cores/esp8266/spiffs/spiffs_gc.c +++ b/cores/esp8266/spiffs/spiffs_gc.c @@ -9,7 +9,7 @@ static s32_t spiffs_gc_erase_block( spiffs_block_ix bix) { s32_t res; - SPIFFS_GC_DBG("gc: erase block %d\n", bix); + SPIFFS_GC_DBG("gc: erase block %i\n", bix); res = spiffs_erase_block(fs, bix); SPIFFS_CHECK_RES(res); @@ -28,7 +28,7 @@ static s32_t spiffs_gc_erase_block( // the block is erased. Compared to the non-quick gc, the quick one ensures // that no updates are needed on existing objects on pages that are erased. s32_t spiffs_gc_quick( - spiffs *fs) { + spiffs *fs, u16_t max_free_pages) { s32_t res = SPIFFS_OK; u32_t blocks = fs->block_count; spiffs_block_ix cur_block = 0; @@ -47,6 +47,7 @@ s32_t spiffs_gc_quick( // check each block while (res == SPIFFS_OK && blocks--) { u16_t deleted_pages_in_block = 0; + u16_t free_pages_in_block = 0; int obj_lookup_page = 0; // check each object lookup page @@ -63,9 +64,12 @@ s32_t spiffs_gc_quick( deleted_pages_in_block++; } else if (obj_id == SPIFFS_OBJ_ID_FREE) { // kill scan, go for next block - obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); - res = 1; // kill object lu loop - break; + free_pages_in_block++; + if (free_pages_in_block > max_free_pages) { + obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); + res = 1; // kill object lu loop + break; + } } else { // kill scan, go for next block obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); @@ -78,7 +82,9 @@ s32_t spiffs_gc_quick( } // per object lookup page if (res == 1) res = SPIFFS_OK; - if (res == SPIFFS_OK && deleted_pages_in_block == SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) { + if (res == SPIFFS_OK && + deleted_pages_in_block + free_pages_in_block == SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs) && + free_pages_in_block <= max_free_pages) { // found a fully deleted block fs->stats_p_deleted -= deleted_pages_in_block; res = spiffs_gc_erase_block(fs, cur_block); @@ -90,10 +96,13 @@ s32_t spiffs_gc_quick( cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); } // per block + if (res == SPIFFS_OK) { + res = SPIFFS_ERR_NO_DELETED_BLOCKS; + } return res; } -// Checks if garbaga collecting is necessary. If so a candidate block is found, +// Checks if garbage collecting is necessary. If so a candidate block is found, // cleansed and erased s32_t spiffs_gc_check( spiffs *fs, @@ -111,16 +120,16 @@ s32_t spiffs_gc_check( u32_t needed_pages = (len + SPIFFS_DATA_PAGE_SIZE(fs) - 1) / SPIFFS_DATA_PAGE_SIZE(fs); // if (fs->free_blocks <= 2 && (s32_t)needed_pages > free_pages) { -// SPIFFS_GC_DBG("gc: full freeblk:%d needed:%d free:%d dele:%d\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); +// SPIFFS_GC_DBG("gc: full freeblk:%i needed:%i free:%i dele:%i\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); // return SPIFFS_ERR_FULL; // } if ((s32_t)needed_pages > (s32_t)(free_pages + fs->stats_p_deleted)) { - SPIFFS_GC_DBG("gc_check: full freeblk:%d needed:%d free:%d dele:%d\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); + SPIFFS_GC_DBG("gc_check: full freeblk:%i needed:%i free:%i dele:%i\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); return SPIFFS_ERR_FULL; } do { - SPIFFS_GC_DBG("\ngc_check #%d: run gc free_blocks:%d pfree:%d pallo:%d pdele:%d [%d] len:%d of %d\n", + SPIFFS_GC_DBG("\ngc_check #%i: run gc free_blocks:%i pfree:%i pallo:%i pdele:%i [%i] len:%i of %i\n", tries, fs->free_blocks, free_pages, fs->stats_p_allocated, fs->stats_p_deleted, (free_pages+fs->stats_p_allocated+fs->stats_p_deleted), len, free_pages*SPIFFS_DATA_PAGE_SIZE(fs)); @@ -141,13 +150,13 @@ s32_t spiffs_gc_check( #endif cand = cands[0]; fs->cleaning = 1; - //c_printf("gcing: cleaning block %d\n", cand); + //printf("gcing: cleaning block %i\n", cand); res = spiffs_gc_clean(fs, cand); fs->cleaning = 0; if (res < 0) { - SPIFFS_GC_DBG("gc_check: cleaning block %d, result %d\n", cand, res); + SPIFFS_GC_DBG("gc_check: cleaning block %i, result %i\n", cand, res); } else { - SPIFFS_GC_DBG("gc_check: cleaning block %d, result %d\n", cand, res); + SPIFFS_GC_DBG("gc_check: cleaning block %i, result %i\n", cand, res); } SPIFFS_CHECK_RES(res); @@ -177,7 +186,7 @@ s32_t spiffs_gc_check( res = SPIFFS_ERR_FULL; } - SPIFFS_GC_DBG("gc_check: finished, %d dirty, blocks %d free, %d pages free, %d tries, res %d\n", + SPIFFS_GC_DBG("gc_check: finished, %i dirty, blocks %i free, %i pages free, %i tries, res %i\n", fs->stats_p_allocated + fs->stats_p_deleted, fs->free_blocks, free_pages, tries, res); @@ -215,7 +224,7 @@ s32_t spiffs_gc_erase_page_stats( } // per entry obj_lookup_page++; } // per object lookup page - SPIFFS_GC_DBG("gc_check: wipe pallo:%d pdele:%d\n", allo, dele); + SPIFFS_GC_DBG("gc_check: wipe pallo:%i pdele:%i\n", allo, dele); fs->stats_p_allocated -= allo; fs->stats_p_deleted -= dele; return res; @@ -237,13 +246,18 @@ s32_t spiffs_gc_find_candidate( // using fs->work area as sorted candidate memory, (spiffs_block_ix)cand_bix/(s32_t)score int max_candidates = MIN(fs->block_count, (SPIFFS_CFG_LOG_PAGE_SZ(fs)-8)/(sizeof(spiffs_block_ix) + sizeof(s32_t))); *candidate_count = 0; - c_memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); // divide up work area into block indices and scores - // todo alignment? spiffs_block_ix *cand_blocks = (spiffs_block_ix *)fs->work; s32_t *cand_scores = (s32_t *)(fs->work + max_candidates * sizeof(spiffs_block_ix)); + // align cand_scores on s32_t boundary +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" + cand_scores = (s32_t*)(((u32_t)cand_scores + sizeof(s32_t) - 1) & ~(sizeof(s32_t) - 1)); +#pragma GCC diagnostic pop + *block_candidates = cand_blocks; int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); @@ -301,7 +315,7 @@ s32_t spiffs_gc_find_candidate( used_pages_in_block * SPIFFS_GC_HEUR_W_USED + erase_age * (fs_crammed ? 0 : SPIFFS_GC_HEUR_W_ERASE_AGE); int cand_ix = 0; - SPIFFS_GC_DBG("gc_check: bix:%d del:%d use:%d score:%d\n", cur_block, deleted_pages_in_block, used_pages_in_block, score); + SPIFFS_GC_DBG("gc_check: bix:%i del:%i use:%i score:%i\n", cur_block, deleted_pages_in_block, used_pages_in_block, score); while (cand_ix < max_candidates) { if (cand_blocks[cand_ix] == (spiffs_block_ix)-1) { cand_blocks[cand_ix] = cur_block; @@ -370,20 +384,20 @@ s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) { spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - SPIFFS_GC_DBG("gc_clean: cleaning block %d\n", bix); + SPIFFS_GC_DBG("gc_clean: cleaning block %i\n", bix); - c_memset(&gc, 0, sizeof(spiffs_gc)); + memset(&gc, 0, sizeof(spiffs_gc)); gc.state = FIND_OBJ_DATA; if (fs->free_cursor_block_ix == bix) { // move free cursor to next block, cannot use free pages from the block we want to clean fs->free_cursor_block_ix = (bix+1)%fs->block_count; fs->free_cursor_obj_lu_entry = 0; - SPIFFS_GC_DBG("gc_clean: move free cursor to block %d\n", fs->free_cursor_block_ix); + SPIFFS_GC_DBG("gc_clean: move free cursor to block %i\n", fs->free_cursor_block_ix); } while (res == SPIFFS_OK && gc.state != FINISHED) { - SPIFFS_GC_DBG("gc_clean: state = %d entry:%d\n", gc.state, cur_entry); + SPIFFS_GC_DBG("gc_clean: state = %i entry:%i\n", gc.state, cur_entry); gc.obj_id_found = 0; // scan through lookup pages @@ -406,7 +420,7 @@ s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) { case FIND_OBJ_DATA: if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0)) { - SPIFFS_GC_DBG("gc_clean: FIND_DATA state:%d - found obj id %04x\n", gc.state, obj_id); + SPIFFS_GC_DBG("gc_clean: FIND_DATA state:%i - found obj id %04x\n", gc.state, obj_id); gc.obj_id_found = 1; gc.cur_obj_id = obj_id; scan = 0; @@ -550,9 +564,10 @@ s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) { cur_entry = 0; break; } - SPIFFS_GC_DBG("gc_clean: state-> %d\n", gc.state); + SPIFFS_GC_DBG("gc_clean: state-> %i\n", gc.state); } // while state != FINISHED return res; } + diff --git a/cores/esp8266/spiffs/spiffs_hydrogen.c b/cores/esp8266/spiffs/spiffs_hydrogen.c index 6601b61ad..72b75d6ef 100644 --- a/cores/esp8266/spiffs/spiffs_hydrogen.c +++ b/cores/esp8266/spiffs/spiffs_hydrogen.c @@ -8,7 +8,9 @@ #include "spiffs.h" #include "spiffs_nucleus.h" +#if SPIFFS_CACHE == 1 static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh); +#endif #if SPIFFS_BUFFER_HELP u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs) { @@ -56,12 +58,12 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, void *cache, u32_t cache_size, spiffs_check_callback check_cb_f) { SPIFFS_LOCK(fs); - c_memset(fs, 0, sizeof(spiffs)); - c_memcpy(&fs->cfg, config, sizeof(spiffs_config)); + memset(fs, 0, sizeof(spiffs)); + memcpy(&fs->cfg, config, sizeof(spiffs_config)); fs->block_count = SPIFFS_CFG_PHYS_SZ(fs) / SPIFFS_CFG_LOG_BLOCK_SZ(fs); fs->work = &work[0]; fs->lu_work = &work[SPIFFS_CFG_LOG_PAGE_SZ(fs)]; - c_memset(fd_space, 0, fd_space_size); + memset(fd_space, 0, fd_space_size); // align fd_space pointer to pointer size byte boundary, below is safe u8_t ptr_size = sizeof(void*); #pragma GCC diagnostic push @@ -89,9 +91,10 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, if (cache_size & (ptr_size-1)) { cache_size -= (cache_size & (ptr_size-1)); } + #if SPIFFS_CACHE fs->cache = cache; - fs->cache_size = cache_size; + fs->cache_size = (cache_size > (SPIFFS_CFG_LOG_PAGE_SZ(fs)*32)) ? SPIFFS_CFG_LOG_PAGE_SZ(fs)*32 : cache_size; spiffs_cache_init(fs); #endif @@ -107,14 +110,14 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, res = spiffs_obj_lu_scan(fs); SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_DBG("page index byte len: %d\n", SPIFFS_CFG_LOG_PAGE_SZ(fs)); - SPIFFS_DBG("object lookup pages: %d\n", SPIFFS_OBJ_LOOKUP_PAGES(fs)); - SPIFFS_DBG("page pages per block: %d\n", SPIFFS_PAGES_PER_BLOCK(fs)); - SPIFFS_DBG("page header length: %d\n", sizeof(spiffs_page_header)); - SPIFFS_DBG("object header index entries: %d\n", SPIFFS_OBJ_HDR_IX_LEN(fs)); - SPIFFS_DBG("object index entries: %d\n", SPIFFS_OBJ_IX_LEN(fs)); - SPIFFS_DBG("available file descriptors: %d\n", fs->fd_count); - SPIFFS_DBG("free blocks: %d\n", fs->free_blocks); + SPIFFS_DBG("page index byte len: %i\n", SPIFFS_CFG_LOG_PAGE_SZ(fs)); + SPIFFS_DBG("object lookup pages: %i\n", SPIFFS_OBJ_LOOKUP_PAGES(fs)); + SPIFFS_DBG("page pages per block: %i\n", SPIFFS_PAGES_PER_BLOCK(fs)); + SPIFFS_DBG("page header length: %i\n", sizeof(spiffs_page_header)); + SPIFFS_DBG("object header index entries: %i\n", SPIFFS_OBJ_HDR_IX_LEN(fs)); + SPIFFS_DBG("object index entries: %i\n", SPIFFS_OBJ_IX_LEN(fs)); + SPIFFS_DBG("available file descriptors: %i\n", fs->fd_count); + SPIFFS_DBG("free blocks: %i\n", fs->free_blocks); fs->check_cb_f = check_cb_f; @@ -188,6 +191,14 @@ spiffs_file SPIFFS_open(spiffs *fs, char *path, spiffs_flags flags, spiffs_mode SPIFFS_API_CHECK_RES_UNLOCK(fs, res); } + if (res == SPIFFS_OK && + (flags & (SPIFFS_CREAT | SPIFFS_EXCL)) == (SPIFFS_CREAT | SPIFFS_EXCL)) { + // creat and excl and file exists - fail + res = SPIFFS_ERR_FILE_EXISTS; + spiffs_fd_return(fs, fd->file_nbr); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + if ((flags & SPIFFS_CREAT) && res == SPIFFS_ERR_NOT_FOUND) { spiffs_obj_id obj_id; // no need to enter conflicting name here, already looked for it above @@ -377,7 +388,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { offset + len > fd->cache_page->offset + SPIFFS_CFG_LOG_PAGE_SZ(fs)) // writing beyond cache page { // boundary violation, write back cache first and allocate new - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %d for fd %d:%04x, boundary viol, offs:%d size:%d\n", + SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, boundary viol, offs:%i size:%i\n", fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); res = spiffs_hydro_write(fs, fd, spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), @@ -395,19 +406,19 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { if (fd->cache_page) { fd->cache_page->offset = offset; fd->cache_page->size = 0; - SPIFFS_CACHE_DBG("CACHE_WR_ALLO: allocating cache page %d for fd %d:%04x\n", + SPIFFS_CACHE_DBG("CACHE_WR_ALLO: allocating cache page %i for fd %i:%04x\n", fd->cache_page->ix, fd->file_nbr, fd->obj_id); } } if (fd->cache_page) { u32_t offset_in_cpage = offset - fd->cache_page->offset; - SPIFFS_CACHE_DBG("CACHE_WR_WRITE: storing to cache page %d for fd %d:%04x, offs %d:%d len %d\n", + SPIFFS_CACHE_DBG("CACHE_WR_WRITE: storing to cache page %i for fd %i:%04x, offs %i:%i len %i\n", fd->cache_page->ix, fd->file_nbr, fd->obj_id, offset, offset_in_cpage, len); spiffs_cache *cache = spiffs_get_cache(fs); u8_t *cpage_data = spiffs_get_cache_page(fs, cache, fd->cache_page->ix); - c_memcpy(&cpage_data[offset_in_cpage], buf, len); + memcpy(&cpage_data[offset_in_cpage], buf, len); fd->cache_page->size = MAX(fd->cache_page->size, offset_in_cpage + len); fd->fdoffset += len; SPIFFS_UNLOCK(fs); @@ -423,7 +434,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { // big write, no need to cache it - but first check if there is a cached write already if (fd->cache_page) { // write back cache first - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %d for fd %d:%04x, big write, offs:%d size:%d\n", + SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, big write, offs:%i size:%i\n", fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); res = spiffs_hydro_write(fs, fd, spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), @@ -488,7 +499,7 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) { SPIFFS_UNLOCK(fs); - return 0; + return offs; } s32_t SPIFFS_remove(spiffs *fs, char *path) { @@ -554,6 +565,7 @@ s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) { } static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spiffs_stat *s) { + (void)fh; spiffs_page_object_ix_header objix_hdr; spiffs_obj_id obj_id; s32_t res =_spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fh, @@ -616,7 +628,10 @@ s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) { // Checks if there are any cached writes for the object id associated with // given filehandle. If so, these writes are flushed. +#if SPIFFS_CACHE == 1 static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) { + (void)fs; + (void)fh; s32_t res = SPIFFS_OK; #if SPIFFS_CACHE_WR @@ -630,7 +645,7 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) { fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); } if (fd->cache_page) { - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %d for fd %d:%04x, flush, offs:%d size:%d\n", + SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, flush, offs:%i size:%i\n", fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); res = spiffs_hydro_write(fs, fd, spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), @@ -645,8 +660,10 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) { return res; } +#endif s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) { + (void)fh; SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_MOUNT(fs); s32_t res = SPIFFS_OK; @@ -660,24 +677,23 @@ s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) { return res; } -void SPIFFS_close(spiffs *fs, spiffs_file fh) { - if (!SPIFFS_CHECK_CFG((fs))) { - (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; - return; - } +s32_t SPIFFS_close(spiffs *fs, spiffs_file fh) { + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); - if (!SPIFFS_CHECK_MOUNT(fs)) { - fs->err_code = SPIFFS_ERR_NOT_MOUNTED; - return; - } + s32_t res = SPIFFS_OK; SPIFFS_LOCK(fs); #if SPIFFS_CACHE - spiffs_fflush_cache(fs, fh); + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #endif - spiffs_fd_return(fs, fh); + res = spiffs_fd_return(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); SPIFFS_UNLOCK(fs); + + return res; } s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) { @@ -711,9 +727,8 @@ s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) { res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, (u8_t*)new, 0, &pix_dummy); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } + spiffs_fd_return(fs, fd->file_nbr); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); SPIFFS_UNLOCK(fs); @@ -780,7 +795,7 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) { d->fs->err_code = SPIFFS_ERR_NOT_MOUNTED; return 0; } - SPIFFS_LOCK(fs); + SPIFFS_LOCK(d->fs); spiffs_block_ix bix; int entry; @@ -804,7 +819,7 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) { } else { d->fs->err_code = res; } - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(d->fs); return ret; } @@ -856,46 +871,34 @@ s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) { return res; } -s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) { +s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages) { + s32_t res; SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_LOCK(fs); - spiffs_fd *fd; - s32_t res; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES(fs, res); - -#if SPIFFS_CACHE_WR - spiffs_fflush_cache(fs, fh); -#endif - - res = (fd->fdoffset == fd->size); + res = spiffs_gc_quick(fs, max_free_pages); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); SPIFFS_UNLOCK(fs); - return res; + return 0; } -s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) { + +s32_t SPIFFS_gc(spiffs *fs, u32_t size) { + s32_t res; SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_LOCK(fs); - spiffs_fd *fd; - s32_t res; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES(fs, res); - -#if SPIFFS_CACHE_WR - spiffs_fflush_cache(fs, fh); -#endif - - res = fd->fdoffset; + res = spiffs_gc_check(fs, size); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); SPIFFS_UNLOCK(fs); - return res; + return 0; } + #if SPIFFS_TEST_VISUALISATION s32_t SPIFFS_vis(spiffs *fs) { s32_t res = SPIFFS_OK; @@ -949,7 +952,7 @@ s32_t SPIFFS_vis(spiffs *fs) { SPIFFS_CHECK_RES(res); if (erase_count != (spiffs_obj_id)-1) { - spiffs_printf("\tera_cnt: %d\n", erase_count); + spiffs_printf("\tera_cnt: %i\n", erase_count); } else { spiffs_printf("\tera_cnt: N/A\n"); } @@ -957,15 +960,15 @@ s32_t SPIFFS_vis(spiffs *fs) { bix++; } // per block - spiffs_printf("era_cnt_max: %d\n", fs->max_erase_count); - spiffs_printf("last_errno: %d\n", fs->err_code); - spiffs_printf("blocks: %d\n", fs->block_count); - spiffs_printf("free_blocks: %d\n", fs->free_blocks); - spiffs_printf("page_alloc: %d\n", fs->stats_p_allocated); - spiffs_printf("page_delet: %d\n", fs->stats_p_deleted); + spiffs_printf("era_cnt_max: %i\n", fs->max_erase_count); + spiffs_printf("last_errno: %i\n", fs->err_code); + spiffs_printf("blocks: %i\n", fs->block_count); + spiffs_printf("free_blocks: %i\n", fs->free_blocks); + spiffs_printf("page_alloc: %i\n", fs->stats_p_allocated); + spiffs_printf("page_delet: %i\n", fs->stats_p_deleted); u32_t total, used; SPIFFS_info(fs, &total, &used); - spiffs_printf("used: %d of %d\n", used, total); + spiffs_printf("used: %i of %i\n", used, total); SPIFFS_UNLOCK(fs); return res; diff --git a/cores/esp8266/spiffs/spiffs_nucleus.c b/cores/esp8266/spiffs/spiffs_nucleus.c index fa75fd8e9..18712c6e1 100644 --- a/cores/esp8266/spiffs/spiffs_nucleus.c +++ b/cores/esp8266/spiffs/spiffs_nucleus.c @@ -64,7 +64,7 @@ s32_t spiffs_phys_rd( u32_t addr, u32_t len, u8_t *dst) { - return fs->cfg.hal_read_f(addr, len, dst); + return SPIFFS_HAL_READ(fs, addr, len, dst); } s32_t spiffs_phys_wr( @@ -72,7 +72,7 @@ s32_t spiffs_phys_wr( u32_t addr, u32_t len, u8_t *src) { - return fs->cfg.hal_write_f(addr, len, src); + return SPIFFS_HAL_WRITE(fs, addr, len, src); } #endif @@ -83,6 +83,7 @@ s32_t spiffs_phys_cpy( u32_t dst, u32_t src, u32_t len) { + (void)fh; s32_t res; u8_t b[SPIFFS_COPY_BUFFER_STACK]; while (len > 0) { @@ -227,7 +228,8 @@ s32_t spiffs_erase_block( // here we ignore res, just try erasing the block while (size > 0) { SPIFFS_DBG("erase %08x:%08x\n", addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); - (void)fs->cfg.hal_erase_f(addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); + SPIFFS_HAL_ERASE(fs, addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); + addr += SPIFFS_CFG_PHYS_ERASE_SZ(fs); size -= SPIFFS_CFG_PHYS_ERASE_SZ(fs); } @@ -347,7 +349,7 @@ s32_t spiffs_obj_lu_scan( #if SPIFFS_USE_MAGIC if (unerased_bix != (spiffs_block_ix)-1) { // found one unerased block, remedy - SPIFFS_DBG("mount: erase block %d\n", bix); + SPIFFS_DBG("mount: erase block %i\n", bix); res = spiffs_erase_block(fs, unerased_bix); SPIFFS_CHECK_RES(res); } @@ -389,7 +391,10 @@ s32_t spiffs_obj_lu_find_free( int *lu_entry) { s32_t res; if (!fs->cleaning && fs->free_blocks < 2) { - res = spiffs_gc_quick(fs); + res = spiffs_gc_quick(fs, 0); + if (res == SPIFFS_ERR_NO_DELETED_BLOCKS) { + res = SPIFFS_OK; + } SPIFFS_CHECK_RES(res); if (fs->free_blocks < 2) { return SPIFFS_ERR_FULL; @@ -701,7 +706,7 @@ s32_t spiffs_object_create( // find free entry res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); SPIFFS_CHECK_RES(res); - SPIFFS_DBG("create: found free page @ %04x bix:%d entry:%d\n", SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), bix, entry); + SPIFFS_DBG("create: found free page @ %04x bix:%i entry:%i\n", SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), bix, entry); // occupy page in object lookup res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, @@ -806,7 +811,7 @@ void spiffs_cb_object_event( if (cur_fd->file_nbr == 0 || (cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; if (spix == 0) { if (ev == SPIFFS_EV_IX_NEW || ev == SPIFFS_EV_IX_UPD) { - SPIFFS_DBG(" callback: setting fd %d:%04x objix_hdr_pix to %04x, size:%d\n", cur_fd->file_nbr, cur_fd->obj_id, new_pix, new_size); + SPIFFS_DBG(" callback: setting fd %i:%04x objix_hdr_pix to %04x, size:%i\n", cur_fd->file_nbr, cur_fd->obj_id, new_pix, new_size); cur_fd->objix_hdr_pix = new_pix; if (new_size != 0) { cur_fd->size = new_size; @@ -818,7 +823,7 @@ void spiffs_cb_object_event( } if (cur_fd->cursor_objix_spix == spix) { if (ev == SPIFFS_EV_IX_NEW || ev == SPIFFS_EV_IX_UPD) { - SPIFFS_DBG(" callback: setting fd %d:%04x span:%04x objix_pix to %04x\n", cur_fd->file_nbr, cur_fd->obj_id, spix, new_pix); + SPIFFS_DBG(" callback: setting fd %i:%04x span:%04x objix_pix to %04x\n", cur_fd->file_nbr, cur_fd->obj_id, spix, new_pix); cur_fd->cursor_objix_pix = new_pix; } else { cur_fd->cursor_objix_pix = 0; @@ -878,7 +883,7 @@ s32_t spiffs_object_open_by_page( SPIFFS_VALIDATE_OBJIX(oix_hdr.p_hdr, fd->obj_id, 0); - SPIFFS_DBG("open: fd %d is obj id %04x\n", fd->file_nbr, fd->obj_id); + SPIFFS_DBG("open: fd %i is obj id %04x\n", fd->file_nbr, fd->obj_id); return res; } @@ -890,7 +895,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { s32_t res = SPIFFS_OK; u32_t written = 0; - SPIFFS_DBG("append: %d bytes @ offs %d of size %d\n", len, offset, fd->size); + SPIFFS_DBG("append: %i bytes @ offs %i of size %i\n", len, offset, fd->size); if (offset > fd->size) { SPIFFS_DBG("append: offset reversed to size\n"); @@ -899,7 +904,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); // add an extra page of data worth for meta if (res != SPIFFS_OK) { - SPIFFS_DBG("append: gc check fail %d\n", res); + SPIFFS_DBG("append: gc check fail %i\n", res); } SPIFFS_CHECK_RES(res); @@ -927,7 +932,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { // within this clause we return directly if something fails, object index mess-up if (written > 0) { // store previous object index page, unless first pass - SPIFFS_DBG("append: %04x store objix %04x:%04x, written %d\n", fd->obj_id, + SPIFFS_DBG("append: %04x store objix %04x:%04x, written %i\n", fd->obj_id, cur_objix_pix, prev_objix_spix, written); if (prev_objix_spix == 0) { // this is an update to object index header page @@ -944,7 +949,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, fs->work, 0, offset+written, &new_objix_hdr_page); SPIFFS_CHECK_RES(res); - SPIFFS_DBG("append: %04x store new objix_hdr, %04x:%04x, written %d\n", fd->obj_id, + SPIFFS_DBG("append: %04x store new objix_hdr, %04x:%04x, written %i\n", fd->obj_id, new_objix_hdr_page, 0, written); } } else { @@ -960,7 +965,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, offset+written, &new_objix_hdr_page); SPIFFS_CHECK_RES(res); - SPIFFS_DBG("append: %04x store new size I %d in objix_hdr, %04x:%04x, written %d\n", fd->obj_id, + SPIFFS_DBG("append: %04x store new size I %i in objix_hdr, %04x:%04x, written %i\n", fd->obj_id, offset+written, new_objix_hdr_page, 0, written); } fd->size = offset+written; @@ -987,9 +992,9 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { SPIFFS_CHECK_RES(res); spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_NEW, fd->obj_id, cur_objix_spix, cur_objix_pix, 0); // quick "load" of new object index page - c_memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - c_memcpy(fs->work, &p_hdr, sizeof(spiffs_page_header)); - SPIFFS_DBG("append: %04x create objix page, %04x:%04x, written %d\n", fd->obj_id + memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + memcpy(fs->work, &p_hdr, sizeof(spiffs_page_header)); + SPIFFS_DBG("append: %04x create objix page, %04x:%04x, written %i\n", fd->obj_id , cur_objix_pix, cur_objix_spix, written); } else { // on first pass, we load existing object index page @@ -1001,7 +1006,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); SPIFFS_CHECK_RES(res); } - SPIFFS_DBG("append: %04x found object index at page %04x [fd size %d]\n", fd->obj_id, pix, fd->size); + SPIFFS_DBG("append: %04x found object index at page %04x [fd size %i]\n", fd->obj_id, pix, fd->size); res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); SPIFFS_CHECK_RES(res); @@ -1025,7 +1030,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL); // finalize immediately res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, &p_hdr, &data[written], to_write, page_offs, 1, &data_page); - SPIFFS_DBG("append: %04x store new data page, %04x:%04x offset:%d, len %d, written %d\n", fd->obj_id, + SPIFFS_DBG("append: %04x store new data page, %04x:%04x offset:%i, len %i, written %i\n", fd->obj_id, data_page, data_spix, page_offs, to_write, written); } else { // append to existing page, fill out free data in existing page @@ -1042,7 +1047,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, data_page) + sizeof(spiffs_page_header) + page_offs, to_write, &data[written]); - SPIFFS_DBG("append: %04x store to existing data page, %04x:%04x offset:%d, len %d, written %d\n", fd->obj_id + SPIFFS_DBG("append: %04x store to existing data page, %04x:%04x offset:%i, len %i, written %i\n", fd->obj_id , data_page, data_spix, page_offs, to_write, written); } @@ -1078,7 +1083,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { if (cur_objix_spix != 0) { // wrote beyond object index header page // write last modified object index page, unless object header index page - SPIFFS_DBG("append: %04x store objix page, %04x:%04x, written %d\n", fd->obj_id, + SPIFFS_DBG("append: %04x store objix page, %04x:%04x, written %i\n", fd->obj_id, cur_objix_pix, cur_objix_spix, written); res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); @@ -1092,7 +1097,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { // update size in object header index page res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, offset+written, &new_objix_hdr_page); - SPIFFS_DBG("append: %04x store new size II %d in objix_hdr, %04x:%04x, written %d, res %d\n", fd->obj_id + SPIFFS_DBG("append: %04x store new size II %i in objix_hdr, %04x:%04x, written %i, res %i\n", fd->obj_id , offset+written, new_objix_hdr_page, 0, written, res2); SPIFFS_CHECK_RES(res2); } else { @@ -1100,7 +1105,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { if (offset == 0) { // wrote to empty object - simply update size and write whole page objix_hdr->size = offset+written; - SPIFFS_DBG("append: %04x store fresh objix_hdr page, %04x:%04x, written %d\n", fd->obj_id + SPIFFS_DBG("append: %04x store fresh objix_hdr page, %04x:%04x, written %i\n", fd->obj_id , cur_objix_pix, cur_objix_spix, written); res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); @@ -1115,7 +1120,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { // modifying object index header page, update size and make new copy res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, fs->work, 0, offset+written, &new_objix_hdr_page); - SPIFFS_DBG("append: %04x store modified objix_hdr page, %04x:%04x, written %d\n", fd->obj_id + SPIFFS_DBG("append: %04x store modified objix_hdr page, %04x:%04x, written %i\n", fd->obj_id , new_objix_hdr_page, 0, written); SPIFFS_CHECK_RES(res2); } @@ -1163,7 +1168,7 @@ s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { // store previous object index header page res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, fs->work, 0, 0, &new_objix_hdr_pix); - SPIFFS_DBG("modify: store modified objix_hdr page, %04x:%04x, written %d\n", new_objix_hdr_pix, 0, written); + SPIFFS_DBG("modify: store modified objix_hdr page, %04x:%04x, written %i\n", new_objix_hdr_pix, 0, written); SPIFFS_CHECK_RES(res); } else { // store new version of previous object index page @@ -1173,7 +1178,7 @@ s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { SPIFFS_CHECK_RES(res); res = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); - SPIFFS_DBG("modify: store previous modified objix page, %04x:%04x, written %d\n", new_objix_pix, objix->p_hdr.span_ix, written); + SPIFFS_DBG("modify: store previous modified objix page, %04x:%04x, written %i\n", new_objix_pix, objix->p_hdr.span_ix, written); SPIFFS_CHECK_RES(res); spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); } @@ -1228,7 +1233,7 @@ s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { // a full page, allocate and write a new page of data res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, &p_hdr, &data[written], to_write, page_offs, 1, &data_pix); - SPIFFS_DBG("modify: store new data page, %04x:%04x offset:%d, len %d, written %d\n", data_pix, data_spix, page_offs, to_write, written); + SPIFFS_DBG("modify: store new data page, %04x:%04x offset:%i, len %i, written %i\n", data_pix, data_spix, page_offs, to_write, written); } else { // write to existing page, allocate new and copy unmodified data @@ -1269,7 +1274,7 @@ s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { (u8_t *)&p_hdr.flags); if (res != SPIFFS_OK) break; - SPIFFS_DBG("modify: store to existing data page, src:%04x, dst:%04x:%04x offset:%d, len %d, written %d\n", orig_data_pix, data_pix, data_spix, page_offs, to_write, written); + SPIFFS_DBG("modify: store to existing data page, src:%04x, dst:%04x:%04x offset:%i, len %i, written %i\n", orig_data_pix, data_pix, data_spix, page_offs, to_write, written); } // delete original data page @@ -1308,7 +1313,7 @@ s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { SPIFFS_CHECK_RES(res2); res2 = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); - SPIFFS_DBG("modify: store modified objix page, %04x:%04x, written %d\n", new_objix_pix, cur_objix_spix, written); + SPIFFS_DBG("modify: store modified objix page, %04x:%04x, written %i\n", new_objix_pix, cur_objix_spix, written); fd->cursor_objix_pix = new_objix_pix; fd->cursor_objix_spix = cur_objix_spix; SPIFFS_CHECK_RES(res2); @@ -1318,7 +1323,7 @@ s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { // wrote within object index header page res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, fs->work, 0, 0, &new_objix_hdr_pix); - SPIFFS_DBG("modify: store modified objix_hdr page, %04x:%04x, written %d\n", new_objix_hdr_pix, 0, written); + SPIFFS_DBG("modify: store modified objix_hdr page, %04x:%04x, written %i\n", new_objix_hdr_pix, 0, written); SPIFFS_CHECK_RES(res2); } @@ -1438,7 +1443,7 @@ s32_t spiffs_object_truncate( spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_DEL, fd->obj_id, objix->p_hdr.span_ix, objix_pix, 0); if (prev_objix_spix > 0) { // update object index header page - SPIFFS_DBG("truncate: update objix hdr page %04x:%04x to size %d\n", fd->objix_hdr_pix, prev_objix_spix, cur_size); + SPIFFS_DBG("truncate: update objix hdr page %04x:%04x to size %i\n", fd->objix_hdr_pix, prev_objix_spix, cur_size); res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, cur_size, &new_objix_hdr_pix); SPIFFS_CHECK_RES(res); @@ -1481,14 +1486,14 @@ s32_t spiffs_object_truncate( // delete full data page res = spiffs_page_data_check(fs, fd, data_pix, data_spix); if (res != SPIFFS_ERR_DELETED && res != SPIFFS_OK && res != SPIFFS_ERR_INDEX_REF_FREE) { - SPIFFS_DBG("truncate: err validating data pix %d\n", res); + SPIFFS_DBG("truncate: err validating data pix %i\n", res); break; } if (res == SPIFFS_OK) { res = spiffs_page_delete(fs, data_pix); if (res != SPIFFS_OK) { - SPIFFS_DBG("truncate: err deleting data pix %d\n", res); + SPIFFS_DBG("truncate: err deleting data pix %i\n", res); break; } } else if (res == SPIFFS_ERR_DELETED || res == SPIFFS_ERR_INDEX_REF_FREE) { @@ -1503,13 +1508,13 @@ s32_t spiffs_object_truncate( } fd->size = cur_size; fd->offset = cur_size; - SPIFFS_DBG("truncate: delete data page %04x for data spix:%04x, cur_size:%d\n", data_pix, data_spix, cur_size); + SPIFFS_DBG("truncate: delete data page %04x for data spix:%04x, cur_size:%i\n", data_pix, data_spix, cur_size); } else { // delete last page, partially spiffs_page_header p_hdr; spiffs_page_ix new_data_pix; u32_t bytes_to_remove = SPIFFS_DATA_PAGE_SIZE(fs) - (new_size % SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_DBG("truncate: delete %d bytes from data page %04x for data spix:%04x, cur_size:%d\n", bytes_to_remove, data_pix, data_spix, cur_size); + SPIFFS_DBG("truncate: delete %i bytes from data page %04x for data spix:%04x, cur_size:%i\n", bytes_to_remove, data_pix, data_spix, cur_size); res = spiffs_page_data_check(fs, fd, data_pix, data_spix); if (res != SPIFFS_OK) break; @@ -1572,7 +1577,7 @@ s32_t spiffs_object_truncate( } else { // make uninitialized object SPIFFS_DBG("truncate: reset objix_hdr page %04x\n", objix_pix); - c_memset(fs->work + sizeof(spiffs_page_object_ix_header), 0xff, + memset(fs->work + sizeof(spiffs_page_object_ix_header), 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header)); res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, objix_pix, fs->work, 0, SPIFFS_UNDEFINED_LEN, &new_objix_hdr_pix); @@ -1664,7 +1669,7 @@ s32_t spiffs_object_read( len_to_read = MIN(len_to_read, SPIFFS_DATA_PAGE_SIZE(fs) - (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); // remaining data in file len_to_read = MIN(len_to_read, fd->size); - SPIFFS_DBG("read: offset:%d rd:%d data spix:%04x is data_pix:%04x addr:%08x\n", cur_offset, len_to_read, data_spix, data_pix, + SPIFFS_DBG("read: offset:%i rd:%i data spix:%04x is data_pix:%04x addr:%08x\n", cur_offset, len_to_read, data_spix, data_pix, SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); if (len_to_read <= 0) { res = SPIFFS_ERR_END_OF_OBJECT; @@ -1750,7 +1755,7 @@ static s32_t spiffs_obj_lu_find_free_obj_id_compact_v(spiffs *fs, spiffs_obj_id if (id >= state->min_obj_id && id <= state->max_obj_id) { u8_t *map = (u8_t *)fs->work; int ix = (id - state->min_obj_id) / state->compaction; - //SPIFFS_DBG("free_obj_id: add ix %d for id %04x min:%04x max%04x comp:%d\n", ix, id, state->min_obj_id, state->max_obj_id, state->compaction); + //SPIFFS_DBG("free_obj_id: add ix %i for id %04x min:%04x max%04x comp:%i\n", ix, id, state->min_obj_id, state->max_obj_id, state->compaction); map[ix]++; } } @@ -1780,7 +1785,7 @@ s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, u8_t *co u32_t i, j; SPIFFS_DBG("free_obj_id: BITM min:%04x max:%04x\n", state.min_obj_id, state.max_obj_id); - c_memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_bitmap_v, state.min_obj_id, conflicting_name, 0, 0); if (res == SPIFFS_VIS_END) res = SPIFFS_OK; @@ -1823,7 +1828,7 @@ s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, u8_t *co return SPIFFS_ERR_FULL; } - SPIFFS_DBG("free_obj_id: COMP select index:%d min_count:%d min:%04x max:%04x compact:%d\n", min_i, min_count, state.min_obj_id, state.max_obj_id, state.compaction); + SPIFFS_DBG("free_obj_id: COMP select index:%i min_count:%i min:%04x max:%04x compact:%i\n", min_i, min_count, state.min_obj_id, state.max_obj_id, state.compaction); if (min_count == 0) { // no id in this range, skip compacting and use directly @@ -1843,9 +1848,9 @@ s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, u8_t *co // in a work memory of log_page_size bytes, we may fit in log_page_size ids // todo what if compaction is > 255 - then we cannot fit it in a byte state.compaction = (state.max_obj_id-state.min_obj_id) / ((SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(u8_t))); - SPIFFS_DBG("free_obj_id: COMP min:%04x max:%04x compact:%d\n", state.min_obj_id, state.max_obj_id, state.compaction); + SPIFFS_DBG("free_obj_id: COMP min:%04x max:%04x compact:%i\n", state.min_obj_id, state.max_obj_id, state.compaction); - c_memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_compact_v, 0, &state, 0, 0); if (res == SPIFFS_VIS_END) res = SPIFFS_OK; SPIFFS_CHECK_RES(res); diff --git a/cores/esp8266/spiffs/spiffs_nucleus.h b/cores/esp8266/spiffs/spiffs_nucleus.h index 5d905fe90..f19b24af8 100644 --- a/cores/esp8266/spiffs/spiffs_nucleus.h +++ b/cores/esp8266/spiffs/spiffs_nucleus.h @@ -124,7 +124,7 @@ #define SPIFFS_EV_IX_NEW 1 #define SPIFFS_EV_IX_DEL 2 -#define SPIFFS_OBJ_ID_IX_FLAG (1<<(8*sizeof(spiffs_obj_id)-1)) +#define SPIFFS_OBJ_ID_IX_FLAG ((spiffs_obj_id)(1<<(8*sizeof(spiffs_obj_id)-1))) #define SPIFFS_UNDEFINED_LEN (u32_t)(-1) @@ -311,6 +311,26 @@ // stop searching at end of all look up pages #define SPIFFS_VIS_NO_WRAP (1<<2) +#if SPIFFS_HAL_CALLBACK_EXTRA + +#define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \ + (_fs)->cfg.hal_write_f((_fs), (_paddr), (_len), (_src)) +#define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \ + (_fs)->cfg.hal_read_f((_fs), (_paddr), (_len), (_dst)) +#define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \ + (_fs)->cfg.hal_erase_f((_fs), (_paddr), (_len)) + +#else // SPIFFS_HAL_CALLBACK_EXTRA + +#define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \ + (_fs)->cfg.hal_write_f((_paddr), (_len), (_src)) +#define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \ + (_fs)->cfg.hal_read_f((_paddr), (_len), (_dst)) +#define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \ + (_fs)->cfg.hal_erase_f((_paddr), (_len)) + +#endif // SPIFFS_HAL_CALLBACK_EXTRA + #if SPIFFS_CACHE #define SPIFFS_CACHE_FLAG_DIRTY (1<<0) @@ -423,7 +443,7 @@ typedef struct __attribute(( packed )) // common page header spiffs_page_header p_hdr; // alignment - u8_t _align[4 - (sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3)]; + u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))]; // size of object u32_t size; // type of object @@ -435,7 +455,7 @@ typedef struct __attribute(( packed )) // object index page header typedef struct __attribute(( packed )) { spiffs_page_header p_hdr; - u8_t _align[4 - (sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3)]; + u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))]; } spiffs_page_object_ix; // callback func for object lookup visitor @@ -665,7 +685,7 @@ s32_t spiffs_gc_clean( spiffs_block_ix bix); s32_t spiffs_gc_quick( - spiffs *fs); + spiffs *fs, u16_t max_free_pages); // --------------- diff --git a/cores/esp8266/spiffs_api.cpp b/cores/esp8266/spiffs_api.cpp index d9c7c618f..c482c8438 100644 --- a/cores/esp8266/spiffs_api.cpp +++ b/cores/esp8266/spiffs_api.cpp @@ -239,7 +239,7 @@ public: size_t position() const override { CHECKFD(); - auto result = SPIFFS_tell(_fs->getFs(), _fd); + auto result = SPIFFS_lseek(_fs->getFs(), _fd, 0, SPIFFS_SEEK_CUR); if (result < 0) { DEBUGV("SPIFFS_tell rc=%d\r\n", result); return 0;