Skip to content

Commit

Permalink
fix bugs for spiffs from pellepl/spiffs
Browse files Browse the repository at this point in the history
  • Loading branch information
funshine committed Mar 10, 2015
1 parent 43594cf commit 27c0620
Show file tree
Hide file tree
Showing 15 changed files with 3,301 additions and 8 deletions.
2 changes: 1 addition & 1 deletion app/spiffs/spiffs_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ typedef uint8_t u8_t;
#endif
// Set spiffs debug output call for caching.
#ifndef SPIFFS_CACHE_DGB
#define SPIFFS_CACHE_DBG(...) //printf("CA: " __VA_ARGS__)
#define SPIFFS_CACHE_DBG(...) //printf(__VA_ARGS__)
#endif
// Set spiffs debug output call for system consistency checks.
#ifndef SPIFFS_CHECK_DGB
Expand Down
5 changes: 5 additions & 0 deletions app/spiffs/spiffs_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ s32_t spiffs_gc_check(
return SPIFFS_OK;
}

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) {
return SPIFFS_ERR_FULL;
}

//printf("gcing started %i dirty, blocks %i free, want %i bytes\n", fs->stats_p_allocated + fs->stats_p_deleted, fs->free_blocks, len);

do {
Expand Down
3 changes: 2 additions & 1 deletion app/spiffs/spiffs_hydrogen.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, u32_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 %i for fd %i:&04x, boundary viol, offs:%i size:%i\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),
Expand Down Expand Up @@ -382,6 +382,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, u32_t len) {
spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix),
fd->cache_page->offset, fd->cache_page->size);
spiffs_cache_fd_release(fs, fd->cache_page);
SPIFFS_API_CHECK_RES(fs, res);
res = spiffs_hydro_write(fs, fd, buf, offset, len);
SPIFFS_API_CHECK_RES(fs, res);
}
Expand Down
28 changes: 22 additions & 6 deletions app/spiffs/spiffs_nucleus.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ s32_t spiffs_object_create(
spiffs_page_object_ix_header oix_hdr;
int entry;

res = spiffs_gc_check(fs, 0);
res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs));
SPIFFS_CHECK_RES(res);

obj_id |= SPIFFS_OBJ_ID_IX_FLAG;
Expand Down Expand Up @@ -811,7 +811,17 @@ 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: %i bytes @ offs %i of size %i\n", len, offset, fd->size);

if (offset > fd->size) {
SPIFFS_DBG("append: offset reversed to size\n");
offset = fd->size;
}

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 %i\n", res);
}
SPIFFS_CHECK_RES(res);

spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work;
Expand Down Expand Up @@ -1042,7 +1052,7 @@ s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) {
s32_t res = SPIFFS_OK;
u32_t written = 0;

res = spiffs_gc_check(fs, len);
res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs));
SPIFFS_CHECK_RES(res);

spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work;
Expand Down Expand Up @@ -1308,7 +1318,7 @@ s32_t spiffs_object_truncate(
s32_t res = SPIFFS_OK;
spiffs *fs = fd->fs;

res = spiffs_gc_check(fs, 0);
res = spiffs_gc_check(fs, remove ? 0 : SPIFFS_DATA_PAGE_SIZE(fs));
SPIFFS_CHECK_RES(res);

spiffs_page_ix objix_pix = fd->objix_hdr_pix;
Expand Down Expand Up @@ -1391,12 +1401,18 @@ s32_t spiffs_object_truncate(
if (cur_size - SPIFFS_DATA_PAGE_SIZE(fs) >= new_size) {
// delete full data page
res = spiffs_page_data_check(fs, fd, data_pix, data_spix);
if (res != SPIFFS_ERR_DELETED && res != SPIFFS_OK) break;
if (res != SPIFFS_ERR_DELETED && res != SPIFFS_OK && res != SPIFFS_ERR_INDEX_REF_FREE) {
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) break;
} else if (res == SPIFFS_ERR_DELETED) {
if (res != SPIFFS_OK) {
SPIFFS_DBG("truncate: err deleting data pix %i\n", res);
break;
}
} else if (res == SPIFFS_ERR_DELETED || res == SPIFFS_ERR_INDEX_REF_FREE) {
res = SPIFFS_OK;
}

Expand Down
7 changes: 7 additions & 0 deletions app/spiffs/test/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "testrunner.h"
#include <stdlib.h>

int main(int argc, char **args) {
run_tests(argc, args);
exit(EXIT_SUCCESS);
}
36 changes: 36 additions & 0 deletions app/spiffs/test/params_test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* params_test.h
*
* Created on: May 26, 2013
* Author: petera
*/

#ifndef PARAMS_TEST_H_
#define PARAMS_TEST_H_

// total emulated spi flash size
#define PHYS_FLASH_SIZE (16*1024*1024)
// spiffs file system size
#define SPIFFS_FLASH_SIZE (2*1024*1024)
// spiffs file system offset in emulated spi flash
#define SPIFFS_PHYS_ADDR (4*1024*1024)

#define SECTOR_SIZE 65536
#define LOG_BLOCK (SECTOR_SIZE*2)
#define LOG_PAGE (SECTOR_SIZE/256)

#define FD_BUF_SIZE 64*6
#define CACHE_BUF_SIZE (LOG_PAGE + 32)*8

#define ASSERT(c, m) real_assert((c),(m), __FILE__, __LINE__);

typedef signed int s32_t;
typedef unsigned int u32_t;
typedef signed short s16_t;
typedef unsigned short u16_t;
typedef signed char s8_t;
typedef unsigned char u8_t;

void real_assert(int c, const char *n, const char *file, int l);

#endif /* PARAMS_TEST_H_ */
160 changes: 160 additions & 0 deletions app/spiffs/test/test_bugreports.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* test_bugreports.c
*
* Created on: Mar 8, 2015
* Author: petera
*/



#include "testrunner.h"
#include "test_spiffs.h"
#include "spiffs_nucleus.h"
#include "spiffs.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>


SUITE(bug_tests)
void setup() {
_setup_test_only();
}
void teardown() {
_teardown();
}

TEST(nodemcu_full_fs_1) {
fs_reset_specific(0, 4096*20, 4096, 4096, 256);

int res;
spiffs_file fd;

printf(" fill up system by writing one byte a lot\n");
fd = SPIFFS_open(FS, "test1.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
TEST_CHECK(fd > 0);
int i;
spiffs_stat s;
res = SPIFFS_OK;
for (i = 0; i < 100*1000; i++) {
u8_t buf = 'x';
res = SPIFFS_write(FS, fd, &buf, 1);
}

int errno = SPIFFS_errno(FS);
int res2 = SPIFFS_fstat(FS, fd, &s);
TEST_CHECK(res2 == SPIFFS_OK);
printf(" >>> file %s size: %i\n", s.name, s.size);

TEST_CHECK(errno == SPIFFS_ERR_FULL);
SPIFFS_close(FS, fd);

printf(" remove big file\n");
res = SPIFFS_remove(FS, "test1.txt");

printf("res:%i errno:%i\n",res, SPIFFS_errno(FS));

TEST_CHECK(res == SPIFFS_OK);
res2 = SPIFFS_fstat(FS, fd, &s);
TEST_CHECK(res2 == -1);
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED);
res2 = SPIFFS_stat(FS, "test1.txt", &s);
TEST_CHECK(res2 == -1);
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND);

printf(" create small file\n");
fd = SPIFFS_open(FS, "test2.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
TEST_CHECK(fd > 0);
res = SPIFFS_OK;
for (i = 0; res >= 0 && i < 1000; i++) {
u8_t buf = 'x';
res = SPIFFS_write(FS, fd, &buf, 1);
}
TEST_CHECK(res >= SPIFFS_OK);

res2 = SPIFFS_fstat(FS, fd, &s);
TEST_CHECK(res2 == SPIFFS_OK);
printf(" >>> file %s size: %i\n", s.name, s.size);

TEST_CHECK(s.size == 1000);
SPIFFS_close(FS, fd);

return TEST_RES_OK;

} TEST_END(nodemcu_full_fs_1)

TEST(nodemcu_full_fs_2) {
fs_reset_specific(0, 4096*22, 4096, 4096, 256);

int res;
spiffs_file fd;

printf(" fill up system by writing one byte a lot\n");
fd = SPIFFS_open(FS, "test1.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
TEST_CHECK(fd > 0);
int i;
spiffs_stat s;
res = SPIFFS_OK;
for (i = 0; i < 100*1000; i++) {
u8_t buf = 'x';
res = SPIFFS_write(FS, fd, &buf, 1);
}

int errno = SPIFFS_errno(FS);
int res2 = SPIFFS_fstat(FS, fd, &s);
TEST_CHECK(res2 == SPIFFS_OK);
printf(" >>> file %s size: %i\n", s.name, s.size);

TEST_CHECK(errno == SPIFFS_ERR_FULL);
SPIFFS_close(FS, fd);

res2 = SPIFFS_stat(FS, "test1.txt", &s);
TEST_CHECK(res2 == SPIFFS_OK);

SPIFFS_clearerr(FS);
printf(" create small file\n");
fd = SPIFFS_open(FS, "test2.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK);
TEST_CHECK(fd > 0);

for (i = 0; i < 1000; i++) {
u8_t buf = 'x';
res = SPIFFS_write(FS, fd, &buf, 1);
}

TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FULL);
res2 = SPIFFS_fstat(FS, fd, &s);
TEST_CHECK(res2 == SPIFFS_OK);
printf(" >>> file %s size: %i\n", s.name, s.size);
TEST_CHECK(s.size == 0);
SPIFFS_clearerr(FS);

printf(" remove files\n");
res = SPIFFS_remove(FS, "test1.txt");
TEST_CHECK(res == SPIFFS_OK);
res = SPIFFS_remove(FS, "test2.txt");
TEST_CHECK(res == SPIFFS_OK);

printf(" create medium file\n");
fd = SPIFFS_open(FS, "test3.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0);
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK);
TEST_CHECK(fd > 0);

for (i = 0; i < 20*1000; i++) {
u8_t buf = 'x';
res = SPIFFS_write(FS, fd, &buf, 1);
}
TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK);

res2 = SPIFFS_fstat(FS, fd, &s);
TEST_CHECK(res2 == SPIFFS_OK);
printf(" >>> file %s size: %i\n", s.name, s.size);
TEST_CHECK(s.size == 20*1000);

return TEST_RES_OK;

} TEST_END(nodemcu_full_fs_2)

SUITE_END(bug_tests)
Loading

0 comments on commit 27c0620

Please sign in to comment.