mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +03:00
Merge remote-tracking branch 'esp8266/esp8266' into esp8266
This commit is contained in:
commit
b79f1c689d
@ -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;
|
||||
|
@ -78,6 +78,7 @@ public:
|
||||
|
||||
File openFile(const char* mode);
|
||||
String fileName();
|
||||
size_t fileSize();
|
||||
bool next();
|
||||
|
||||
protected:
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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,50 +159,65 @@ 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 signInt_Part = 1;
|
||||
|
||||
|
||||
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) {
|
||||
signInt_Part = -1;
|
||||
negative = true;
|
||||
fillme--;
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
// Figure out how big our number really is
|
||||
double tenpow = 1.0;
|
||||
int digitcount = 1;
|
||||
while (number >= 10.0 * tenpow) {
|
||||
tenpow *= 10.0;
|
||||
digitcount++;
|
||||
}
|
||||
|
||||
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 (digitcount-- > 0) {
|
||||
digit = (int8_t)number;
|
||||
if (digit > 9) digit = 9; // insurance
|
||||
*out++ = (char)('0' | digit);
|
||||
if ((digitcount == prec) && (prec > 0)) {
|
||||
*out++ = '.';
|
||||
}
|
||||
number -= digit;
|
||||
number *= 10.0;
|
||||
}
|
||||
|
||||
// make sure the string is terminated
|
||||
*out = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
SPIFFS (SPI Flash File System)
|
||||
V0.3.0
|
||||
V0.3.2
|
||||
|
||||
Copyright (c) 2013-2015 Peter Andersson (pelleplutt1976<at>gmail.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
|
||||
|
@ -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
|
||||
|
||||
|
@ -20,7 +20,7 @@ static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix)
|
||||
if ((cache->cpage_use_map & (1<<i)) &&
|
||||
(cp->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<<i);
|
||||
cp->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++) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
// ---------------
|
||||
|
||||
|
@ -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;
|
||||
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user