mirror of
https://github.com/pellepl/spiffs.git
synced 2026-10-19 14:08:10 +00:00
gc check preempts gc, truncate even less picky
This commit is contained in:
@@ -30,7 +30,7 @@
|
||||
#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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -330,7 +330,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 %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),
|
||||
@@ -382,6 +382,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_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);
|
||||
}
|
||||
|
||||
+22
-6
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ void teardown() {
|
||||
_teardown();
|
||||
}
|
||||
|
||||
TEST(nodemcu_full_fs) {
|
||||
fs_reset_specific(0, 65536, 4096, 4096, 256);
|
||||
TEST(nodemcu_full_fs_1) {
|
||||
fs_reset_specific(0, 4096*20, 4096, 4096, 256);
|
||||
|
||||
int res;
|
||||
spiffs_file fd;
|
||||
@@ -38,7 +38,7 @@ TEST(nodemcu_full_fs) {
|
||||
int i;
|
||||
spiffs_stat s;
|
||||
res = SPIFFS_OK;
|
||||
for (i = 0; res >= 0 && SPIFFS_errno(FS) == SPIFFS_OK && i < 100*1000; i++) {
|
||||
for (i = 0; i < 100*1000; i++) {
|
||||
u8_t buf = 'x';
|
||||
res = SPIFFS_write(FS, fd, &buf, 1);
|
||||
}
|
||||
@@ -51,10 +51,11 @@ TEST(nodemcu_full_fs) {
|
||||
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);
|
||||
@@ -82,6 +83,78 @@ TEST(nodemcu_full_fs) {
|
||||
|
||||
return TEST_RES_OK;
|
||||
|
||||
} TEST_END(nodemcu_full_fs)
|
||||
} 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)
|
||||
|
||||
Reference in New Issue
Block a user