From f81638cbc61419a79990a412c6766a30313d1640 Mon Sep 17 00:00:00 2001 From: Peter Andersson Date: Thu, 29 Jan 2015 11:20:14 +0100 Subject: [PATCH] added SPIFFS_open_by_dirent --- src/default/spiffs_config.h | 2 +- src/spiffs.h | 17 +++++++ src/spiffs_hydrogen.c | 32 +++++++++++++- src/test/test_hydrogen.c | 88 ++++++++++++++++++++++++++++++++----- src/test/test_spiffs.c | 6 ++- src/test/test_spiffs.h | 1 + 6 files changed, 132 insertions(+), 14 deletions(-) diff --git a/src/default/spiffs_config.h b/src/default/spiffs_config.h index 31cd8d7..c7c6c57 100644 --- a/src/default/spiffs_config.h +++ b/src/default/spiffs_config.h @@ -186,7 +186,7 @@ // Block index type. Make sure the size of this type can hold // the highest number of all blocks - i.e. spiffs_file_system_size / log_block_size -typedef u8_t spiffs_block_ix; +typedef u16_t spiffs_block_ix; // Page index type. Make sure the size of this type can hold // the highest page number of all pages - i.e. spiffs_file_system_size / log_page_size typedef u16_t spiffs_page_ix; diff --git a/src/spiffs.h b/src/spiffs.h index 339a748..102884e 100644 --- a/src/spiffs.h +++ b/src/spiffs.h @@ -225,6 +225,7 @@ struct spiffs_dirent { u8_t name[SPIFFS_OBJ_NAME_LEN]; spiffs_obj_type type; u32_t size; + spiffs_page_ix pix; }; typedef struct { @@ -278,6 +279,22 @@ 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); + +/** + * Opens a file by given dir entry. + * Optimization purposes, when traversing a file system with SPIFFS_readdir + * a normal SPIFFS_open would need to traverse the filesystem again to find + * the file, whilst SPIFFS_open_by_dirent already knows where the file resides. + * @param fs the file system struct + * @param path the dir entry to the file + * @param flags the flags for the open command, can be combinations of + * SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY, + * SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT. + * SPIFFS_CREAT will have no effect in this case. + * @param mode ignored, for posix compliance + */ +spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode); + /** * Reads from given filehandle. * @param fs the file system struct diff --git a/src/spiffs_hydrogen.c b/src/spiffs_hydrogen.c index 6080d56..e92439d 100644 --- a/src/spiffs_hydrogen.c +++ b/src/spiffs_hydrogen.c @@ -155,7 +155,36 @@ spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs } SPIFFS_API_CHECK_RES_UNLOCK(fs, res); } - res = spiffs_object_open_by_page(fs, pix, fd, flags, flags); + res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + if (flags & SPIFFS_TRUNC) { + res = spiffs_object_truncate(fd, 0, 0); + if (res < SPIFFS_OK) { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + fd->fdoffset = 0; + + SPIFFS_UNLOCK(fs); + + return fd->file_nbr; +} + +spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode) { + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + spiffs_fd *fd; + + s32_t res = spiffs_fd_find_new(fs, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_open_by_page(fs, e->pix, fd, flags, mode); if (res < SPIFFS_OK) { spiffs_fd_return(fs, fd->file_nbr); } @@ -618,6 +647,7 @@ static s32_t spiffs_read_dir_v( strcpy((char *)e->name, (char *)objix_hdr.name); e->type = objix_hdr.type; e->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; + e->pix = pix; return SPIFFS_OK; } diff --git a/src/test/test_hydrogen.c b/src/test/test_hydrogen.c index c3ff6fc..db32194 100644 --- a/src/test/test_hydrogen.c +++ b/src/test/test_hydrogen.c @@ -192,36 +192,102 @@ TEST(file_by_creat) TEST_END(file_by_creat) - - TEST(list_dir) { int res; - res = test_create_file("file1"); - TEST_CHECK(res >= 0); - res = test_create_file("file2"); - TEST_CHECK(res >= 0); - res = test_create_file("file3"); - TEST_CHECK(res >= 0); - res = test_create_file("file4"); - TEST_CHECK(res >= 0); + + char *files[4] = { + "file1", + "file2", + "file3", + "file4" + }; + int file_cnt = sizeof(files)/sizeof(char *); + + int i; + + for (i = 0; i < file_cnt; i++) { + res = test_create_file(files[i]); + TEST_CHECK(res >= 0); + } spiffs_DIR d; struct spiffs_dirent e; struct spiffs_dirent *pe = &e; SPIFFS_opendir(FS, "/", &d); + int found = 0; while ((pe = SPIFFS_readdir(&d, pe))) { printf(" %s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size); - // TODO verify + for (i = 0; i < file_cnt; i++) { + if (strcmp(files[i], pe->name) == 0) { + found++; + break; + } + } } SPIFFS_closedir(&d); + TEST_CHECK(found == file_cnt); + return TEST_RES_OK; } TEST_END(list_dir) +TEST(open_by_dirent) { + int res; + + char *files[4] = { + "file1", + "file2", + "file3", + "file4" + }; + int file_cnt = sizeof(files)/sizeof(char *); + + int i; + int size = SPIFFS_DATA_PAGE_SIZE(FS); + + for (i = 0; i < file_cnt; i++) { + res = test_create_and_write_file(files[i], size, size); + TEST_CHECK(res >= 0); + } + + spiffs_DIR d; + struct spiffs_dirent e; + struct spiffs_dirent *pe = &e; + + int found = 0; + SPIFFS_opendir(FS, "/", &d); + while ((pe = SPIFFS_readdir(&d, pe))) { + spiffs_file fd = SPIFFS_open_by_dirent(FS, pe, SPIFFS_RDWR, 0); + TEST_CHECK(fd >= 0); + res = read_and_verify_fd(fd, pe->name); + TEST_CHECK(res == SPIFFS_OK); + fd = SPIFFS_open_by_dirent(FS, pe, SPIFFS_RDWR, 0); + TEST_CHECK(fd >= 0); + res = SPIFFS_fremove(FS, fd); + TEST_CHECK(res == SPIFFS_OK); + SPIFFS_close(FS, fd); + found++; + } + SPIFFS_closedir(&d); + + TEST_CHECK(found == file_cnt); + + found = 0; + SPIFFS_opendir(FS, "/", &d); + while ((pe = SPIFFS_readdir(&d, pe))) { + found++; + } + SPIFFS_closedir(&d); + + TEST_CHECK(found == 0); + + return TEST_RES_OK; + +} TEST_END(open_by_dirent) TEST(remove_single_by_path) { diff --git a/src/test/test_spiffs.c b/src/test/test_spiffs.c index dbcbf89..e4e2e9f 100644 --- a/src/test/test_spiffs.c +++ b/src/test/test_spiffs.c @@ -375,7 +375,6 @@ void real_assert(int c, const char *n, const char *file, int l) { } } - int read_and_verify(char *name) { s32_t res; int fd = SPIFFS_open(&__fs, name, SPIFFS_RDONLY, 0); @@ -383,6 +382,11 @@ int read_and_verify(char *name) { printf(" read_and_verify: could not open file %s\n", name); return fd; } + return read_and_verify_fd(fd, name); +} + +int read_and_verify_fd(spiffs_file fd, char *name) { + s32_t res; int pfd = open(make_test_fname(name), O_RDONLY); spiffs_stat s; res = SPIFFS_fstat(&__fs, fd, &s); diff --git a/src/test/test_spiffs.h b/src/test/test_spiffs.h index 4949926..7519264 100644 --- a/src/test/test_spiffs.h +++ b/src/test/test_spiffs.h @@ -58,6 +58,7 @@ typedef struct { void fs_reset(); int read_and_verify(char *name); +int read_and_verify_fd(spiffs_file fd, char *name); void dump_page(spiffs *fs, spiffs_page_ix p); void hexdump(u32_t addr, u32_t len); char *make_test_fname(const char *name);