Commit 11c47fa1 authored by Philip Gladstone's avatar Philip Gladstone Committed by Marcel Stör
Browse files

New version of spiffs (#2172)

parent ef91580c
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2013-2016 Peter Andersson (pelleplutt1976<at>gmail.com) Copyright (c) 2013-2017 Peter Andersson (pelleplutt1976<at>gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
......
...@@ -14,7 +14,7 @@ spiffs fs; ...@@ -14,7 +14,7 @@ spiffs fs;
static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2]; static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];
static u8_t spiffs_fds[sizeof(spiffs_fd) * SPIFFS_MAX_OPEN_FILES]; static u8_t spiffs_fds[sizeof(spiffs_fd) * SPIFFS_MAX_OPEN_FILES];
#if SPIFFS_CACHE #if SPIFFS_CACHE
static u8_t myspiffs_cache[(LOG_PAGE_SIZE+32)*2]; static u8_t myspiffs_cache[20 + (LOG_PAGE_SIZE+20)*4];
#endif #endif
static s32_t my_spiffs_read(u32_t addr, u32_t size, u8_t *dst) { static s32_t my_spiffs_read(u32_t addr, u32_t size, u8_t *dst) {
......
...@@ -60,6 +60,9 @@ extern "C" { ...@@ -60,6 +60,9 @@ extern "C" {
#define SPIFFS_ERR_IX_MAP_MAPPED -10038 #define SPIFFS_ERR_IX_MAP_MAPPED -10038
#define SPIFFS_ERR_IX_MAP_BAD_RANGE -10039 #define SPIFFS_ERR_IX_MAP_BAD_RANGE -10039
#define SPIFFS_ERR_SEEK_BOUNDS -10040
#define SPIFFS_ERR_INTERNAL -10050 #define SPIFFS_ERR_INTERNAL -10050
#define SPIFFS_ERR_TEST -10100 #define SPIFFS_ERR_TEST -10100
......
...@@ -20,7 +20,7 @@ static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix) ...@@ -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)) && if ((cache->cpage_use_map & (1<<i)) &&
(cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 &&
cp->pix == pix ) { cp->pix == pix ) {
SPIFFS_CACHE_DBG("CACHE_GET: have cache page "_SPIPRIi" for "_SPIPRIpg"\n", i, pix); //SPIFFS_CACHE_DBG("CACHE_GET: have cache page "_SPIPRIi" for "_SPIPRIpg"\n", i, pix);
cp->last_access = cache->last_access; cp->last_access = cache->last_access;
return cp; return cp;
} }
...@@ -39,17 +39,20 @@ static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) { ...@@ -39,17 +39,20 @@ 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_TYPE_WR) == 0 &&
(cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) { (cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) {
u8_t *mem = spiffs_get_cache_page(fs, cache, ix); u8_t *mem = spiffs_get_cache_page(fs, cache, ix);
SPIFFS_CACHE_DBG("CACHE_FREE: write cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix);
res = SPIFFS_HAL_WRITE(fs, 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; #if SPIFFS_CACHE_WR
cache->cpage_use_map &= ~(1 << ix);
if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) { if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) {
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" objid "_SPIPRIid"\n", ix, cp->obj_id); SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" objid "_SPIPRIid"\n", ix, cp->obj_id);
} else { } else
#endif
{
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix); SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix);
} }
cache->cpage_use_map &= ~(1 << ix);
cp->flags = 0;
} }
return res; return res;
...@@ -98,7 +101,7 @@ static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) { ...@@ -98,7 +101,7 @@ static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) {
spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i);
cache->cpage_use_map |= (1<<i); cache->cpage_use_map |= (1<<i);
cp->last_access = cache->last_access; cp->last_access = cache->last_access;
SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi"\n", i); //SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi"\n", i);
return cp; return cp;
} }
} }
...@@ -136,7 +139,7 @@ s32_t spiffs_phys_rd( ...@@ -136,7 +139,7 @@ s32_t spiffs_phys_rd(
#endif #endif
cp->last_access = cache->last_access; cp->last_access = cache->last_access;
u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix);
memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); _SPIFFS_MEMCPY(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len);
} else { } else {
if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) { 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 // for second layer lookup functions, we do not cache in order to prevent shredding
...@@ -153,6 +156,7 @@ s32_t spiffs_phys_rd( ...@@ -153,6 +156,7 @@ s32_t spiffs_phys_rd(
if (cp) { if (cp) {
cp->flags = SPIFFS_CACHE_FLAG_WRTHRU; cp->flags = SPIFFS_CACHE_FLAG_WRTHRU;
cp->pix = SPIFFS_PADDR_TO_PAGE(fs, addr); cp->pix = SPIFFS_PADDR_TO_PAGE(fs, addr);
SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for pix "_SPIPRIpg "\n", cp->ix, cp->pix);
s32_t res2 = SPIFFS_HAL_READ(fs, s32_t res2 = SPIFFS_HAL_READ(fs,
addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr), addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr),
...@@ -163,7 +167,7 @@ s32_t spiffs_phys_rd( ...@@ -163,7 +167,7 @@ s32_t spiffs_phys_rd(
res = res2; res = res2;
} }
u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix);
memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); _SPIFFS_MEMCPY(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len);
} else { } else {
// this will never happen, last resort for sake of symmetry // this will never happen, last resort for sake of symmetry
s32_t res2 = SPIFFS_HAL_READ(fs, addr, len, dst); s32_t res2 = SPIFFS_HAL_READ(fs, addr, len, dst);
...@@ -201,7 +205,7 @@ s32_t spiffs_phys_wr( ...@@ -201,7 +205,7 @@ s32_t spiffs_phys_wr(
} }
u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix);
memcpy(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len); _SPIFFS_MEMCPY(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len);
cache->last_access++; cache->last_access++;
cp->last_access = cache->last_access; cp->last_access = cache->last_access;
...@@ -256,6 +260,7 @@ spiffs_cache_page *spiffs_cache_page_allocate_by_fd(spiffs *fs, spiffs_fd *fd) { ...@@ -256,6 +260,7 @@ spiffs_cache_page *spiffs_cache_page_allocate_by_fd(spiffs *fs, spiffs_fd *fd) {
cp->flags = SPIFFS_CACHE_FLAG_TYPE_WR; cp->flags = SPIFFS_CACHE_FLAG_TYPE_WR;
cp->obj_id = fd->obj_id; cp->obj_id = fd->obj_id;
fd->cache_page = cp; fd->cache_page = cp;
SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for fd "_SPIPRIfd ":"_SPIPRIid "\n", cp->ix, fd->file_nbr, fd->obj_id);
return cp; return cp;
} }
...@@ -299,7 +304,7 @@ void spiffs_cache_init(spiffs *fs) { ...@@ -299,7 +304,7 @@ void spiffs_cache_init(spiffs *fs) {
cache.cpage_use_map = 0xffffffff; cache.cpage_use_map = 0xffffffff;
cache.cpage_use_mask = cache_mask; cache.cpage_use_mask = cache_mask;
memcpy(fs->cache, &cache, sizeof(spiffs_cache)); _SPIFFS_MEMCPY(fs->cache, &cache, sizeof(spiffs_cache));
spiffs_cache *c = spiffs_get_cache(fs); spiffs_cache *c = spiffs_get_cache(fs);
......
...@@ -161,11 +161,17 @@ static s32_t spiffs_delete_obj_lazy(spiffs *fs, spiffs_obj_id obj_id) { ...@@ -161,11 +161,17 @@ static s32_t spiffs_delete_obj_lazy(spiffs *fs, spiffs_obj_id obj_id) {
return SPIFFS_OK; return SPIFFS_OK;
} }
SPIFFS_CHECK_RES(res); SPIFFS_CHECK_RES(res);
u8_t flags = 0xff & ~SPIFFS_PH_FLAG_IXDELE; u8_t flags = 0xff;
#if SPIFFS_NO_BLIND_WRITES
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags),
sizeof(flags), &flags);
SPIFFS_CHECK_RES(res);
#endif
flags &= ~SPIFFS_PH_FLAG_IXDELE;
res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT,
0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags), 0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags),
sizeof(u8_t), sizeof(flags), &flags);
(u8_t *)&flags);
return res; return res;
} }
...@@ -423,10 +429,17 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s ...@@ -423,10 +429,17 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s
// just finalize // just finalize
SPIFFS_CHECK_DBG("LU: FIXUP: unfinalized page is referred, finalizing\n"); SPIFFS_CHECK_DBG("LU: FIXUP: unfinalized page is referred, finalizing\n");
CHECK_CB(fs, 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; u8_t flags = 0xff;
#if SPIFFS_NO_BLIND_WRITES
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ,
0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags),
sizeof(flags), &flags);
SPIFFS_CHECK_RES(res);
#endif
flags &= ~SPIFFS_PH_FLAG_FINAL;
res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, 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), 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags),
sizeof(u8_t), (u8_t*)&flags); sizeof(flags), &flags);
} }
} }
} }
......
...@@ -34,6 +34,10 @@ ...@@ -34,6 +34,10 @@
#ifndef SPIFFS_CHECK_DBG #ifndef SPIFFS_CHECK_DBG
#define SPIFFS_CHECK_DBG(...) //dbg_printf(__VA_ARGS__) #define SPIFFS_CHECK_DBG(...) //dbg_printf(__VA_ARGS__)
#endif #endif
// Set spiffs debug output call for all api invocations.
#ifndef SPIFFS_API_DBG
#define SPIFFS_API_DBG(_f, ...) //printf(_f, ## __VA_ARGS__)
#endif
// Defines spiffs debug print formatters // Defines spiffs debug print formatters
// some general signed number // some general signed number
...@@ -303,6 +307,17 @@ ...@@ -303,6 +307,17 @@
#define SPIFFS_IX_MAP 0 #define SPIFFS_IX_MAP 0
#endif #endif
// By default SPIFFS in some cases relies on the property of NOR flash that bits
// cannot be set from 0 to 1 by writing and that controllers will ignore such
// bit changes. This results in fewer reads as SPIFFS can in some cases perform
// blind writes, with all bits set to 1 and only those it needs reset set to 0.
// Most of the chips and controllers allow this behavior, so the default is to
// use this technique. If your controller is one of the rare ones that don't,
// turn this option on and SPIFFS will perform a read-modify-write instead.
#ifndef SPIFFS_NO_BLIND_WRITES
#define SPIFFS_NO_BLIND_WRITES 0
#endif
// Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function // Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function
// in the api. This function will visualize all filesystem using given printf // in the api. This function will visualize all filesystem using given printf
// function. // function.
......
...@@ -294,7 +294,7 @@ s32_t spiffs_gc_find_candidate( ...@@ -294,7 +294,7 @@ s32_t spiffs_gc_find_candidate(
// calculate score and insert into candidate table // calculate score and insert into candidate table
// stoneage sort, but probably not so many blocks // stoneage sort, but probably not so many blocks
if (res == SPIFFS_OK && deleted_pages_in_block > 0) { if (res == SPIFFS_OK /*&& deleted_pages_in_block > 0*/) {
// read erase count // read erase count
spiffs_obj_id erase_count; spiffs_obj_id erase_count;
res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0,
......
...@@ -8,14 +8,6 @@ ...@@ -8,14 +8,6 @@
#include "spiffs.h" #include "spiffs.h"
#include "spiffs_nucleus.h" #include "spiffs_nucleus.h"
#if SPIFFS_FILEHDL_OFFSET
#define SPIFFS_FH_OFFS(fs, fh) ((fh) != 0 ? ((fh) + (fs)->cfg.fh_ix_offset) : 0)
#define SPIFFS_FH_UNOFFS(fs, fh) ((fh) != 0 ? ((fh) - (fs)->cfg.fh_ix_offset) : 0)
#else
#define SPIFFS_FH_OFFS(fs, fh) (fh)
#define SPIFFS_FH_UNOFFS(fs, fh) (fh)
#endif
#if SPIFFS_CACHE == 1 #if SPIFFS_CACHE == 1
static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh); static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh);
#endif #endif
...@@ -69,6 +61,7 @@ s32_t SPIFFS_format(spiffs *fs) { ...@@ -69,6 +61,7 @@ s32_t SPIFFS_format(spiffs *fs) {
#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 #if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0
s32_t SPIFFS_probe_fs(spiffs_config *config) { s32_t SPIFFS_probe_fs(spiffs_config *config) {
SPIFFS_API_DBG("%s\n", __func__);
s32_t res = spiffs_probe(config); s32_t res = spiffs_probe(config);
return res; return res;
} }
...@@ -79,11 +72,23 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, ...@@ -79,11 +72,23 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
u8_t *fd_space, u32_t fd_space_size, u8_t *fd_space, u32_t fd_space_size,
void *cache, u32_t cache_size, void *cache, u32_t cache_size,
spiffs_check_callback check_cb_f) { spiffs_check_callback check_cb_f) {
SPIFFS_API_DBG("%s "
" sz:"_SPIPRIi " logpgsz:"_SPIPRIi " logblksz:"_SPIPRIi " perasz:"_SPIPRIi
" addr:"_SPIPRIad
" fdsz:"_SPIPRIi " cachesz:"_SPIPRIi
"\n",
__func__,
SPIFFS_CFG_PHYS_SZ(fs),
SPIFFS_CFG_LOG_PAGE_SZ(fs),
SPIFFS_CFG_LOG_BLOCK_SZ(fs),
SPIFFS_CFG_PHYS_ERASE_SZ(fs),
SPIFFS_CFG_PHYS_ADDR(fs),
fd_space_size, cache_size);
void *user_data; void *user_data;
SPIFFS_LOCK(fs); SPIFFS_LOCK(fs);
user_data = fs->user_data; user_data = fs->user_data;
memset(fs, 0, sizeof(spiffs)); memset(fs, 0, sizeof(spiffs));
memcpy(&fs->cfg, config, sizeof(spiffs_config)); _SPIFFS_MEMCPY(&fs->cfg, config, sizeof(spiffs_config));
fs->user_data = user_data; fs->user_data = user_data;
fs->block_count = SPIFFS_CFG_PHYS_SZ(fs) / SPIFFS_CFG_LOG_BLOCK_SZ(fs); fs->block_count = SPIFFS_CFG_PHYS_SZ(fs) / SPIFFS_CFG_LOG_BLOCK_SZ(fs);
fs->work = &work[0]; fs->work = &work[0];
...@@ -148,6 +153,7 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, ...@@ -148,6 +153,7 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
} }
void SPIFFS_unmount(spiffs *fs) { void SPIFFS_unmount(spiffs *fs) {
SPIFFS_API_DBG("%s\n", __func__);
if (!SPIFFS_CHECK_CFG(fs) || !SPIFFS_CHECK_MOUNT(fs)) return; if (!SPIFFS_CHECK_CFG(fs) || !SPIFFS_CHECK_MOUNT(fs)) return;
SPIFFS_LOCK(fs); SPIFFS_LOCK(fs);
u32_t i; u32_t i;
...@@ -171,10 +177,12 @@ s32_t SPIFFS_errno(spiffs *fs) { ...@@ -171,10 +177,12 @@ s32_t SPIFFS_errno(spiffs *fs) {
} }
void SPIFFS_clearerr(spiffs *fs) { void SPIFFS_clearerr(spiffs *fs) {
SPIFFS_API_DBG("%s\n", __func__);
fs->err_code = SPIFFS_OK; fs->err_code = SPIFFS_OK;
} }
s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode) { s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode) {
SPIFFS_API_DBG("%s '%s'\n", __func__, path);
#if SPIFFS_READ_ONLY #if SPIFFS_READ_ONLY
(void)fs; (void)path; (void)mode; (void)fs; (void)path; (void)mode;
return SPIFFS_ERR_RO_NOT_IMPL; return SPIFFS_ERR_RO_NOT_IMPL;
...@@ -199,6 +207,7 @@ s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode) { ...@@ -199,6 +207,7 @@ s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode) {
} }
spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode) { spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode) {
SPIFFS_API_DBG("%s '%s' "_SPIPRIfl "\n", __func__, path, flags);
(void)mode; (void)mode;
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
...@@ -279,6 +288,7 @@ spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs ...@@ -279,6 +288,7 @@ spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs
} }
spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode) { spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode) {
SPIFFS_API_DBG("%s '%s':"_SPIPRIid " "_SPIPRIfl "\n", __func__, e->name, e->obj_id, flags);
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
SPIFFS_LOCK(fs); SPIFFS_LOCK(fs);
...@@ -311,6 +321,7 @@ spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_fl ...@@ -311,6 +321,7 @@ spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_fl
} }
spiffs_file SPIFFS_open_by_page(spiffs *fs, spiffs_page_ix page_ix, spiffs_flags flags, spiffs_mode mode) { spiffs_file SPIFFS_open_by_page(spiffs *fs, spiffs_page_ix page_ix, spiffs_flags flags, spiffs_mode mode) {
SPIFFS_API_DBG("%s "_SPIPRIpg " "_SPIPRIfl "\n", __func__, page_ix, flags);
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
SPIFFS_LOCK(fs); SPIFFS_LOCK(fs);
...@@ -411,6 +422,7 @@ static s32_t spiffs_hydro_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) ...@@ -411,6 +422,7 @@ static s32_t spiffs_hydro_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len)
} }
s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, len);
s32_t res = spiffs_hydro_read(fs, fh, buf, len); s32_t res = spiffs_hydro_read(fs, fh, buf, len);
if (res == SPIFFS_ERR_END_OF_OBJECT) { if (res == SPIFFS_ERR_END_OF_OBJECT) {
res = 0; res = 0;
...@@ -444,6 +456,7 @@ static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offs ...@@ -444,6 +456,7 @@ static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offs
#endif // !SPIFFS_READ_ONLY #endif // !SPIFFS_READ_ONLY
s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, len);
#if SPIFFS_READ_ONLY #if SPIFFS_READ_ONLY
(void)fs; (void)fh; (void)buf; (void)len; (void)fs; (void)fh; (void)buf; (void)len;
return SPIFFS_ERR_RO_NOT_IMPL; return SPIFFS_ERR_RO_NOT_IMPL;
...@@ -468,7 +481,6 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { ...@@ -468,7 +481,6 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
if ((fd->flags & SPIFFS_O_APPEND)) { if ((fd->flags & SPIFFS_O_APPEND)) {
fd->fdoffset = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size; fd->fdoffset = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size;
} }
offset = fd->fdoffset; offset = fd->fdoffset;
#if SPIFFS_CACHE_WR #if SPIFFS_CACHE_WR
...@@ -502,7 +514,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { ...@@ -502,7 +514,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 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 // boundary violation, write back cache first and allocate new
SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIpg" for fd "_SPIPRIfd":"_SPIPRIid", boundary viol, offs:"_SPIPRIi" size:"_SPIPRIi"\n", SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", boundary viol, offs:"_SPIPRIi" size:"_SPIPRIi"\n",
fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size);
res = spiffs_hydro_write(fs, fd, res = spiffs_hydro_write(fs, fd,
spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix),
...@@ -520,19 +532,30 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { ...@@ -520,19 +532,30 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
if (fd->cache_page) { if (fd->cache_page) {
fd->cache_page->offset = offset; fd->cache_page->offset = offset;
fd->cache_page->size = 0; fd->cache_page->size = 0;
SPIFFS_CACHE_DBG("CACHE_WR_ALLO: allocating cache page "_SPIPRIpg" for fd "_SPIPRIfd":"_SPIPRIid"\n", SPIFFS_CACHE_DBG("CACHE_WR_ALLO: allocating cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid"\n",
fd->cache_page->ix, fd->file_nbr, fd->obj_id); fd->cache_page->ix, fd->file_nbr, fd->obj_id);
} }
} }
if (fd->cache_page) { if (fd->cache_page) {
u32_t offset_in_cpage = offset - fd->cache_page->offset; u32_t offset_in_cpage = offset - fd->cache_page->offset;
SPIFFS_CACHE_DBG("CACHE_WR_WRITE: storing to cache page "_SPIPRIpg" for fd "_SPIPRIfd":"_SPIPRIid", offs "_SPIPRIi":"_SPIPRIi" len "_SPIPRIi"\n", SPIFFS_CACHE_DBG("CACHE_WR_WRITE: storing to cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", offs "_SPIPRIi":"_SPIPRIi" len "_SPIPRIi"\n",
fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->ix, fd->file_nbr, fd->obj_id,
offset, offset_in_cpage, len); offset, offset_in_cpage, len);
spiffs_cache *cache = spiffs_get_cache(fs); spiffs_cache *cache = spiffs_get_cache(fs);
u8_t *cpage_data = spiffs_get_cache_page(fs, cache, fd->cache_page->ix); u8_t *cpage_data = spiffs_get_cache_page(fs, cache, fd->cache_page->ix);
memcpy(&cpage_data[offset_in_cpage], buf, len); #ifdef _SPIFFS_TEST
{
intptr_t __a1 = (u8_t*)&cpage_data[offset_in_cpage]-(u8_t*)cache;
intptr_t __a2 = (u8_t*)&cpage_data[offset_in_cpage]+len-(u8_t*)cache;
intptr_t __b = sizeof(spiffs_cache) + cache->cpage_count * (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs));
if (__a1 > __b || __a2 > __b) {
printf("FATAL OOB: CACHE_WR: memcpy to cache buffer ixs:%4ld..%4ld of %4ld\n", __a1, __a2, __b);
ERREXIT();
}
}
#endif
_SPIFFS_MEMCPY(&cpage_data[offset_in_cpage], buf, len);
fd->cache_page->size = MAX(fd->cache_page->size, offset_in_cpage + len); fd->cache_page->size = MAX(fd->cache_page->size, offset_in_cpage + len);
fd->fdoffset += len; fd->fdoffset += len;
SPIFFS_UNLOCK(fs); SPIFFS_UNLOCK(fs);
...@@ -548,7 +571,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { ...@@ -548,7 +571,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 // big write, no need to cache it - but first check if there is a cached write already
if (fd->cache_page) { if (fd->cache_page) {
// write back cache first // write back cache first
SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIpg" for fd "_SPIPRIfd":"_SPIPRIid", big write, offs:"_SPIPRIi" size:"_SPIPRIi"\n", SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", big write, offs:"_SPIPRIi" size:"_SPIPRIi"\n",
fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size);
res = spiffs_hydro_write(fs, fd, res = spiffs_hydro_write(fs, fd,
spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix),
...@@ -572,6 +595,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { ...@@ -572,6 +595,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) {
} }
s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) { s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi " %s\n", __func__, fh, offs, (const char* []){"SET","CUR","END","???"}[MIN(whence,3)]);
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
SPIFFS_LOCK(fs); SPIFFS_LOCK(fs);
...@@ -586,24 +610,26 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) { ...@@ -586,24 +610,26 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
spiffs_fflush_cache(fs, fh); spiffs_fflush_cache(fs, fh);
#endif #endif
s32_t fileSize = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size; s32_t file_size = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size;
switch (whence) { switch (whence) {
case SPIFFS_SEEK_CUR: case SPIFFS_SEEK_CUR:
offs = fd->fdoffset+offs; offs = fd->fdoffset+offs;
break; break;
case SPIFFS_SEEK_END: case SPIFFS_SEEK_END:
offs = fileSize + offs; offs = file_size + offs;
break; break;
} }
if (offs < 0) {
if ((offs > fileSize)) { SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_SEEK_BOUNDS);
fd->fdoffset = fileSize; }
if (offs > file_size) {
fd->fdoffset = file_size;
res = SPIFFS_ERR_END_OF_OBJECT; res = SPIFFS_ERR_END_OF_OBJECT;
} }
SPIFFS_API_CHECK_RES_UNLOCK(fs, res); SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
spiffs_span_ix data_spix = offs / SPIFFS_DATA_PAGE_SIZE(fs); spiffs_span_ix data_spix = (offs > 0 ? (offs-1) : 0) / SPIFFS_DATA_PAGE_SIZE(fs);
spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix);
if (fd->cursor_objix_spix != objix_spix) { if (fd->cursor_objix_spix != objix_spix) {
spiffs_page_ix pix; spiffs_page_ix pix;
...@@ -621,6 +647,7 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) { ...@@ -621,6 +647,7 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
} }
s32_t SPIFFS_remove(spiffs *fs, const char *path) { s32_t SPIFFS_remove(spiffs *fs, const char *path) {
SPIFFS_API_DBG("%s '%s'\n", __func__, path);
#if SPIFFS_READ_ONLY #if SPIFFS_READ_ONLY
(void)fs; (void)path; (void)fs; (void)path;
return SPIFFS_ERR_RO_NOT_IMPL; return SPIFFS_ERR_RO_NOT_IMPL;
...@@ -663,6 +690,7 @@ s32_t SPIFFS_remove(spiffs *fs, const char *path) { ...@@ -663,6 +690,7 @@ s32_t SPIFFS_remove(spiffs *fs, const char *path) {
} }
s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) { s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) {
SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh);
#if SPIFFS_READ_ONLY #if SPIFFS_READ_ONLY
(void)fs; (void)fh; (void)fs; (void)fh;
return SPIFFS_ERR_RO_NOT_IMPL; return SPIFFS_ERR_RO_NOT_IMPL;
...@@ -716,13 +744,14 @@ static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spi ...@@ -716,13 +744,14 @@ static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spi
s->pix = pix; s->pix = pix;
strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN); strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN);
#if SPIFFS_OBJ_META_LEN #if SPIFFS_OBJ_META_LEN
memcpy(s->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN); _SPIFFS_MEMCPY(s->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN);
#endif #endif
return res; return res;
} }
s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s) { s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s) {
SPIFFS_API_DBG("%s '%s'\n", __func__, path);
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) {
...@@ -744,6 +773,7 @@ s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s) { ...@@ -744,6 +773,7 @@ s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s) {
} }
s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) { s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) {
SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh);
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
SPIFFS_LOCK(fs); SPIFFS_LOCK(fs);
...@@ -785,7 +815,7 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) { ...@@ -785,7 +815,7 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) {
fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd);
} }
if (fd->cache_page) { if (fd->cache_page) {
SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIpg" for fd "_SPIPRIfd":"_SPIPRIid", flush, offs:"_SPIPRIi" size:"_SPIPRIi"\n", SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page "_SPIPRIi" for fd "_SPIPRIfd":"_SPIPRIid", flush, offs:"_SPIPRIi" size:"_SPIPRIi"\n",
fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size);
res = spiffs_hydro_write(fs, fd, res = spiffs_hydro_write(fs, fd,
spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix),
...@@ -803,6 +833,7 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) { ...@@ -803,6 +833,7 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) {
#endif #endif
s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) { s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) {
SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh);
(void)fh; (void)fh;
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
...@@ -819,6 +850,7 @@ s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) { ...@@ -819,6 +850,7 @@ s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) {
} }
s32_t SPIFFS_close(spiffs *fs, spiffs_file fh) { s32_t SPIFFS_close(spiffs *fs, spiffs_file fh) {
SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh);
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
...@@ -839,6 +871,7 @@ s32_t SPIFFS_close(spiffs *fs, spiffs_file fh) { ...@@ -839,6 +871,7 @@ s32_t SPIFFS_close(spiffs *fs, spiffs_file fh) {
} }
s32_t SPIFFS_rename(spiffs *fs, const char *old_path, const char *new_path) { s32_t SPIFFS_rename(spiffs *fs, const char *old_path, const char *new_path) {
SPIFFS_API_DBG("%s %s %s\n", __func__, old_path, new_path);
#if SPIFFS_READ_ONLY #if SPIFFS_READ_ONLY
(void)fs; (void)old_path; (void)new_path; (void)fs; (void)old_path; (void)new_path;
return SPIFFS_ERR_RO_NOT_IMPL; return SPIFFS_ERR_RO_NOT_IMPL;
...@@ -965,6 +998,7 @@ s32_t SPIFFS_fupdate_meta(spiffs *fs, spiffs_file fh, const void *meta) { ...@@ -965,6 +998,7 @@ s32_t SPIFFS_fupdate_meta(spiffs *fs, spiffs_file fh, const void *meta) {
#endif // SPIFFS_OBJ_META_LEN #endif // SPIFFS_OBJ_META_LEN
spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d) { spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d) {
SPIFFS_API_DBG("%s\n", __func__);
(void)name; (void)name;
if (!SPIFFS_CHECK_CFG((fs))) { if (!SPIFFS_CHECK_CFG((fs))) {
...@@ -1013,7 +1047,7 @@ static s32_t spiffs_read_dir_v( ...@@ -1013,7 +1047,7 @@ static s32_t spiffs_read_dir_v(
e->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; e->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size;
e->pix = pix; e->pix = pix;
#if SPIFFS_OBJ_META_LEN #if SPIFFS_OBJ_META_LEN
memcpy(e->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN); _SPIFFS_MEMCPY(e->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN);
#endif #endif
return SPIFFS_OK; return SPIFFS_OK;
} }
...@@ -1021,6 +1055,7 @@ static s32_t spiffs_read_dir_v( ...@@ -1021,6 +1055,7 @@ static s32_t spiffs_read_dir_v(
} }
struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) { struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) {
SPIFFS_API_DBG("%s\n", __func__);
if (!SPIFFS_CHECK_MOUNT(d->fs)) { if (!SPIFFS_CHECK_MOUNT(d->fs)) {
d->fs->err_code = SPIFFS_ERR_NOT_MOUNTED; d->fs->err_code = SPIFFS_ERR_NOT_MOUNTED;
return 0; return 0;
...@@ -1055,12 +1090,14 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) { ...@@ -1055,12 +1090,14 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) {
} }
s32_t SPIFFS_closedir(spiffs_DIR *d) { s32_t SPIFFS_closedir(spiffs_DIR *d) {
SPIFFS_API_DBG("%s\n", __func__);
SPIFFS_API_CHECK_CFG(d->fs); SPIFFS_API_CHECK_CFG(d->fs);
SPIFFS_API_CHECK_MOUNT(d->fs); SPIFFS_API_CHECK_MOUNT(d->fs);
return 0; return 0;
} }
s32_t SPIFFS_check(spiffs *fs) { s32_t SPIFFS_check(spiffs *fs) {
SPIFFS_API_DBG("%s\n", __func__);
#if SPIFFS_READ_ONLY #if SPIFFS_READ_ONLY
(void)fs; (void)fs;
return SPIFFS_ERR_RO_NOT_IMPL; return SPIFFS_ERR_RO_NOT_IMPL;
...@@ -1084,6 +1121,7 @@ s32_t SPIFFS_check(spiffs *fs) { ...@@ -1084,6 +1121,7 @@ s32_t SPIFFS_check(spiffs *fs) {
} }
s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) { s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) {
SPIFFS_API_DBG("%s\n", __func__);
s32_t res = SPIFFS_OK; s32_t res = SPIFFS_OK;
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
...@@ -1108,6 +1146,7 @@ s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) { ...@@ -1108,6 +1146,7 @@ s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) {
} }
s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages) { s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages) {
SPIFFS_API_DBG("%s "_SPIPRIi "\n", __func__, max_free_pages);
#if SPIFFS_READ_ONLY #if SPIFFS_READ_ONLY
(void)fs; (void)max_free_pages; (void)fs; (void)max_free_pages;
return SPIFFS_ERR_RO_NOT_IMPL; return SPIFFS_ERR_RO_NOT_IMPL;
...@@ -1127,6 +1166,7 @@ s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages) { ...@@ -1127,6 +1166,7 @@ s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages) {
s32_t SPIFFS_gc(spiffs *fs, u32_t size) { s32_t SPIFFS_gc(spiffs *fs, u32_t size) {
SPIFFS_API_DBG("%s "_SPIPRIi "\n", __func__, size);
#if SPIFFS_READ_ONLY #if SPIFFS_READ_ONLY
(void)fs; (void)size; (void)fs; (void)size;
return SPIFFS_ERR_RO_NOT_IMPL; return SPIFFS_ERR_RO_NOT_IMPL;
...@@ -1145,6 +1185,7 @@ s32_t SPIFFS_gc(spiffs *fs, u32_t size) { ...@@ -1145,6 +1185,7 @@ s32_t SPIFFS_gc(spiffs *fs, u32_t size) {
} }
s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) { s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) {
SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh);
s32_t res; s32_t res;
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
...@@ -1168,6 +1209,7 @@ s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) { ...@@ -1168,6 +1209,7 @@ s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) {
} }
s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) { s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) {
SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh);
s32_t res; s32_t res;
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
...@@ -1191,6 +1233,7 @@ s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) { ...@@ -1191,6 +1233,7 @@ s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) {
} }
s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func) { s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func) {
SPIFFS_API_DBG("%s\n", __func__);
SPIFFS_LOCK(fs); SPIFFS_LOCK(fs);
fs->file_cb_f = cb_func; fs->file_cb_f = cb_func;
SPIFFS_UNLOCK(fs); SPIFFS_UNLOCK(fs);
...@@ -1201,6 +1244,7 @@ s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func) { ...@@ -1201,6 +1244,7 @@ s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func) {
s32_t SPIFFS_ix_map(spiffs *fs, spiffs_file fh, spiffs_ix_map *map, s32_t SPIFFS_ix_map(spiffs *fs, spiffs_file fh, spiffs_ix_map *map,
u32_t offset, u32_t len, spiffs_page_ix *map_buf) { u32_t offset, u32_t len, spiffs_page_ix *map_buf) {
SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi " "_SPIPRIi "\n", __func__, fh, offset, len);
s32_t res; s32_t res;
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
...@@ -1233,6 +1277,7 @@ s32_t SPIFFS_ix_map(spiffs *fs, spiffs_file fh, spiffs_ix_map *map, ...@@ -1233,6 +1277,7 @@ s32_t SPIFFS_ix_map(spiffs *fs, spiffs_file fh, spiffs_ix_map *map,
} }
s32_t SPIFFS_ix_unmap(spiffs *fs, spiffs_file fh) { s32_t SPIFFS_ix_unmap(spiffs *fs, spiffs_file fh) {
SPIFFS_API_DBG("%s "_SPIPRIfd "\n", __func__, fh);
s32_t res; s32_t res;
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
...@@ -1255,6 +1300,7 @@ s32_t SPIFFS_ix_unmap(spiffs *fs, spiffs_file fh) { ...@@ -1255,6 +1300,7 @@ s32_t SPIFFS_ix_unmap(spiffs *fs, spiffs_file fh) {
} }
s32_t SPIFFS_ix_remap(spiffs *fs, spiffs_file fh, u32_t offset) { s32_t SPIFFS_ix_remap(spiffs *fs, spiffs_file fh, u32_t offset) {
SPIFFS_API_DBG("%s "_SPIPRIfd " "_SPIPRIi "\n", __func__, fh, offset);
s32_t res = SPIFFS_OK; s32_t res = SPIFFS_OK;
SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_CFG(fs);
SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_API_CHECK_MOUNT(fs);
......
...@@ -270,7 +270,7 @@ s32_t spiffs_probe( ...@@ -270,7 +270,7 @@ s32_t spiffs_probe(
s32_t res; s32_t res;
u32_t paddr; u32_t paddr;
spiffs dummy_fs; // create a dummy fs struct just to be able to use macros spiffs dummy_fs; // create a dummy fs struct just to be able to use macros
memcpy(&dummy_fs.cfg, cfg, sizeof(spiffs_config)); _SPIFFS_MEMCPY(&dummy_fs.cfg, cfg, sizeof(spiffs_config));
dummy_fs.block_count = 0; dummy_fs.block_count = 0;
// Read three magics, as one block may be in an aborted erase state. // Read three magics, as one block may be in an aborted erase state.
...@@ -713,8 +713,8 @@ s32_t spiffs_populate_ix_map(spiffs *fs, spiffs_fd *fd, u32_t vec_entry_start, u ...@@ -713,8 +713,8 @@ s32_t spiffs_populate_ix_map(spiffs *fs, spiffs_fd *fd, u32_t vec_entry_start, u
s32_t res; s32_t res;
spiffs_ix_map *map = fd->ix_map; spiffs_ix_map *map = fd->ix_map;
spiffs_ix_map_populate_state state; spiffs_ix_map_populate_state state;
vec_entry_start = MIN((map->end_spix - map->start_spix + 1) - 1, (s32_t)vec_entry_start); vec_entry_start = MIN((u32_t)(map->end_spix - map->start_spix), vec_entry_start);
vec_entry_end = MAX((map->end_spix - map->start_spix + 1) - 1, (s32_t)vec_entry_end); vec_entry_end = MAX((u32_t)(map->end_spix - map->start_spix), vec_entry_end);
if (vec_entry_start > vec_entry_end) { if (vec_entry_start > vec_entry_end) {
return SPIFFS_ERR_IX_MAP_BAD_RANGE; return SPIFFS_ERR_IX_MAP_BAD_RANGE;
} }
...@@ -877,8 +877,6 @@ s32_t spiffs_page_delete( ...@@ -877,8 +877,6 @@ s32_t spiffs_page_delete(
spiffs *fs, spiffs *fs,
spiffs_page_ix pix) { spiffs_page_ix pix) {
s32_t res; s32_t res;
spiffs_page_header hdr;
hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED);
// mark deleted entry in source object lookup // mark deleted entry in source object lookup
spiffs_obj_id d_obj_id = SPIFFS_OBJ_ID_DELETED; spiffs_obj_id d_obj_id = SPIFFS_OBJ_ID_DELETED;
res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_DELE, res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_DELE,
...@@ -892,11 +890,18 @@ s32_t spiffs_page_delete( ...@@ -892,11 +890,18 @@ s32_t spiffs_page_delete(
fs->stats_p_allocated--; fs->stats_p_allocated--;
// mark deleted in source page // mark deleted in source page
u8_t flags = 0xff;
#if SPIFFS_NO_BLIND_WRITES
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ,
0, SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags),
sizeof(flags), &flags);
SPIFFS_CHECK_RES(res);
#endif
flags &= ~(SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED);
res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_DELE, res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_DELE,
0, 0,
SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags), SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags),
sizeof(u8_t), sizeof(flags), &flags);
(u8_t *)&hdr.flags);
return res; return res;
} }
...@@ -942,7 +947,7 @@ s32_t spiffs_object_create( ...@@ -942,7 +947,7 @@ s32_t spiffs_object_create(
strncpy((char*)oix_hdr.name, (const char*)name, SPIFFS_OBJ_NAME_LEN); strncpy((char*)oix_hdr.name, (const char*)name, SPIFFS_OBJ_NAME_LEN);
#if SPIFFS_OBJ_META_LEN #if SPIFFS_OBJ_META_LEN
if (meta) { if (meta) {
memcpy(oix_hdr.meta, meta, SPIFFS_OBJ_META_LEN); _SPIFFS_MEMCPY(oix_hdr.meta, meta, SPIFFS_OBJ_META_LEN);
} else { } else {
memset(oix_hdr.meta, 0xff, SPIFFS_OBJ_META_LEN); memset(oix_hdr.meta, 0xff, SPIFFS_OBJ_META_LEN);
} }
...@@ -1006,7 +1011,7 @@ s32_t spiffs_object_update_index_hdr( ...@@ -1006,7 +1011,7 @@ s32_t spiffs_object_update_index_hdr(
} }
#if SPIFFS_OBJ_META_LEN #if SPIFFS_OBJ_META_LEN
if (meta) { if (meta) {
memcpy(objix_hdr->meta, meta, SPIFFS_OBJ_META_LEN); _SPIFFS_MEMCPY(objix_hdr->meta, meta, SPIFFS_OBJ_META_LEN);
} }
#else #else
(void) meta; (void) meta;
...@@ -1048,34 +1053,66 @@ void spiffs_cb_object_event( ...@@ -1048,34 +1053,66 @@ void spiffs_cb_object_event(
spiffs_obj_id obj_id = obj_id_raw & ~SPIFFS_OBJ_ID_IX_FLAG; spiffs_obj_id obj_id = obj_id_raw & ~SPIFFS_OBJ_ID_IX_FLAG;
u32_t i; u32_t i;
spiffs_fd *fds = (spiffs_fd *)fs->fd_space; spiffs_fd *fds = (spiffs_fd *)fs->fd_space;
SPIFFS_DBG(" CALLBACK %s obj_id:"_SPIPRIid" spix:"_SPIPRIsp" npix:"_SPIPRIpg" nsz:"_SPIPRIi"\n", (const char *[]){"UPD", "NEW", "DEL", "MOV", "HUP","???"}[MIN(ev,5)],
obj_id_raw, spix, new_pix, new_size);
for (i = 0; i < fs->fd_count; i++) { for (i = 0; i < fs->fd_count; i++) {
spiffs_fd *cur_fd = &fds[i]; spiffs_fd *cur_fd = &fds[i];
#if SPIFFS_TEMPORAL_FD_CACHE if ((cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; // fd not related to updated file
if (cur_fd->score == 0 || (cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; #if !SPIFFS_TEMPORAL_FD_CACHE
#else if (cur_fd->file_nbr == 0) continue; // fd closed
if (cur_fd->file_nbr == 0 || (cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue;
#endif #endif
if (spix == 0) { if (spix == 0) { // object index header update
if (ev != SPIFFS_EV_IX_DEL) { if (ev != SPIFFS_EV_IX_DEL) {
SPIFFS_DBG(" callback: setting fd "_SPIPRIfd":"_SPIPRIid" objix_hdr_pix to "_SPIPRIpg", size:"_SPIPRIi"\n", cur_fd->file_nbr, cur_fd->obj_id, new_pix, new_size); #if SPIFFS_TEMPORAL_FD_CACHE
if (cur_fd->score == 0) continue; // never used fd
#endif
SPIFFS_DBG(" callback: setting fd "_SPIPRIfd":"_SPIPRIid"(fdoffs:"_SPIPRIi" offs:"_SPIPRIi") objix_hdr_pix to "_SPIPRIpg", size:"_SPIPRIi"\n",
SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, cur_fd->fdoffset, cur_fd->offset, new_pix, new_size);
cur_fd->objix_hdr_pix = new_pix; cur_fd->objix_hdr_pix = new_pix;
if (new_size != 0) { if (new_size != 0) {
// update size and offsets for fds to this file
cur_fd->size = new_size; cur_fd->size = new_size;
u32_t act_new_size = new_size == SPIFFS_UNDEFINED_LEN ? 0 : new_size;
#if SPIFFS_CACHE_WR
if (act_new_size > 0 && cur_fd->cache_page) {
act_new_size = MAX(act_new_size, cur_fd->cache_page->offset + cur_fd->cache_page->size);
}
#endif
if (cur_fd->offset > act_new_size) {
cur_fd->offset = act_new_size;
}
if (cur_fd->fdoffset > act_new_size) {
cur_fd->fdoffset = act_new_size;
}
#if SPIFFS_CACHE_WR
if (cur_fd->cache_page && cur_fd->cache_page->offset > act_new_size+1) {
SPIFFS_CACHE_DBG("CACHE_DROP: file trunced, dropping cache page "_SPIPRIi", no writeback\n", cur_fd->cache_page->ix);
spiffs_cache_fd_release(fs, cur_fd->cache_page);
}
#endif
} }
} else { } else {
// removing file
#if SPIFFS_CACHE_WR
if (cur_fd->file_nbr && cur_fd->cache_page) {
SPIFFS_CACHE_DBG("CACHE_DROP: file deleted, dropping cache page "_SPIPRIi", no writeback\n", cur_fd->cache_page->ix);
spiffs_cache_fd_release(fs, cur_fd->cache_page);
}
#endif
SPIFFS_DBG(" callback: release fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp" objix_pix to "_SPIPRIpg"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix, new_pix);
cur_fd->file_nbr = 0; cur_fd->file_nbr = 0;
cur_fd->obj_id = SPIFFS_OBJ_ID_DELETED; cur_fd->obj_id = SPIFFS_OBJ_ID_DELETED;
} }
} } // object index header update
if (cur_fd->cursor_objix_spix == spix) { if (cur_fd->cursor_objix_spix == spix) {
if (ev != SPIFFS_EV_IX_DEL) { if (ev != SPIFFS_EV_IX_DEL) {
SPIFFS_DBG(" callback: setting fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp" objix_pix to "_SPIPRIpg"\n", cur_fd->file_nbr, cur_fd->obj_id, spix, new_pix); SPIFFS_DBG(" callback: setting fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp" objix_pix to "_SPIPRIpg"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix, new_pix);
cur_fd->cursor_objix_pix = new_pix; cur_fd->cursor_objix_pix = new_pix;
} else { } else {
cur_fd->cursor_objix_pix = 0; cur_fd->cursor_objix_pix = 0;
} }
} }
} } // fd update loop
#if SPIFFS_IX_MAP #if SPIFFS_IX_MAP
...@@ -1087,7 +1124,7 @@ void spiffs_cb_object_event( ...@@ -1087,7 +1124,7 @@ void spiffs_cb_object_event(
if (cur_fd->file_nbr == 0 || if (cur_fd->file_nbr == 0 ||
cur_fd->ix_map == 0 || cur_fd->ix_map == 0 ||
(cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; (cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue;
SPIFFS_DBG(" callback: map ix update fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp"\n", cur_fd->file_nbr, cur_fd->obj_id, spix); SPIFFS_DBG(" callback: map ix update fd "_SPIPRIfd":"_SPIPRIid" span:"_SPIPRIsp"\n", SPIFFS_FH_OFFS(fs, cur_fd->file_nbr), cur_fd->obj_id, spix);
spiffs_update_ix_map(fs, cur_fd, spix, objix); spiffs_update_ix_map(fs, cur_fd, spix, objix);
} }
} }
...@@ -1164,7 +1201,7 @@ s32_t spiffs_object_open_by_page( ...@@ -1164,7 +1201,7 @@ s32_t spiffs_object_open_by_page(
SPIFFS_VALIDATE_OBJIX(oix_hdr.p_hdr, fd->obj_id, 0); SPIFFS_VALIDATE_OBJIX(oix_hdr.p_hdr, fd->obj_id, 0);
SPIFFS_DBG("open: fd "_SPIPRIfd" is obj id "_SPIPRIid"\n", fd->file_nbr, fd->obj_id); SPIFFS_DBG("open: fd "_SPIPRIfd" is obj id "_SPIPRIid"\n", SPIFFS_FH_OFFS(fs, fd->file_nbr), fd->obj_id);
return res; return res;
} }
...@@ -1275,7 +1312,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { ...@@ -1275,7 +1312,7 @@ s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) {
SPIFFS_CHECK_RES(res); SPIFFS_CHECK_RES(res);
// quick "load" of new object index page // quick "load" of new object index page
memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs));
memcpy(fs->work, &p_hdr, sizeof(spiffs_page_header)); _SPIFFS_MEMCPY(fs->work, &p_hdr, sizeof(spiffs_page_header));
spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work, spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work,
SPIFFS_EV_IX_NEW, fd->obj_id, cur_objix_spix, cur_objix_pix, 0); SPIFFS_EV_IX_NEW, fd->obj_id, cur_objix_spix, cur_objix_pix, 0);
SPIFFS_DBG("append: "_SPIPRIid" create objix page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id SPIFFS_DBG("append: "_SPIPRIid" create objix page, "_SPIPRIpg":"_SPIPRIsp", written "_SPIPRIi"\n", fd->obj_id
...@@ -2222,7 +2259,7 @@ s32_t spiffs_fd_find_new(spiffs *fs, spiffs_fd **fd, const char *name) { ...@@ -2222,7 +2259,7 @@ s32_t spiffs_fd_find_new(spiffs *fs, spiffs_fd **fd, const char *name) {
} }
} }
// find the free fd with least score // find the free fd with least score or name match
for (i = 0; i < fs->fd_count; i++) { for (i = 0; i < fs->fd_count; i++) {
spiffs_fd *cur_fd = &fds[i]; spiffs_fd *cur_fd = &fds[i];
if (cur_fd->file_nbr == 0) { if (cur_fd->file_nbr == 0) {
......
...@@ -141,6 +141,22 @@ ...@@ -141,6 +141,22 @@
#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0) #define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0)
#define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1) #define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1)
#if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
/* For GCC, clang and TI compilers */
#define SPIFFS_PACKED __attribute__((packed))
#elif defined(__ICCARM__) || defined(__CC_ARM)
/* For IAR ARM and Keil MDK-ARM compilers */
#define SPIFFS_PACKED
#else
/* Unknown compiler */
#define SPIFFS_PACKED
#endif
#if SPIFFS_USE_MAGIC #if SPIFFS_USE_MAGIC
#if !SPIFFS_USE_MAGIC_LENGTH #if !SPIFFS_USE_MAGIC_LENGTH
#define SPIFFS_MAGIC(fs, bix) \ #define SPIFFS_MAGIC(fs, bix) \
...@@ -242,6 +258,15 @@ ...@@ -242,6 +258,15 @@
#define SPIFFS_DATA_SPAN_IX_FOR_OBJ_IX_SPAN_IX(fs, spix) \ #define SPIFFS_DATA_SPAN_IX_FOR_OBJ_IX_SPAN_IX(fs, spix) \
( (spix) == 0 ? 0 : (SPIFFS_OBJ_HDR_IX_LEN(fs) + (((spix)-1) * SPIFFS_OBJ_IX_LEN(fs))) ) ( (spix) == 0 ? 0 : (SPIFFS_OBJ_HDR_IX_LEN(fs) + (((spix)-1) * SPIFFS_OBJ_IX_LEN(fs))) )
#if SPIFFS_FILEHDL_OFFSET
#define SPIFFS_FH_OFFS(fs, fh) ((fh) != 0 ? ((fh) + (fs)->cfg.fh_ix_offset) : 0)
#define SPIFFS_FH_UNOFFS(fs, fh) ((fh) != 0 ? ((fh) - (fs)->cfg.fh_ix_offset) : 0)
#else
#define SPIFFS_FH_OFFS(fs, fh) (fh)
#define SPIFFS_FH_UNOFFS(fs, fh) (fh)
#endif
#define SPIFFS_OP_T_OBJ_LU (0<<0) #define SPIFFS_OP_T_OBJ_LU (0<<0)
#define SPIFFS_OP_T_OBJ_LU2 (1<<0) #define SPIFFS_OP_T_OBJ_LU2 (1<<0)
#define SPIFFS_OP_T_OBJ_IX (2<<0) #define SPIFFS_OP_T_OBJ_IX (2<<0)
...@@ -430,7 +455,7 @@ typedef struct { ...@@ -430,7 +455,7 @@ typedef struct {
spiffs_span_ix cursor_objix_spix; spiffs_span_ix cursor_objix_spix;
// current absolute offset // current absolute offset
u32_t offset; u32_t offset;
// current file descriptor offset // current file descriptor offset (cached)
u32_t fdoffset; u32_t fdoffset;
// fd flags // fd flags
spiffs_flags flags; spiffs_flags flags;
...@@ -455,7 +480,7 @@ typedef struct { ...@@ -455,7 +480,7 @@ typedef struct {
// page header, part of each page except object lookup pages // page header, part of each page except object lookup pages
// NB: this is always aligned when the data page is an object index, // NB: this is always aligned when the data page is an object index,
// as in this case struct spiffs_page_object_ix is used // as in this case struct spiffs_page_object_ix is used
typedef struct __attribute(( packed )) { typedef struct SPIFFS_PACKED {
// object id // object id
spiffs_obj_id obj_id; spiffs_obj_id obj_id;
// object span index // object span index
...@@ -465,7 +490,7 @@ typedef struct __attribute(( packed )) { ...@@ -465,7 +490,7 @@ typedef struct __attribute(( packed )) {
} spiffs_page_header; } spiffs_page_header;
// object index header page header // object index header page header
typedef struct __attribute(( packed )) typedef struct SPIFFS_PACKED
#if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES #if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
__attribute(( aligned(sizeof(spiffs_page_ix)) )) __attribute(( aligned(sizeof(spiffs_page_ix)) ))
#endif #endif
...@@ -487,7 +512,7 @@ typedef struct __attribute(( packed )) ...@@ -487,7 +512,7 @@ typedef struct __attribute(( packed ))
} spiffs_page_object_ix_header; } spiffs_page_object_ix_header;
// object index page header // object index page header
typedef struct __attribute(( packed )) { typedef struct SPIFFS_PACKED {
spiffs_page_header p_hdr; 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; } spiffs_page_object_ix;
...@@ -794,4 +819,24 @@ s32_t spiffs_page_consistency_check( ...@@ -794,4 +819,24 @@ s32_t spiffs_page_consistency_check(
s32_t spiffs_object_index_consistency_check( s32_t spiffs_object_index_consistency_check(
spiffs *fs); spiffs *fs);
// memcpy macro,
// checked in test builds, otherwise plain memcpy (unless already defined)
#ifdef _SPIFFS_TEST
#define _SPIFFS_MEMCPY(__d, __s, __l) do { \
intptr_t __a1 = (intptr_t)((u8_t*)(__s)); \
intptr_t __a2 = (intptr_t)((u8_t*)(__s)+(__l)); \
intptr_t __b1 = (intptr_t)((u8_t*)(__d)); \
intptr_t __b2 = (intptr_t)((u8_t*)(__d)+(__l)); \
if (__a1 <= __b2 && __b1 <= __a2) { \
printf("FATAL OVERLAP: memcpy from %lx..%lx to %lx..%lx\n", __a1, __a2, __b1, __b2); \
ERREXIT(); \
} \
memcpy((__d),(__s),(__l)); \
} while (0)
#else
#ifndef _SPIFFS_MEMCPY
#define _SPIFFS_MEMCPY(__d, __s, __l) do{memcpy((__d),(__s),(__l));}while(0)
#endif
#endif //_SPIFFS_TEST
#endif /* SPIFFS_NUCLEUS_H_ */ #endif /* SPIFFS_NUCLEUS_H_ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment