From a7cdd563f650337ba4dd24b3be94d644f221cb57 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 26 Nov 2020 09:16:20 -0600 Subject: [PATCH] Changed callbacks to take user-provided context directly This is a style change to make littlefs's callbacks consistent with most callback declarations found in C. That is, taking in a user-provided `void*`. Previously, these callbacks took a pointer to the config struct itself, which indirectly contained a user provided context, and this gets the job done, but taking in a callback with a `void*` is arguably more expected, has a better chance of integrating with C++/OS-specific code, and is more likely to be optimized out by a clever compiler. --- As a part of these changes, the geometry for the test bds needed to be moved into bd specific configuration objects. This is a good change as it also allows for testing situations where littlefs's geometry does not match the underlying bd. --- bd/lfs_filebd.c | 107 ++++++++----------- bd/lfs_filebd.h | 38 ++++--- bd/lfs_rambd.c | 109 ++++++++------------ bd/lfs_rambd.h | 36 ++++--- bd/lfs_testbd.c | 204 ++++++++++++++++--------------------- bd/lfs_testbd.h | 52 +++++----- lfs.c | 20 ++-- lfs.h | 19 +--- scripts/test.py | 57 ++++++++--- tests/test_alloc.toml | 4 +- tests/test_badblocks.toml | 12 +-- tests/test_evil.toml | 6 +- tests/test_exhaustion.toml | 8 +- tests/test_move.toml | 100 +++++++++--------- tests/test_orphans.toml | 8 +- 15 files changed, 383 insertions(+), 397 deletions(-) diff --git a/bd/lfs_filebd.c b/bd/lfs_filebd.c index d684778..c738837 100644 --- a/bd/lfs_filebd.c +++ b/bd/lfs_filebd.c @@ -10,21 +10,18 @@ #include #include -int lfs_filebd_createcfg(const struct lfs_cfg *cfg, const char *path, - const struct lfs_filebd_cfg *bdcfg) { - LFS_FILEBD_TRACE("lfs_filebd_createcfg(%p {.context=%p, " - ".read=%p, .prog=%p, .erase=%p, .sync=%p, " +int lfs_filebd_createcfg(lfs_filebd_t *bd, const char *path, + const struct lfs_filebd_cfg *cfg) { + LFS_FILEBD_TRACE("lfs_filebd_createcfg(%p, \"%s\", %p {" ".read_size=%"PRIu32", .prog_size=%"PRIu32", " - ".block_size=%"PRIu32", .block_count=%"PRIu32"}, " - "\"%s\", " - "%p {.erase_value=%"PRId32"})", - (void*)cfg, cfg->context, - (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, - (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, - cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, - path, (void*)bdcfg, bdcfg->erase_value); - lfs_filebd_t *bd = cfg->context; - bd->cfg = bdcfg; + ".erase_size=%"PRIu32", .erase_count=%"PRIu32", " + ".erase_value=%"PRId32"})", + (void*)bd, path, (void*)cfg, + cfg->read_size, cfg->prog_size, cfg->erase_size, cfg->erase_count, + cfg->erase_value); + + // copy over config + bd->cfg = *cfg; // open file bd->fd = open(path, O_RDWR | O_CREAT, 0666); @@ -38,26 +35,8 @@ int lfs_filebd_createcfg(const struct lfs_cfg *cfg, const char *path, return 0; } -int lfs_filebd_create(const struct lfs_cfg *cfg, const char *path) { - LFS_FILEBD_TRACE("lfs_filebd_create(%p {.context=%p, " - ".read=%p, .prog=%p, .erase=%p, .sync=%p, " - ".read_size=%"PRIu32", .prog_size=%"PRIu32", " - ".block_size=%"PRIu32", .block_count=%"PRIu32"}, " - "\"%s\")", - (void*)cfg, cfg->context, - (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, - (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, - cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, - path); - static const struct lfs_filebd_cfg defaults = {.erase_value=-1}; - int err = lfs_filebd_createcfg(cfg, path, &defaults); - LFS_FILEBD_TRACE("lfs_filebd_create -> %d", err); - return err; -} - -int lfs_filebd_destroy(const struct lfs_cfg *cfg) { - LFS_FILEBD_TRACE("lfs_filebd_destroy(%p)", (void*)cfg); - lfs_filebd_t *bd = cfg->context; +int lfs_filebd_destroy(lfs_filebd_t *bd) { + LFS_FILEBD_TRACE("lfs_filebd_destroy(%p)", (void*)bd); int err = close(bd->fd); if (err < 0) { err = -errno; @@ -68,26 +47,25 @@ int lfs_filebd_destroy(const struct lfs_cfg *cfg) { return 0; } -int lfs_filebd_read(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_filebd_read(lfs_filebd_t *bd, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { LFS_FILEBD_TRACE("lfs_filebd_read(%p, " "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")", - (void*)cfg, block, off, buffer, size); - lfs_filebd_t *bd = cfg->context; + (void*)bd, block, off, buffer, size); // check if read is valid - LFS_ASSERT(off % cfg->read_size == 0); - LFS_ASSERT(size % cfg->read_size == 0); - LFS_ASSERT(block < cfg->block_count); + LFS_ASSERT(off % bd->cfg.read_size == 0); + LFS_ASSERT(size % bd->cfg.read_size == 0); + LFS_ASSERT(block < bd->cfg.erase_count); // zero for reproducability (in case file is truncated) - if (bd->cfg->erase_value != -1) { - memset(buffer, bd->cfg->erase_value, size); + if (bd->cfg.erase_value != -1) { + memset(buffer, bd->cfg.erase_value, size); } // read off_t res1 = lseek(bd->fd, - (off_t)block*cfg->block_size + (off_t)off, SEEK_SET); + (off_t)block*bd->cfg.erase_size + (off_t)off, SEEK_SET); if (res1 < 0) { int err = -errno; LFS_FILEBD_TRACE("lfs_filebd_read -> %d", err); @@ -105,21 +83,21 @@ int lfs_filebd_read(const struct lfs_cfg *cfg, lfs_block_t block, return 0; } -int lfs_filebd_prog(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_filebd_prog(lfs_filebd_t *bd, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { - LFS_FILEBD_TRACE("lfs_filebd_prog(%p, 0x%"PRIx32", %"PRIu32", %p, %"PRIu32")", - (void*)cfg, block, off, buffer, size); - lfs_filebd_t *bd = cfg->context; + LFS_FILEBD_TRACE("lfs_filebd_prog(%p, " + "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")", + (void*)bd, block, off, buffer, size); // check if write is valid - LFS_ASSERT(off % cfg->prog_size == 0); - LFS_ASSERT(size % cfg->prog_size == 0); - LFS_ASSERT(block < cfg->block_count); + LFS_ASSERT(off % bd->cfg.prog_size == 0); + LFS_ASSERT(size % bd->cfg.prog_size == 0); + LFS_ASSERT(block < bd->cfg.erase_count); // check that data was erased? only needed for testing - if (bd->cfg->erase_value != -1) { + if (bd->cfg.erase_value != -1) { off_t res1 = lseek(bd->fd, - (off_t)block*cfg->block_size + (off_t)off, SEEK_SET); + (off_t)block*bd->cfg.erase_size + (off_t)off, SEEK_SET); if (res1 < 0) { int err = -errno; LFS_FILEBD_TRACE("lfs_filebd_prog -> %d", err); @@ -135,13 +113,13 @@ int lfs_filebd_prog(const struct lfs_cfg *cfg, lfs_block_t block, return err; } - LFS_ASSERT(c == bd->cfg->erase_value); + LFS_ASSERT(c == bd->cfg.erase_value); } } // program data off_t res1 = lseek(bd->fd, - (off_t)block*cfg->block_size + (off_t)off, SEEK_SET); + (off_t)block*bd->cfg.erase_size + (off_t)off, SEEK_SET); if (res1 < 0) { int err = -errno; LFS_FILEBD_TRACE("lfs_filebd_prog -> %d", err); @@ -159,24 +137,23 @@ int lfs_filebd_prog(const struct lfs_cfg *cfg, lfs_block_t block, return 0; } -int lfs_filebd_erase(const struct lfs_cfg *cfg, lfs_block_t block) { - LFS_FILEBD_TRACE("lfs_filebd_erase(%p, 0x%"PRIx32")", (void*)cfg, block); - lfs_filebd_t *bd = cfg->context; +int lfs_filebd_erase(lfs_filebd_t *bd, lfs_block_t block) { + LFS_FILEBD_TRACE("lfs_filebd_erase(%p, 0x%"PRIx32")", (void*)bd, block); // check if erase is valid - LFS_ASSERT(block < cfg->block_count); + LFS_ASSERT(block < bd->cfg.erase_count); // erase, only needed for testing - if (bd->cfg->erase_value != -1) { - off_t res1 = lseek(bd->fd, (off_t)block*cfg->block_size, SEEK_SET); + if (bd->cfg.erase_value != -1) { + off_t res1 = lseek(bd->fd, (off_t)block*bd->cfg.erase_size, SEEK_SET); if (res1 < 0) { int err = -errno; LFS_FILEBD_TRACE("lfs_filebd_erase -> %d", err); return err; } - for (lfs_off_t i = 0; i < cfg->block_size; i++) { - ssize_t res2 = write(bd->fd, &(uint8_t){bd->cfg->erase_value}, 1); + for (lfs_off_t i = 0; i < bd->cfg.erase_size; i++) { + ssize_t res2 = write(bd->fd, &(uint8_t){bd->cfg.erase_value}, 1); if (res2 < 0) { int err = -errno; LFS_FILEBD_TRACE("lfs_filebd_erase -> %d", err); @@ -189,10 +166,10 @@ int lfs_filebd_erase(const struct lfs_cfg *cfg, lfs_block_t block) { return 0; } -int lfs_filebd_sync(const struct lfs_cfg *cfg) { - LFS_FILEBD_TRACE("lfs_filebd_sync(%p)", (void*)cfg); +int lfs_filebd_sync(lfs_filebd_t *bd) { + LFS_FILEBD_TRACE("lfs_filebd_sync(%p)", (void*)bd); + // file sync - lfs_filebd_t *bd = cfg->context; int err = fsync(bd->fd); if (err) { err = -errno; diff --git a/bd/lfs_filebd.h b/bd/lfs_filebd.h index f719852..98e924b 100644 --- a/bd/lfs_filebd.h +++ b/bd/lfs_filebd.h @@ -10,8 +10,7 @@ #include "lfs.h" #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif @@ -24,6 +23,20 @@ extern "C" // filebd config (optional) struct lfs_filebd_cfg { + // Minimum size of block read. All read operations must be a + // multiple of this value. + lfs_size_t read_size; + + // Minimum size of block program. All program operations must be a + // multiple of this value. + lfs_size_t prog_size; + + // Size of an erasable block. + lfs_size_t erase_size; + + // Number of erasable blocks on the device. + lfs_size_t erase_count; + // 8-bit erase value to use for simulating erases. -1 does not simulate // erases, which can speed up testing by avoiding all the extra block-device // operations to store the erase value. @@ -33,40 +46,39 @@ struct lfs_filebd_cfg { // filebd state typedef struct lfs_filebd { int fd; - const struct lfs_filebd_cfg *cfg; + struct lfs_filebd_cfg cfg; } lfs_filebd_t; -// Create a file block device using the geometry in lfs_cfg -int lfs_filebd_create(const struct lfs_cfg *cfg, const char *path); -int lfs_filebd_createcfg(const struct lfs_cfg *cfg, const char *path, - const struct lfs_filebd_cfg *bdcfg); +// Create a file block device using the geometry in lfs_filebd_cfg +int lfs_filebd_createcfg(lfs_filebd_t *bd, const char *path, + const struct lfs_filebd_cfg *cfg); // Clean up memory associated with block device -int lfs_filebd_destroy(const struct lfs_cfg *cfg); +int lfs_filebd_destroy(lfs_filebd_t *bd); // Read a block -int lfs_filebd_read(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_filebd_read(lfs_filebd_t *bd, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size); // Program a block // // The block must have previously been erased. -int lfs_filebd_prog(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_filebd_prog(lfs_filebd_t *bd, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size); // Erase a block // // A block must be erased before being programmed. The // state of an erased block is undefined. -int lfs_filebd_erase(const struct lfs_cfg *cfg, lfs_block_t block); +int lfs_filebd_erase(lfs_filebd_t *bd, lfs_block_t block); // Sync the block device -int lfs_filebd_sync(const struct lfs_cfg *cfg); +int lfs_filebd_sync(lfs_filebd_t *bd); #ifdef __cplusplus -} /* extern "C" */ +} #endif #endif diff --git a/bd/lfs_rambd.c b/bd/lfs_rambd.c index 567d3bf..c9e78ad 100644 --- a/bd/lfs_rambd.c +++ b/bd/lfs_rambd.c @@ -6,26 +6,24 @@ */ #include "bd/lfs_rambd.h" -int lfs_rambd_createcfg(const struct lfs_cfg *cfg, - const struct lfs_rambd_cfg *bdcfg) { - LFS_RAMBD_TRACE("lfs_rambd_createcfg(%p {.context=%p, " - ".read=%p, .prog=%p, .erase=%p, .sync=%p, " +int lfs_rambd_createcfg(lfs_rambd_t *bd, + const struct lfs_rambd_cfg *cfg) { + LFS_RAMBD_TRACE("lfs_filebd_createcfg(%p, %p {" ".read_size=%"PRIu32", .prog_size=%"PRIu32", " - ".block_size=%"PRIu32", .block_count=%"PRIu32"}, " - "%p {.erase_value=%"PRId32", .buffer=%p})", - (void*)cfg, cfg->context, - (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, - (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, - cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, - (void*)bdcfg, bdcfg->erase_value, bdcfg->buffer); - lfs_rambd_t *bd = cfg->context; - bd->cfg = bdcfg; + ".erase_size=%"PRIu32", .erase_count=%"PRIu32", " + ".erase_value=%"PRId32", .buffer=%p})", + (void*)bd, (void*)cfg, + cfg->read_size, cfg->prog_size, cfg->erase_size, cfg->erase_count, + cfg->erase_value, cfg->buffer); + + // copy over config + bd->cfg = *cfg; // allocate buffer? - if (bd->cfg->buffer) { - bd->buffer = bd->cfg->buffer; + if (bd->cfg.buffer) { + bd->buffer = bd->cfg.buffer; } else { - bd->buffer = lfs_malloc(cfg->block_size * cfg->block_count); + bd->buffer = lfs_malloc(bd->cfg.erase_size * bd->cfg.erase_count); if (!bd->buffer) { LFS_RAMBD_TRACE("lfs_rambd_createcfg -> %d", LFS_ERR_NOMEM); return LFS_ERR_NOMEM; @@ -33,108 +31,89 @@ int lfs_rambd_createcfg(const struct lfs_cfg *cfg, } // zero for reproducability? - if (bd->cfg->erase_value != -1) { - memset(bd->buffer, bd->cfg->erase_value, - cfg->block_size * cfg->block_count); + if (bd->cfg.erase_value != -1) { + memset(bd->buffer, bd->cfg.erase_value, + bd->cfg.erase_size * bd->cfg.erase_count); } LFS_RAMBD_TRACE("lfs_rambd_createcfg -> %d", 0); return 0; } -int lfs_rambd_create(const struct lfs_cfg *cfg) { - LFS_RAMBD_TRACE("lfs_rambd_create(%p {.context=%p, " - ".read=%p, .prog=%p, .erase=%p, .sync=%p, " - ".read_size=%"PRIu32", .prog_size=%"PRIu32", " - ".block_size=%"PRIu32", .block_count=%"PRIu32"})", - (void*)cfg, cfg->context, - (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, - (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, - cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count); - static const struct lfs_rambd_cfg defaults = {.erase_value=-1}; - int err = lfs_rambd_createcfg(cfg, &defaults); - LFS_RAMBD_TRACE("lfs_rambd_create -> %d", err); - return err; -} - -int lfs_rambd_destroy(const struct lfs_cfg *cfg) { - LFS_RAMBD_TRACE("lfs_rambd_destroy(%p)", (void*)cfg); +int lfs_rambd_destroy(lfs_rambd_t *bd) { + LFS_RAMBD_TRACE("lfs_rambd_destroy(%p)", (void*)bd); // clean up memory - lfs_rambd_t *bd = cfg->context; - if (!bd->cfg->buffer) { + if (!bd->cfg.buffer) { lfs_free(bd->buffer); } LFS_RAMBD_TRACE("lfs_rambd_destroy -> %d", 0); return 0; } -int lfs_rambd_read(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_rambd_read(lfs_rambd_t *bd, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { LFS_RAMBD_TRACE("lfs_rambd_read(%p, " "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")", - (void*)cfg, block, off, buffer, size); - lfs_rambd_t *bd = cfg->context; + (void*)bd, block, off, buffer, size); // check if read is valid - LFS_ASSERT(off % cfg->read_size == 0); - LFS_ASSERT(size % cfg->read_size == 0); - LFS_ASSERT(block < cfg->block_count); + LFS_ASSERT(off % bd->cfg.read_size == 0); + LFS_ASSERT(size % bd->cfg.read_size == 0); + LFS_ASSERT(block < bd->cfg.erase_count); // read data - memcpy(buffer, &bd->buffer[block*cfg->block_size + off], size); + memcpy(buffer, &bd->buffer[block*bd->cfg.erase_size + off], size); LFS_RAMBD_TRACE("lfs_rambd_read -> %d", 0); return 0; } -int lfs_rambd_prog(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_rambd_prog(lfs_rambd_t *bd, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { LFS_RAMBD_TRACE("lfs_rambd_prog(%p, " "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")", - (void*)cfg, block, off, buffer, size); - lfs_rambd_t *bd = cfg->context; + (void*)bd, block, off, buffer, size); // check if write is valid - LFS_ASSERT(off % cfg->prog_size == 0); - LFS_ASSERT(size % cfg->prog_size == 0); - LFS_ASSERT(block < cfg->block_count); + LFS_ASSERT(off % bd->cfg.prog_size == 0); + LFS_ASSERT(size % bd->cfg.prog_size == 0); + LFS_ASSERT(block < bd->cfg.erase_count); // check that data was erased? only needed for testing - if (bd->cfg->erase_value != -1) { + if (bd->cfg.erase_value != -1) { for (lfs_off_t i = 0; i < size; i++) { - LFS_ASSERT(bd->buffer[block*cfg->block_size + off + i] == - bd->cfg->erase_value); + LFS_ASSERT(bd->buffer[block*bd->cfg.erase_size + off + i] == + bd->cfg.erase_value); } } // program data - memcpy(&bd->buffer[block*cfg->block_size + off], buffer, size); + memcpy(&bd->buffer[block*bd->cfg.erase_size + off], buffer, size); LFS_RAMBD_TRACE("lfs_rambd_prog -> %d", 0); return 0; } -int lfs_rambd_erase(const struct lfs_cfg *cfg, lfs_block_t block) { - LFS_RAMBD_TRACE("lfs_rambd_erase(%p, 0x%"PRIx32")", (void*)cfg, block); - lfs_rambd_t *bd = cfg->context; +int lfs_rambd_erase(lfs_rambd_t *bd, lfs_block_t block) { + LFS_RAMBD_TRACE("lfs_rambd_erase(%p, 0x%"PRIx32")", (void*)bd, block); // check if erase is valid - LFS_ASSERT(block < cfg->block_count); + LFS_ASSERT(block < bd->cfg.erase_count); // erase, only needed for testing - if (bd->cfg->erase_value != -1) { - memset(&bd->buffer[block*cfg->block_size], - bd->cfg->erase_value, cfg->block_size); + if (bd->cfg.erase_value != -1) { + memset(&bd->buffer[block*bd->cfg.erase_size], + bd->cfg.erase_value, bd->cfg.erase_size); } LFS_RAMBD_TRACE("lfs_rambd_erase -> %d", 0); return 0; } -int lfs_rambd_sync(const struct lfs_cfg *cfg) { - LFS_RAMBD_TRACE("lfs_rambd_sync(%p)", (void*)cfg); +int lfs_rambd_sync(lfs_rambd_t *bd) { + LFS_RAMBD_TRACE("lfs_rambd_sync(%p)", (void*)bd); // sync does nothing because we aren't backed by anything real - (void)cfg; + (void)bd; LFS_RAMBD_TRACE("lfs_rambd_sync -> %d", 0); return 0; } diff --git a/bd/lfs_rambd.h b/bd/lfs_rambd.h index 09efd48..5627e54 100644 --- a/bd/lfs_rambd.h +++ b/bd/lfs_rambd.h @@ -10,8 +10,7 @@ #include "lfs.h" #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif @@ -24,6 +23,20 @@ extern "C" // rambd config (optional) struct lfs_rambd_cfg { + // Minimum size of block read. All read operations must be a + // multiple of this value. + lfs_size_t read_size; + + // Minimum size of block program. All program operations must be a + // multiple of this value. + lfs_size_t prog_size; + + // Size of an erasable block. + lfs_size_t erase_size; + + // Number of erasable blocks on the device. + lfs_size_t erase_count; + // 8-bit erase value to simulate erasing with. -1 indicates no erase // occurs, which is still a valid block device int32_t erase_value; @@ -35,40 +48,39 @@ struct lfs_rambd_cfg { // rambd state typedef struct lfs_rambd { uint8_t *buffer; - const struct lfs_rambd_cfg *cfg; + struct lfs_rambd_cfg cfg; } lfs_rambd_t; // Create a RAM block device using the geometry in lfs_cfg -int lfs_rambd_create(const struct lfs_cfg *cfg); -int lfs_rambd_createcfg(const struct lfs_cfg *cfg, - const struct lfs_rambd_cfg *bdcfg); +int lfs_rambd_createcfg(lfs_rambd_t *bd, + const struct lfs_rambd_cfg *cfg); // Clean up memory associated with block device -int lfs_rambd_destroy(const struct lfs_cfg *cfg); +int lfs_rambd_destroy(lfs_rambd_t *bd); // Read a block -int lfs_rambd_read(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_rambd_read(lfs_rambd_t *bd, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size); // Program a block // // The block must have previously been erased. -int lfs_rambd_prog(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_rambd_prog(lfs_rambd_t *bd, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size); // Erase a block // // A block must be erased before being programmed. The // state of an erased block is undefined. -int lfs_rambd_erase(const struct lfs_cfg *cfg, lfs_block_t block); +int lfs_rambd_erase(lfs_rambd_t *bd, lfs_block_t block); // Sync the block device -int lfs_rambd_sync(const struct lfs_cfg *cfg); +int lfs_rambd_sync(lfs_rambd_t *bd); #ifdef __cplusplus -} /* extern "C" */ +} #endif #endif diff --git a/bd/lfs_testbd.c b/bd/lfs_testbd.c index f098a1c..5d12a49 100644 --- a/bd/lfs_testbd.c +++ b/bd/lfs_testbd.c @@ -10,185 +10,164 @@ #include -int lfs_testbd_createcfg(const struct lfs_cfg *cfg, const char *path, - const struct lfs_testbd_cfg *bdcfg) { - LFS_TESTBD_TRACE("lfs_testbd_createcfg(%p {.context=%p, " - ".read=%p, .prog=%p, .erase=%p, .sync=%p, " +int lfs_testbd_createcfg(lfs_testbd_t *bd, const char *path, + const struct lfs_testbd_cfg *cfg) { + LFS_TESTBD_TRACE("lfs_testbd_createcfg(%p, \"%s\", %p {" ".read_size=%"PRIu32", .prog_size=%"PRIu32", " - ".block_size=%"PRIu32", .block_count=%"PRIu32"}, " - "\"%s\", " - "%p {.erase_value=%"PRId32", .erase_cycles=%"PRIu32", " + ".erase_size=%"PRIu32", .erase_count=%"PRIu32", " + ".erase_value=%"PRId32", .erase_cycles=%"PRIu32", " ".badblock_behavior=%"PRIu8", .power_cycles=%"PRIu32", " ".buffer=%p, .wear_buffer=%p})", - (void*)cfg, cfg->context, - (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, - (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, - cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, - path, (void*)bdcfg, bdcfg->erase_value, bdcfg->erase_cycles, - bdcfg->badblock_behavior, bdcfg->power_cycles, - bdcfg->buffer, bdcfg->wear_buffer); - lfs_testbd_t *bd = cfg->context; - bd->cfg = bdcfg; + (void*)bd, path, (void*)cfg, + cfg->read_size, cfg->prog_size, cfg->erase_size, cfg->erase_count, + cfg->erase_value, cfg->erase_cycles, + cfg->badblock_behavior, cfg->power_cycles, + cfg->buffer, cfg->wear_buffer); + + // copy over config + bd->cfg = *cfg; // setup testing things bd->persist = path; - bd->power_cycles = bd->cfg->power_cycles; + bd->power_cycles = bd->cfg.power_cycles; - if (bd->cfg->erase_cycles) { - if (bd->cfg->wear_buffer) { - bd->wear = bd->cfg->wear_buffer; + if (bd->cfg.erase_cycles) { + if (bd->cfg.wear_buffer) { + bd->wear = bd->cfg.wear_buffer; } else { - bd->wear = lfs_malloc(sizeof(lfs_testbd_wear_t)*cfg->block_count); + bd->wear = lfs_malloc(sizeof(lfs_testbd_wear_t)*cfg->erase_count); if (!bd->wear) { LFS_TESTBD_TRACE("lfs_testbd_createcfg -> %d", LFS_ERR_NOMEM); return LFS_ERR_NOMEM; } } - memset(bd->wear, 0, sizeof(lfs_testbd_wear_t) * cfg->block_count); + memset(bd->wear, 0, sizeof(lfs_testbd_wear_t) * bd->cfg.erase_count); } // create underlying block device if (bd->persist) { - bd->u.file.cfg = (struct lfs_filebd_cfg){ - .erase_value = bd->cfg->erase_value, - }; - int err = lfs_filebd_createcfg(cfg, path, &bd->u.file.cfg); + int err = lfs_filebd_createcfg(&bd->impl.filebd, path, + &(struct lfs_filebd_cfg){ + .read_size=bd->cfg.read_size, + .prog_size=bd->cfg.prog_size, + .erase_size=bd->cfg.erase_size, + .erase_count=bd->cfg.erase_count, + .erase_value=bd->cfg.erase_value}); LFS_TESTBD_TRACE("lfs_testbd_createcfg -> %d", err); return err; } else { - bd->u.ram.cfg = (struct lfs_rambd_cfg){ - .erase_value = bd->cfg->erase_value, - .buffer = bd->cfg->buffer, - }; - int err = lfs_rambd_createcfg(cfg, &bd->u.ram.cfg); + int err = lfs_rambd_createcfg(&bd->impl.rambd, + &(struct lfs_rambd_cfg){ + .read_size=bd->cfg.read_size, + .prog_size=bd->cfg.prog_size, + .erase_size=bd->cfg.erase_size, + .erase_count=bd->cfg.erase_count, + .erase_value=bd->cfg.erase_value, + .buffer=bd->cfg.buffer}); LFS_TESTBD_TRACE("lfs_testbd_createcfg -> %d", err); return err; } } -int lfs_testbd_create(const struct lfs_cfg *cfg, const char *path) { - LFS_TESTBD_TRACE("lfs_testbd_create(%p {.context=%p, " - ".read=%p, .prog=%p, .erase=%p, .sync=%p, " - ".read_size=%"PRIu32", .prog_size=%"PRIu32", " - ".block_size=%"PRIu32", .block_count=%"PRIu32"}, " - "\"%s\")", - (void*)cfg, cfg->context, - (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, - (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, - cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, - path); - static const struct lfs_testbd_cfg defaults = {.erase_value=-1}; - int err = lfs_testbd_createcfg(cfg, path, &defaults); - LFS_TESTBD_TRACE("lfs_testbd_create -> %d", err); - return err; -} - -int lfs_testbd_destroy(const struct lfs_cfg *cfg) { - LFS_TESTBD_TRACE("lfs_testbd_destroy(%p)", (void*)cfg); - lfs_testbd_t *bd = cfg->context; - if (bd->cfg->erase_cycles && !bd->cfg->wear_buffer) { +int lfs_testbd_destroy(lfs_testbd_t *bd) { + LFS_TESTBD_TRACE("lfs_testbd_destroy(%p)", (void*)bd); + if (bd->cfg.erase_cycles && !bd->cfg.wear_buffer) { lfs_free(bd->wear); } if (bd->persist) { - int err = lfs_filebd_destroy(cfg); + int err = lfs_filebd_destroy(&bd->impl.filebd); LFS_TESTBD_TRACE("lfs_testbd_destroy -> %d", err); return err; } else { - int err = lfs_rambd_destroy(cfg); + int err = lfs_rambd_destroy(&bd->impl.rambd); LFS_TESTBD_TRACE("lfs_testbd_destroy -> %d", err); return err; } } /// Internal mapping to block devices /// -static int lfs_testbd_rawread(const struct lfs_cfg *cfg, lfs_block_t block, +static int lfs_testbd_rawread(lfs_testbd_t *bd, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { - lfs_testbd_t *bd = cfg->context; if (bd->persist) { - return lfs_filebd_read(cfg, block, off, buffer, size); + return lfs_filebd_read(&bd->impl.filebd, block, off, buffer, size); } else { - return lfs_rambd_read(cfg, block, off, buffer, size); + return lfs_rambd_read(&bd->impl.rambd, block, off, buffer, size); } } -static int lfs_testbd_rawprog(const struct lfs_cfg *cfg, lfs_block_t block, +static int lfs_testbd_rawprog(lfs_testbd_t *bd, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { - lfs_testbd_t *bd = cfg->context; if (bd->persist) { - return lfs_filebd_prog(cfg, block, off, buffer, size); + return lfs_filebd_prog(&bd->impl.filebd, block, off, buffer, size); } else { - return lfs_rambd_prog(cfg, block, off, buffer, size); + return lfs_rambd_prog(&bd->impl.rambd, block, off, buffer, size); } } -static int lfs_testbd_rawerase(const struct lfs_cfg *cfg, +static int lfs_testbd_rawerase(lfs_testbd_t *bd, lfs_block_t block) { - lfs_testbd_t *bd = cfg->context; if (bd->persist) { - return lfs_filebd_erase(cfg, block); + return lfs_filebd_erase(&bd->impl.filebd, block); } else { - return lfs_rambd_erase(cfg, block); + return lfs_rambd_erase(&bd->impl.rambd, block); } } -static int lfs_testbd_rawsync(const struct lfs_cfg *cfg) { - lfs_testbd_t *bd = cfg->context; +static int lfs_testbd_rawsync(lfs_testbd_t *bd) { if (bd->persist) { - return lfs_filebd_sync(cfg); + return lfs_filebd_sync(&bd->impl.filebd); } else { - return lfs_rambd_sync(cfg); + return lfs_rambd_sync(&bd->impl.rambd); } } /// block device API /// -int lfs_testbd_read(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_testbd_read(lfs_testbd_t *bd, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { LFS_TESTBD_TRACE("lfs_testbd_read(%p, " "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")", - (void*)cfg, block, off, buffer, size); - lfs_testbd_t *bd = cfg->context; + (void*)bd, block, off, buffer, size); // check if read is valid - LFS_ASSERT(off % cfg->read_size == 0); - LFS_ASSERT(size % cfg->read_size == 0); - LFS_ASSERT(block < cfg->block_count); + LFS_ASSERT(off % bd->cfg.read_size == 0); + LFS_ASSERT(size % bd->cfg.read_size == 0); + LFS_ASSERT(block < bd->cfg.erase_count); // block bad? - if (bd->cfg->erase_cycles && bd->wear[block] >= bd->cfg->erase_cycles && - bd->cfg->badblock_behavior == LFS_TESTBD_BADBLOCK_READERROR) { + if (bd->cfg.erase_cycles && bd->wear[block] >= bd->cfg.erase_cycles && + bd->cfg.badblock_behavior == LFS_TESTBD_BADBLOCK_READERROR) { LFS_TESTBD_TRACE("lfs_testbd_read -> %d", LFS_ERR_CORRUPT); return LFS_ERR_CORRUPT; } // read - int err = lfs_testbd_rawread(cfg, block, off, buffer, size); + int err = lfs_testbd_rawread(bd, block, off, buffer, size); LFS_TESTBD_TRACE("lfs_testbd_read -> %d", err); return err; } -int lfs_testbd_prog(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_testbd_prog(lfs_testbd_t *bd, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { LFS_TESTBD_TRACE("lfs_testbd_prog(%p, " "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")", - (void*)cfg, block, off, buffer, size); - lfs_testbd_t *bd = cfg->context; + (void*)bd, block, off, buffer, size); // check if write is valid - LFS_ASSERT(off % cfg->prog_size == 0); - LFS_ASSERT(size % cfg->prog_size == 0); - LFS_ASSERT(block < cfg->block_count); + LFS_ASSERT(off % bd->cfg.prog_size == 0); + LFS_ASSERT(size % bd->cfg.prog_size == 0); + LFS_ASSERT(block < bd->cfg.erase_count); // block bad? - if (bd->cfg->erase_cycles && bd->wear[block] >= bd->cfg->erase_cycles) { - if (bd->cfg->badblock_behavior == + if (bd->cfg.erase_cycles && bd->wear[block] >= bd->cfg.erase_cycles) { + if (bd->cfg.badblock_behavior == LFS_TESTBD_BADBLOCK_PROGERROR) { LFS_TESTBD_TRACE("lfs_testbd_prog -> %d", LFS_ERR_CORRUPT); return LFS_ERR_CORRUPT; - } else if (bd->cfg->badblock_behavior == + } else if (bd->cfg.badblock_behavior == LFS_TESTBD_BADBLOCK_PROGNOOP || - bd->cfg->badblock_behavior == + bd->cfg.badblock_behavior == LFS_TESTBD_BADBLOCK_ERASENOOP) { LFS_TESTBD_TRACE("lfs_testbd_prog -> %d", 0); return 0; @@ -196,7 +175,7 @@ int lfs_testbd_prog(const struct lfs_cfg *cfg, lfs_block_t block, } // prog - int err = lfs_testbd_rawprog(cfg, block, off, buffer, size); + int err = lfs_testbd_rawprog(bd, block, off, buffer, size); if (err) { LFS_TESTBD_TRACE("lfs_testbd_prog -> %d", err); return err; @@ -207,7 +186,7 @@ int lfs_testbd_prog(const struct lfs_cfg *cfg, lfs_block_t block, bd->power_cycles -= 1; if (bd->power_cycles == 0) { // sync to make sure we persist the last changes - assert(lfs_testbd_rawsync(cfg) == 0); + assert(lfs_testbd_rawsync(bd) == 0); // simulate power loss exit(33); } @@ -217,21 +196,20 @@ int lfs_testbd_prog(const struct lfs_cfg *cfg, lfs_block_t block, return 0; } -int lfs_testbd_erase(const struct lfs_cfg *cfg, lfs_block_t block) { - LFS_TESTBD_TRACE("lfs_testbd_erase(%p, 0x%"PRIx32")", (void*)cfg, block); - lfs_testbd_t *bd = cfg->context; +int lfs_testbd_erase(lfs_testbd_t *bd, lfs_block_t block) { + LFS_TESTBD_TRACE("lfs_testbd_erase(%p, 0x%"PRIx32")", (void*)bd, block); // check if erase is valid - LFS_ASSERT(block < cfg->block_count); + LFS_ASSERT(block < bd->cfg.erase_count); // block bad? - if (bd->cfg->erase_cycles) { - if (bd->wear[block] >= bd->cfg->erase_cycles) { - if (bd->cfg->badblock_behavior == + if (bd->cfg.erase_cycles) { + if (bd->wear[block] >= bd->cfg.erase_cycles) { + if (bd->cfg.badblock_behavior == LFS_TESTBD_BADBLOCK_ERASEERROR) { LFS_TESTBD_TRACE("lfs_testbd_erase -> %d", LFS_ERR_CORRUPT); return LFS_ERR_CORRUPT; - } else if (bd->cfg->badblock_behavior == + } else if (bd->cfg.badblock_behavior == LFS_TESTBD_BADBLOCK_ERASENOOP) { LFS_TESTBD_TRACE("lfs_testbd_erase -> %d", 0); return 0; @@ -243,7 +221,7 @@ int lfs_testbd_erase(const struct lfs_cfg *cfg, lfs_block_t block) { } // erase - int err = lfs_testbd_rawerase(cfg, block); + int err = lfs_testbd_rawerase(bd, block); if (err) { LFS_TESTBD_TRACE("lfs_testbd_erase -> %d", err); return err; @@ -254,7 +232,7 @@ int lfs_testbd_erase(const struct lfs_cfg *cfg, lfs_block_t block) { bd->power_cycles -= 1; if (bd->power_cycles == 0) { // sync to make sure we persist the last changes - assert(lfs_testbd_rawsync(cfg) == 0); + assert(lfs_testbd_rawsync(bd) == 0); // simulate power loss exit(33); } @@ -264,36 +242,34 @@ int lfs_testbd_erase(const struct lfs_cfg *cfg, lfs_block_t block) { return 0; } -int lfs_testbd_sync(const struct lfs_cfg *cfg) { - LFS_TESTBD_TRACE("lfs_testbd_sync(%p)", (void*)cfg); - int err = lfs_testbd_rawsync(cfg); +int lfs_testbd_sync(lfs_testbd_t *bd) { + LFS_TESTBD_TRACE("lfs_testbd_sync(%p)", (void*)bd); + int err = lfs_testbd_rawsync(bd); LFS_TESTBD_TRACE("lfs_testbd_sync -> %d", err); return err; } /// simulated wear operations /// -lfs_testbd_swear_t lfs_testbd_getwear(const struct lfs_cfg *cfg, +lfs_testbd_swear_t lfs_testbd_getwear(lfs_testbd_t *bd, lfs_block_t block) { - LFS_TESTBD_TRACE("lfs_testbd_getwear(%p, %"PRIu32")", (void*)cfg, block); - lfs_testbd_t *bd = cfg->context; + LFS_TESTBD_TRACE("lfs_testbd_getwear(%p, %"PRIu32")", (void*)bd, block); // check if block is valid - LFS_ASSERT(bd->cfg->erase_cycles); - LFS_ASSERT(block < cfg->block_count); + LFS_ASSERT(bd->cfg.erase_cycles); + LFS_ASSERT(block < bd->cfg.erase_count); LFS_TESTBD_TRACE("lfs_testbd_getwear -> %"PRIu32, bd->wear[block]); return bd->wear[block]; } -int lfs_testbd_setwear(const struct lfs_cfg *cfg, +int lfs_testbd_setwear(lfs_testbd_t *bd, lfs_block_t block, lfs_testbd_wear_t wear) { - LFS_TESTBD_TRACE("lfs_testbd_setwear(%p, %"PRIu32")", (void*)cfg, block); - lfs_testbd_t *bd = cfg->context; + LFS_TESTBD_TRACE("lfs_testbd_setwear(%p, %"PRIu32")", (void*)bd, block); // check if block is valid - LFS_ASSERT(bd->cfg->erase_cycles); - LFS_ASSERT(block < cfg->block_count); + LFS_ASSERT(bd->cfg.erase_cycles); + LFS_ASSERT(block < bd->cfg.erase_count); bd->wear[block] = wear; diff --git a/bd/lfs_testbd.h b/bd/lfs_testbd.h index 50c18ce..d75fb0b 100644 --- a/bd/lfs_testbd.h +++ b/bd/lfs_testbd.h @@ -13,8 +13,7 @@ #include "bd/lfs_filebd.h" #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif @@ -45,6 +44,20 @@ typedef int32_t lfs_testbd_swear_t; // testbd config, this is required for testing struct lfs_testbd_cfg { + // Minimum size of block read. All read operations must be a + // multiple of this value. + lfs_size_t read_size; + + // Minimum size of block program. All program operations must be a + // multiple of this value. + lfs_size_t prog_size; + + // Size of an erasable block. + lfs_size_t erase_size; + + // Number of erasable blocks on the device. + lfs_size_t erase_count; + // 8-bit erase value to use for simulating erases. -1 does not simulate // erases, which can speed up testing by avoiding all the extra block-device // operations to store the erase value. @@ -71,21 +84,15 @@ struct lfs_testbd_cfg { // testbd state typedef struct lfs_testbd { union { - struct { - lfs_filebd_t bd; - struct lfs_filebd_cfg cfg; - } file; - struct { - lfs_rambd_t bd; - struct lfs_rambd_cfg cfg; - } ram; - } u; + lfs_filebd_t filebd; + lfs_rambd_t rambd; + } impl; bool persist; uint32_t power_cycles; lfs_testbd_wear_t *wear; - const struct lfs_testbd_cfg *cfg; + struct lfs_testbd_cfg cfg; } lfs_testbd_t; @@ -95,46 +102,45 @@ typedef struct lfs_testbd { // // Note that filebd is used if a path is provided, if path is NULL // testbd will use rambd which can be much faster. -int lfs_testbd_create(const struct lfs_cfg *cfg, const char *path); -int lfs_testbd_createcfg(const struct lfs_cfg *cfg, const char *path, - const struct lfs_testbd_cfg *bdcfg); +int lfs_testbd_createcfg(lfs_testbd_t *bd, const char *path, + const struct lfs_testbd_cfg *cfg); // Clean up memory associated with block device -int lfs_testbd_destroy(const struct lfs_cfg *cfg); +int lfs_testbd_destroy(lfs_testbd_t *bd); // Read a block -int lfs_testbd_read(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_testbd_read(lfs_testbd_t *bd, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size); // Program a block // // The block must have previously been erased. -int lfs_testbd_prog(const struct lfs_cfg *cfg, lfs_block_t block, +int lfs_testbd_prog(lfs_testbd_t *bd, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size); // Erase a block // // A block must be erased before being programmed. The // state of an erased block is undefined. -int lfs_testbd_erase(const struct lfs_cfg *cfg, lfs_block_t block); +int lfs_testbd_erase(lfs_testbd_t *bd, lfs_block_t block); // Sync the block device -int lfs_testbd_sync(const struct lfs_cfg *cfg); +int lfs_testbd_sync(lfs_testbd_t *bd); /// Additional extended API for driving test features /// // Get simulated wear on a given block -lfs_testbd_swear_t lfs_testbd_getwear(const struct lfs_cfg *cfg, +lfs_testbd_swear_t lfs_testbd_getwear(lfs_testbd_t *bd, lfs_block_t block); // Manually set simulated wear on a given block -int lfs_testbd_setwear(const struct lfs_cfg *cfg, +int lfs_testbd_setwear(lfs_testbd_t *bd, lfs_block_t block, lfs_testbd_wear_t wear); #ifdef __cplusplus -} /* extern "C" */ +} #endif #endif diff --git a/lfs.c b/lfs.c index a19d4f9..3e5dfcc 100644 --- a/lfs.c +++ b/lfs.c @@ -34,13 +34,13 @@ #else // direct config towards dynamic lfs_cfg struct #define LFS_CFG_READ(lfs, block, off, buffer, size) \ - lfs->cfg->read(lfs->cfg, block, off, buffer, size) + lfs->cfg->read(lfs->cfg->ctx, block, off, buffer, size) #define LFS_CFG_PROG(lfs, block, off, buffer, size) \ - lfs->cfg->prog(lfs->cfg, block, off, buffer, size) + lfs->cfg->prog(lfs->cfg->ctx, block, off, buffer, size) #define LFS_CFG_ERASE(lfs, block) \ - lfs->cfg->erase(lfs->cfg, block) + lfs->cfg->erase(lfs->cfg->ctx, block) #define LFS_CFG_SYNC(lfs) \ - lfs->cfg->sync(lfs->cfg) + lfs->cfg->sync(lfs->cfg->ctx) #define LFS_CFG_READ_SIZE(lfs) lfs->cfg->read_size #define LFS_CFG_PROG_SIZE(lfs) lfs->cfg->prog_size #define LFS_CFG_BLOCK_SIZE(lfs) lfs->cfg->block_size @@ -3732,7 +3732,7 @@ int lfs_format(lfs_t *lfs) { #if !defined(LFS_STATICCFG) int lfs_formatcfg(lfs_t *lfs, const struct lfs_cfg *cfg) { - LFS_TRACE("lfs_formatcfg(%p, %p {.context=%p, " + LFS_TRACE("lfs_formatcfg(%p, %p {.ctx=%p, " ".read=%p, .prog=%p, .erase=%p, .sync=%p, " ".read_size=%"PRIu32", .prog_size=%"PRIu32", " ".block_size=%"PRIu32", .block_count=%"PRIu32", " @@ -3741,7 +3741,7 @@ int lfs_formatcfg(lfs_t *lfs, const struct lfs_cfg *cfg) { ".prog_buffer=%p, .lookahead_buffer=%p, " ".name_max=%"PRIu32", .file_max=%"PRIu32", " ".attr_max=%"PRIu32"})", - (void*)lfs, (void*)cfg, cfg->context, + (void*)lfs, (void*)cfg, cfg->ctx, (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, @@ -3893,7 +3893,7 @@ int lfs_mount(lfs_t *lfs) { #if !defined(LFS_STATICCFG) int lfs_mountcfg(lfs_t *lfs, const struct lfs_cfg *cfg) { - LFS_TRACE("lfs_mountcfg(%p, %p {.context=%p, " + LFS_TRACE("lfs_mountcfg(%p, %p {.ctx=%p, " ".read=%p, .prog=%p, .erase=%p, .sync=%p, " ".read_size=%"PRIu32", .prog_size=%"PRIu32", " ".block_size=%"PRIu32", .block_count=%"PRIu32", " @@ -3902,7 +3902,7 @@ int lfs_mountcfg(lfs_t *lfs, const struct lfs_cfg *cfg) { ".prog_buffer=%p, .lookahead_buffer=%p, " ".name_max=%"PRIu32", .file_max=%"PRIu32", " ".attr_max=%"PRIu32"})", - (void*)lfs, (void*)cfg, cfg->context, + (void*)lfs, (void*)cfg, cfg->ctx, (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, @@ -5009,7 +5009,7 @@ int lfs_migrate(lfs_t *lfs) { #if !defined(LFS_STATICCFG) int lfs_migratecfg(lfs_t *lfs, const struct lfs_cfg *cfg) { - LFS_TRACE("lfs_migratecfg(%p, %p {.context=%p, " + LFS_TRACE("lfs_migratecfg(%p, %p {.ctx=%p, " ".read=%p, .prog=%p, .erase=%p, .sync=%p, " ".read_size=%"PRIu32", .prog_size=%"PRIu32", " ".block_size=%"PRIu32", .block_count=%"PRIu32", " @@ -5018,7 +5018,7 @@ int lfs_migratecfg(lfs_t *lfs, const struct lfs_cfg *cfg) { ".prog_buffer=%p, .lookahead_buffer=%p, " ".name_max=%"PRIu32", .file_max=%"PRIu32", " ".attr_max=%"PRIu32"})", - (void*)lfs, (void*)cfg, cfg->context, + (void*)lfs, (void*)cfg, cfg->ctx, (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, diff --git a/lfs.h b/lfs.h index 50c2284..23e7b69 100644 --- a/lfs.h +++ b/lfs.h @@ -130,28 +130,28 @@ enum lfs_whence_flags { struct lfs_cfg { // Opaque user provided context that can be used to pass // information to the block device operations - void *context; + void *ctx; // Read a region in a block. Negative error codes are propogated // to the user. - int (*read)(const struct lfs_cfg *c, lfs_block_t block, + int (*read)(void *ctx, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size); // Program a region in a block. The block must have previously // been erased. Negative error codes are propogated to the user. // May return LFS_ERR_CORRUPT if the block should be considered bad. - int (*prog)(const struct lfs_cfg *c, lfs_block_t block, + int (*prog)(void *ctx, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size); // Erase a block. A block must be erased before being programmed. // The state of an erased block is undefined. Negative error codes // are propogated to the user. // May return LFS_ERR_CORRUPT if the block should be considered bad. - int (*erase)(const struct lfs_cfg *c, lfs_block_t block); + int (*erase)(void *ctx, lfs_block_t block); // Sync the state of the underlying block device. Negative error codes // are propogated to the user. - int (*sync)(const struct lfs_cfg *c); + int (*sync)(void *ctx); // Minimum size of a block read. All read operations will be a // multiple of this value. @@ -266,15 +266,6 @@ int lfs_sync(void); #ifndef LFS_LOOKAHEAD_BUFFER #define LFS_LOOKAHEAD_BUFFER NULL #endif -#ifndef LFS_NAME_MAX -#define LFS_NAME_MAX 0 -#endif -#ifndef LFS_FILE_MAX -#define LFS_FILE_MAX 0 -#endif -#ifndef LFS_ATTR_MAX -#define LFS_ATTR_MAX 0 -#endif #endif #if !defined(LFS_FILE_STATICCFG) diff --git a/scripts/test.py b/scripts/test.py index 244d1ed..5750c2e 100755 --- a/scripts/test.py +++ b/scripts/test.py @@ -34,13 +34,43 @@ $(foreach target,$(SRC),$(eval $(FLATTEN))) %.test: %.test.o $(foreach f,$(subst /,.,$(SRC:.c=.o)),%.$f) $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@ """ -GLOBALS = """ +BEFORE_MAIN = """ +const char *lfs_testbd_path; +uint32_t lfs_testbd_cycles; + +int lfs_testbd_readctx(void *ctx, lfs_block_t block, + lfs_off_t off, void *buffer, lfs_size_t size) { + return lfs_testbd_read((lfs_testbd_t*)ctx, block, off, buffer, size); +} + +int lfs_testbd_progctx(void *ctx, lfs_block_t block, + lfs_off_t off, const void *buffer, lfs_size_t size) { + return lfs_testbd_prog((lfs_testbd_t*)ctx, block, off, buffer, size); +} + +int lfs_testbd_erasectx(void *ctx, lfs_block_t block) { + return lfs_testbd_erase((lfs_testbd_t*)ctx, block); +} + +int lfs_testbd_syncctx(void *ctx) { + return lfs_testbd_sync((lfs_testbd_t*)ctx); +} +""" +BEFORE_TESTS = """ //////////////// AUTOGENERATED TEST //////////////// #include "lfs.h" #include "bd/lfs_testbd.h" #include + extern const char *lfs_testbd_path; extern uint32_t lfs_testbd_cycles; + +extern int lfs_testbd_readctx(void *ctx, lfs_block_t block, + lfs_off_t off, void *buffer, lfs_size_t size); +extern int lfs_testbd_progctx(void *ctx, lfs_block_t block, + lfs_off_t off, const void *buffer, lfs_size_t size); +extern int lfs_testbd_erasectx(void *ctx, lfs_block_t block); +extern int lfs_testbd_syncctx(void *ctx); """ DEFINES = { 'LFS_READ_SIZE': 16, @@ -67,11 +97,11 @@ PROLOGUE = """ __attribute__((unused)) int err; __attribute__((unused)) const struct lfs_cfg cfg = { - .context = &bd, - .read = lfs_testbd_read, - .prog = lfs_testbd_prog, - .erase = lfs_testbd_erase, - .sync = lfs_testbd_sync, + .ctx = &bd, + .read = lfs_testbd_readctx, + .prog = lfs_testbd_progctx, + .erase = lfs_testbd_erasectx, + .sync = lfs_testbd_syncctx, .read_size = LFS_READ_SIZE, .prog_size = LFS_PROG_SIZE, .block_size = LFS_BLOCK_SIZE, @@ -82,17 +112,21 @@ PROLOGUE = """ }; __attribute__((unused)) const struct lfs_testbd_cfg bdcfg = { + .read_size = LFS_READ_SIZE, + .prog_size = LFS_PROG_SIZE, + .erase_size = LFS_BLOCK_SIZE, + .erase_count = LFS_BLOCK_COUNT, .erase_value = LFS_ERASE_VALUE, .erase_cycles = LFS_ERASE_CYCLES, .badblock_behavior = LFS_BADBLOCK_BEHAVIOR, .power_cycles = lfs_testbd_cycles, }; - lfs_testbd_createcfg(&cfg, lfs_testbd_path, &bdcfg) => 0; + lfs_testbd_createcfg(&bd, lfs_testbd_path, &bdcfg) => 0; """ EPILOGUE = """ // epilogue - lfs_testbd_destroy(&cfg) => 0; + lfs_testbd_destroy(&bd) => 0; """ PASS = '\033[32m✓\033[0m' FAIL = '\033[31m✗\033[0m' @@ -468,7 +502,7 @@ class TestSuite: def build(self, **args): # build test files tf = open(self.path + '.test.c.t', 'w') - tf.write(GLOBALS) + tf.write(BEFORE_TESTS) if self.code is not None: tf.write('#line %d "%s"\n' % (self.code_lineno, self.path)) tf.write(self.code) @@ -483,14 +517,13 @@ class TestSuite: for line in f: tfs[case.in_].write(line) tfs[case.in_].write('\n') - tfs[case.in_].write(GLOBALS) + tfs[case.in_].write(BEFORE_TESTS) tfs[case.in_].write('\n') case.build(tfs[case.in_], **args) + tf.write(BEFORE_MAIN) tf.write('\n') - tf.write('const char *lfs_testbd_path;\n') - tf.write('uint32_t lfs_testbd_cycles;\n') tf.write('int main(int argc, char **argv) {\n') tf.write(4*' '+'int case_ = (argc > 1) ? atoi(argv[1]) : 0;\n') tf.write(4*' '+'int perm = (argc > 2) ? atoi(argv[2]) : 0;\n') diff --git a/tests/test_alloc.toml b/tests/test_alloc.toml index 711560f..07f63c2 100644 --- a/tests/test_alloc.toml +++ b/tests/test_alloc.toml @@ -362,7 +362,7 @@ code = ''' // but mark the head of our file as a "bad block", this is force our // scan to bail early - lfs_testbd_setwear(&cfg, fileblock, 0xffffffff) => 0; + lfs_testbd_setwear(&bd, fileblock, 0xffffffff) => 0; lfs_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0; strcpy((char*)buffer, "chomp"); size = strlen("chomp"); @@ -377,7 +377,7 @@ code = ''' // now reverse the "bad block" and try to write the file again until we // run out of space - lfs_testbd_setwear(&cfg, fileblock, 0) => 0; + lfs_testbd_setwear(&bd, fileblock, 0) => 0; lfs_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0; strcpy((char*)buffer, "chomp"); size = strlen("chomp"); diff --git a/tests/test_badblocks.toml b/tests/test_badblocks.toml index 2fed0f6..79c062d 100644 --- a/tests/test_badblocks.toml +++ b/tests/test_badblocks.toml @@ -16,8 +16,8 @@ define.NAMEMULT = 64 define.FILEMULT = 1 code = ''' for (lfs_block_t badblock = 2; badblock < LFS_BLOCK_COUNT; badblock++) { - lfs_testbd_setwear(&cfg, badblock-1, 0) => 0; - lfs_testbd_setwear(&cfg, badblock, 0xffffffff) => 0; + lfs_testbd_setwear(&bd, badblock-1, 0) => 0; + lfs_testbd_setwear(&bd, badblock, 0xffffffff) => 0; lfs_formatcfg(&lfs, &cfg) => 0; @@ -90,7 +90,7 @@ define.NAMEMULT = 64 define.FILEMULT = 1 code = ''' for (lfs_block_t i = 0; i < (LFS_BLOCK_COUNT-2)/2; i++) { - lfs_testbd_setwear(&cfg, i+2, 0xffffffff) => 0; + lfs_testbd_setwear(&bd, i+2, 0xffffffff) => 0; } lfs_formatcfg(&lfs, &cfg) => 0; @@ -163,7 +163,7 @@ define.NAMEMULT = 64 define.FILEMULT = 1 code = ''' for (lfs_block_t i = 0; i < (LFS_BLOCK_COUNT-2)/2; i++) { - lfs_testbd_setwear(&cfg, (2*i) + 2, 0xffffffff) => 0; + lfs_testbd_setwear(&bd, (2*i) + 2, 0xffffffff) => 0; } lfs_formatcfg(&lfs, &cfg) => 0; @@ -233,8 +233,8 @@ define.LFS_BADBLOCK_BEHAVIOR = [ 'LFS_TESTBD_BADBLOCK_ERASENOOP', ] code = ''' - lfs_testbd_setwear(&cfg, 0, 0xffffffff) => 0; - lfs_testbd_setwear(&cfg, 1, 0xffffffff) => 0; + lfs_testbd_setwear(&bd, 0, 0xffffffff) => 0; + lfs_testbd_setwear(&bd, 1, 0xffffffff) => 0; lfs_formatcfg(&lfs, &cfg) => LFS_ERR_NOSPC; lfs_mountcfg(&lfs, &cfg) => LFS_ERR_CORRUPT; diff --git a/tests/test_evil.toml b/tests/test_evil.toml index c631799..3c7015c 100644 --- a/tests/test_evil.toml +++ b/tests/test_evil.toml @@ -158,12 +158,12 @@ code = ''' lfs_ctz_fromle32(&ctz); // rewrite block to contain bad pointer uint8_t bbuffer[LFS_BLOCK_SIZE]; - cfg.read(&cfg, ctz.head, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, ctz.head, 0, bbuffer, LFS_BLOCK_SIZE) => 0; uint32_t bad = lfs_tole32(0xcccccccc); memcpy(&bbuffer[0], &bad, sizeof(bad)); memcpy(&bbuffer[4], &bad, sizeof(bad)); - cfg.erase(&cfg, ctz.head) => 0; - cfg.prog(&cfg, ctz.head, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_erase(&bd, ctz.head) => 0; + lfs_testbd_prog(&bd, ctz.head, 0, bbuffer, LFS_BLOCK_SIZE) => 0; lfs_deinit(&lfs) => 0; // test that accessing our bad file fails, note there's a number diff --git a/tests/test_exhaustion.toml b/tests/test_exhaustion.toml index c339d45..5da0d21 100644 --- a/tests/test_exhaustion.toml +++ b/tests/test_exhaustion.toml @@ -180,7 +180,7 @@ code = ''' for (int run = 0; run < 2; run++) { for (lfs_block_t b = 0; b < LFS_BLOCK_COUNT; b++) { - lfs_testbd_setwear(&cfg, b, + lfs_testbd_setwear(&bd, b, (b < run_block_count[run]) ? 0 : LFS_ERASE_CYCLES) => 0; } @@ -272,7 +272,7 @@ code = ''' for (int run = 0; run < 2; run++) { for (lfs_block_t b = 0; b < LFS_BLOCK_COUNT; b++) { - lfs_testbd_setwear(&cfg, b, + lfs_testbd_setwear(&bd, b, (b < run_block_count[run]) ? 0 : LFS_ERASE_CYCLES) => 0; } @@ -434,7 +434,7 @@ exhausted: lfs_testbd_wear_t maxwear = 0; // skip 0 and 1 as superblock movement is intentionally avoided for (lfs_block_t b = 2; b < LFS_BLOCK_COUNT; b++) { - lfs_testbd_wear_t wear = lfs_testbd_getwear(&cfg, b); + lfs_testbd_wear_t wear = lfs_testbd_getwear(&bd, b); printf("%08x: wear %d\n", b, wear); assert(wear >= 0); if (wear < minwear) { @@ -453,7 +453,7 @@ exhausted: // find standard deviation^2 lfs_testbd_wear_t dev2 = 0; for (lfs_block_t b = 2; b < LFS_BLOCK_COUNT; b++) { - lfs_testbd_wear_t wear = lfs_testbd_getwear(&cfg, b); + lfs_testbd_wear_t wear = lfs_testbd_getwear(&bd, b); assert(wear >= 0); lfs_testbd_swear_t diff = wear - avgwear; dev2 += diff*diff; diff --git a/tests/test_move.toml b/tests/test_move.toml index de62795..6d77729 100644 --- a/tests/test_move.toml +++ b/tests/test_move.toml @@ -98,15 +98,15 @@ code = ''' lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; uint8_t bbuffer[LFS_BLOCK_SIZE]; - cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; int off = LFS_BLOCK_SIZE-1; while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { off -= 1; } memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); - cfg.erase(&cfg, block) => 0; - cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; - cfg.sync(&cfg) => 0; + lfs_testbd_erase(&bd, block) => 0; + lfs_testbd_prog(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_sync(&bd) => 0; lfs_mountcfg(&lfs, &cfg) => 0; lfs_dir_open(&lfs, &dir, "a") => 0; @@ -174,15 +174,15 @@ code = ''' lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; uint8_t bbuffer[LFS_BLOCK_SIZE]; - cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; int off = LFS_BLOCK_SIZE-1; while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { off -= 1; } memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); - cfg.erase(&cfg, block) => 0; - cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; - cfg.sync(&cfg) => 0; + lfs_testbd_erase(&bd, block) => 0; + lfs_testbd_prog(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_sync(&bd) => 0; // corrupt the destination lfs_mountcfg(&lfs, &cfg) => 0; @@ -190,15 +190,15 @@ code = ''' block = dir.m.pair[0]; lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; - cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; off = LFS_BLOCK_SIZE-1; while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { off -= 1; } memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); - cfg.erase(&cfg, block) => 0; - cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; - cfg.sync(&cfg) => 0; + lfs_testbd_erase(&bd, block) => 0; + lfs_testbd_prog(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_sync(&bd) => 0; lfs_mountcfg(&lfs, &cfg) => 0; lfs_dir_open(&lfs, &dir, "a") => 0; @@ -266,15 +266,15 @@ code = ''' lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; uint8_t bbuffer[LFS_BLOCK_SIZE]; - cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; int off = LFS_BLOCK_SIZE-1; while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { off -= 1; } memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); - cfg.erase(&cfg, block) => 0; - cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; - cfg.sync(&cfg) => 0; + lfs_testbd_erase(&bd, block) => 0; + lfs_testbd_prog(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_sync(&bd) => 0; // corrupt the destination lfs_mountcfg(&lfs, &cfg) => 0; @@ -282,15 +282,15 @@ code = ''' block = dir.m.pair[0]; lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; - cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; off = LFS_BLOCK_SIZE-1; while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { off -= 1; } memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); - cfg.erase(&cfg, block) => 0; - cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; - cfg.sync(&cfg) => 0; + lfs_testbd_erase(&bd, block) => 0; + lfs_testbd_prog(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_sync(&bd) => 0; // continue move lfs_mountcfg(&lfs, &cfg) => 0; @@ -536,15 +536,15 @@ code = ''' lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; uint8_t bbuffer[LFS_BLOCK_SIZE]; - cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; int off = LFS_BLOCK_SIZE-1; while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { off -= 1; } memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); - cfg.erase(&cfg, block) => 0; - cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; - cfg.sync(&cfg) => 0; + lfs_testbd_erase(&bd, block) => 0; + lfs_testbd_prog(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_sync(&bd) => 0; lfs_mountcfg(&lfs, &cfg) => 0; lfs_dir_open(&lfs, &dir, "a") => 0; @@ -620,15 +620,15 @@ code = ''' lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; uint8_t bbuffer[LFS_BLOCK_SIZE]; - cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; int off = LFS_BLOCK_SIZE-1; while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { off -= 1; } memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); - cfg.erase(&cfg, block) => 0; - cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; - cfg.sync(&cfg) => 0; + lfs_testbd_erase(&bd, block) => 0; + lfs_testbd_prog(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_sync(&bd) => 0; // corrupt the destination lfs_mountcfg(&lfs, &cfg) => 0; @@ -636,15 +636,15 @@ code = ''' block = dir.m.pair[0]; lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; - cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; off = LFS_BLOCK_SIZE-1; while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { off -= 1; } memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); - cfg.erase(&cfg, block) => 0; - cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; - cfg.sync(&cfg) => 0; + lfs_testbd_erase(&bd, block) => 0; + lfs_testbd_prog(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_sync(&bd) => 0; lfs_mountcfg(&lfs, &cfg) => 0; lfs_dir_open(&lfs, &dir, "a") => 0; @@ -720,15 +720,15 @@ code = ''' lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; uint8_t bbuffer[LFS_BLOCK_SIZE]; - cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; int off = LFS_BLOCK_SIZE-1; while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { off -= 1; } memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); - cfg.erase(&cfg, block) => 0; - cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; - cfg.sync(&cfg) => 0; + lfs_testbd_erase(&bd, block) => 0; + lfs_testbd_prog(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_sync(&bd) => 0; // corrupt the destination lfs_mountcfg(&lfs, &cfg) => 0; @@ -736,15 +736,15 @@ code = ''' block = dir.m.pair[0]; lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; - cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; off = LFS_BLOCK_SIZE-1; while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { off -= 1; } memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); - cfg.erase(&cfg, block) => 0; - cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; - cfg.sync(&cfg) => 0; + lfs_testbd_erase(&bd, block) => 0; + lfs_testbd_prog(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_sync(&bd) => 0; // continue move lfs_mountcfg(&lfs, &cfg) => 0; @@ -1569,14 +1569,14 @@ code = ''' // force specific directories to relocate if (RELOCATIONS & 0x1) { lfs_dir_open(&lfs, &dir, "/parent"); - lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0; - lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0; + lfs_testbd_setwear(&bd, dir.m.pair[0], 0xffffffff) => 0; + lfs_testbd_setwear(&bd, dir.m.pair[1], 0xffffffff) => 0; lfs_dir_close(&lfs, &dir) => 0; } if (RELOCATIONS & 0x2) { lfs_dir_open(&lfs, &dir, "/parent/child"); - lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0; - lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0; + lfs_testbd_setwear(&bd, dir.m.pair[0], 0xffffffff) => 0; + lfs_testbd_setwear(&bd, dir.m.pair[1], 0xffffffff) => 0; lfs_dir_close(&lfs, &dir) => 0; } @@ -1707,20 +1707,20 @@ code = ''' // force specific directories to relocate if (RELOCATIONS & 0x1) { lfs_dir_open(&lfs, &dir, "/parent"); - lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0; - lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0; + lfs_testbd_setwear(&bd, dir.m.pair[0], 0xffffffff) => 0; + lfs_testbd_setwear(&bd, dir.m.pair[1], 0xffffffff) => 0; lfs_dir_close(&lfs, &dir) => 0; } if (RELOCATIONS & 0x2) { lfs_dir_open(&lfs, &dir, "/parent/sibling"); - lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0; - lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0; + lfs_testbd_setwear(&bd, dir.m.pair[0], 0xffffffff) => 0; + lfs_testbd_setwear(&bd, dir.m.pair[1], 0xffffffff) => 0; lfs_dir_close(&lfs, &dir) => 0; } if (RELOCATIONS & 0x4) { lfs_dir_open(&lfs, &dir, "/parent/child"); - lfs_testbd_setwear(&cfg, dir.m.pair[0], 0xffffffff) => 0; - lfs_testbd_setwear(&cfg, dir.m.pair[1], 0xffffffff) => 0; + lfs_testbd_setwear(&bd, dir.m.pair[0], 0xffffffff) => 0; + lfs_testbd_setwear(&bd, dir.m.pair[1], 0xffffffff) => 0; lfs_dir_close(&lfs, &dir) => 0; } diff --git a/tests/test_orphans.toml b/tests/test_orphans.toml index e89f03c..01bc463 100644 --- a/tests/test_orphans.toml +++ b/tests/test_orphans.toml @@ -19,15 +19,15 @@ code = ''' lfs_dir_close(&lfs, &dir) => 0; lfs_unmount(&lfs) => 0; uint8_t bbuffer[LFS_BLOCK_SIZE]; - cfg.read(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_read(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; int off = LFS_BLOCK_SIZE-1; while (off >= 0 && bbuffer[off] == LFS_ERASE_VALUE) { off -= 1; } memset(&bbuffer[off-3], LFS_BLOCK_SIZE, 3); - cfg.erase(&cfg, block) => 0; - cfg.prog(&cfg, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; - cfg.sync(&cfg) => 0; + lfs_testbd_erase(&bd, block) => 0; + lfs_testbd_prog(&bd, block, 0, bbuffer, LFS_BLOCK_SIZE) => 0; + lfs_testbd_sync(&bd) => 0; lfs_mountcfg(&lfs, &cfg) => 0; lfs_stat(&lfs, "parent/orphan", &info) => LFS_ERR_NOENT;