diff options
-rw-r--r-- | bd/lfs_filebd.c | 40 | ||||
-rw-r--r-- | bd/lfs_filebd.h | 2 | ||||
-rw-r--r-- | bd/lfs_rambd.c | 48 | ||||
-rw-r--r-- | bd/lfs_rambd.h | 7 | ||||
-rw-r--r-- | bd/lfs_testbd.c | 73 | ||||
-rw-r--r-- | bd/lfs_testbd.h | 10 | ||||
-rwxr-xr-x | scripts/test.py | 14 |
7 files changed, 97 insertions, 97 deletions
diff --git a/bd/lfs_filebd.c b/bd/lfs_filebd.c index c738837..edc0c8b 100644 --- a/bd/lfs_filebd.c +++ b/bd/lfs_filebd.c @@ -19,9 +19,7 @@ int lfs_filebd_createcfg(lfs_filebd_t *bd, const char *path, (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; + bd->cfg = cfg; // open file bd->fd = open(path, O_RDWR | O_CREAT, 0666); @@ -54,18 +52,18 @@ int lfs_filebd_read(lfs_filebd_t *bd, lfs_block_t block, (void*)bd, block, off, buffer, size); // check if read is valid - LFS_ASSERT(off % bd->cfg.read_size == 0); - LFS_ASSERT(size % bd->cfg.read_size == 0); - LFS_ASSERT(block < bd->cfg.erase_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*bd->cfg.erase_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); @@ -90,14 +88,14 @@ int lfs_filebd_prog(lfs_filebd_t *bd, lfs_block_t block, (void*)bd, block, off, buffer, size); // check if write is valid - LFS_ASSERT(off % bd->cfg.prog_size == 0); - LFS_ASSERT(size % bd->cfg.prog_size == 0); - LFS_ASSERT(block < bd->cfg.erase_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*bd->cfg.erase_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); @@ -113,13 +111,13 @@ int lfs_filebd_prog(lfs_filebd_t *bd, 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*bd->cfg.erase_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); @@ -141,19 +139,19 @@ 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 < bd->cfg.erase_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*bd->cfg.erase_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 < bd->cfg.erase_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); diff --git a/bd/lfs_filebd.h b/bd/lfs_filebd.h index 98e924b..2861a8b 100644 --- a/bd/lfs_filebd.h +++ b/bd/lfs_filebd.h @@ -46,7 +46,7 @@ struct lfs_filebd_cfg { // filebd state typedef struct lfs_filebd { int fd; - struct lfs_filebd_cfg cfg; + const struct lfs_filebd_cfg *cfg; } lfs_filebd_t; diff --git a/bd/lfs_rambd.c b/bd/lfs_rambd.c index c9e78ad..3a443f4 100644 --- a/bd/lfs_rambd.c +++ b/bd/lfs_rambd.c @@ -15,15 +15,13 @@ int lfs_rambd_createcfg(lfs_rambd_t *bd, (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; + 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(bd->cfg.erase_size * bd->cfg.erase_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; @@ -31,9 +29,9 @@ int lfs_rambd_createcfg(lfs_rambd_t *bd, } // zero for reproducability? - if (bd->cfg.erase_value != -1) { - memset(bd->buffer, bd->cfg.erase_value, - bd->cfg.erase_size * bd->cfg.erase_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); @@ -43,7 +41,7 @@ int lfs_rambd_createcfg(lfs_rambd_t *bd, int lfs_rambd_destroy(lfs_rambd_t *bd) { LFS_RAMBD_TRACE("lfs_rambd_destroy(%p)", (void*)bd); // clean up memory - if (!bd->cfg.buffer) { + if (!bd->cfg->buffer) { lfs_free(bd->buffer); } LFS_RAMBD_TRACE("lfs_rambd_destroy -> %d", 0); @@ -57,12 +55,12 @@ int lfs_rambd_read(lfs_rambd_t *bd, lfs_block_t block, (void*)bd, block, off, buffer, size); // check if read is valid - LFS_ASSERT(off % bd->cfg.read_size == 0); - LFS_ASSERT(size % bd->cfg.read_size == 0); - LFS_ASSERT(block < bd->cfg.erase_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*bd->cfg.erase_size + off], size); + memcpy(buffer, &bd->buffer[block*bd->cfg->erase_size + off], size); LFS_RAMBD_TRACE("lfs_rambd_read -> %d", 0); return 0; @@ -75,20 +73,20 @@ int lfs_rambd_prog(lfs_rambd_t *bd, lfs_block_t block, (void*)bd, block, off, buffer, size); // check if write is valid - LFS_ASSERT(off % bd->cfg.prog_size == 0); - LFS_ASSERT(size % bd->cfg.prog_size == 0); - LFS_ASSERT(block < bd->cfg.erase_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*bd->cfg.erase_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*bd->cfg.erase_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; @@ -98,12 +96,12 @@ 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 < bd->cfg.erase_count); + LFS_ASSERT(block < bd->cfg->erase_count); // erase, only needed for testing - if (bd->cfg.erase_value != -1) { - memset(&bd->buffer[block*bd->cfg.erase_size], - bd->cfg.erase_value, bd->cfg.erase_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); diff --git a/bd/lfs_rambd.h b/bd/lfs_rambd.h index 5627e54..8b3d24b 100644 --- a/bd/lfs_rambd.h +++ b/bd/lfs_rambd.h @@ -37,8 +37,9 @@ struct lfs_rambd_cfg { // 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 + // 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. int32_t erase_value; // Optional statically allocated buffer for the block device. @@ -48,7 +49,7 @@ struct lfs_rambd_cfg { // rambd state typedef struct lfs_rambd { uint8_t *buffer; - struct lfs_rambd_cfg cfg; + const struct lfs_rambd_cfg *cfg; } lfs_rambd_t; diff --git a/bd/lfs_testbd.c b/bd/lfs_testbd.c index 5d12a49..6bee3e9 100644 --- a/bd/lfs_testbd.c +++ b/bd/lfs_testbd.c @@ -23,17 +23,15 @@ int lfs_testbd_createcfg(lfs_testbd_t *bd, const char *path, cfg->erase_value, cfg->erase_cycles, cfg->badblock_behavior, cfg->power_cycles, cfg->buffer, cfg->wear_buffer); - - // copy over config - bd->cfg = *cfg; + 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->erase_count); if (!bd->wear) { @@ -42,29 +40,18 @@ int lfs_testbd_createcfg(lfs_testbd_t *bd, const char *path, } } - memset(bd->wear, 0, sizeof(lfs_testbd_wear_t) * bd->cfg.erase_count); + memset(bd->wear, 0, sizeof(lfs_testbd_wear_t) * bd->cfg->erase_count); } // create underlying block device if (bd->persist) { 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}); + bd->cfg->filebd_cfg); LFS_TESTBD_TRACE("lfs_testbd_createcfg -> %d", err); return err; } else { 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}); + bd->cfg->rambd_cfg); LFS_TESTBD_TRACE("lfs_testbd_createcfg -> %d", err); return err; } @@ -72,7 +59,7 @@ int lfs_testbd_createcfg(lfs_testbd_t *bd, const char *path, 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) { + if (bd->cfg->erase_cycles && !bd->cfg->wear_buffer) { lfs_free(bd->wear); } @@ -131,13 +118,13 @@ int lfs_testbd_read(lfs_testbd_t *bd, lfs_block_t block, (void*)bd, block, off, buffer, size); // check if read is valid - LFS_ASSERT(off % bd->cfg.read_size == 0); - LFS_ASSERT(size % bd->cfg.read_size == 0); - LFS_ASSERT(block < bd->cfg.erase_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; } @@ -155,19 +142,19 @@ int lfs_testbd_prog(lfs_testbd_t *bd, lfs_block_t block, (void*)bd, block, off, buffer, size); // check if write is valid - LFS_ASSERT(off % bd->cfg.prog_size == 0); - LFS_ASSERT(size % bd->cfg.prog_size == 0); - LFS_ASSERT(block < bd->cfg.erase_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; @@ -200,16 +187,16 @@ 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 < bd->cfg.erase_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; @@ -256,8 +243,8 @@ lfs_testbd_swear_t lfs_testbd_getwear(lfs_testbd_t *bd, 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 < bd->cfg.erase_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]; @@ -268,8 +255,8 @@ int lfs_testbd_setwear(lfs_testbd_t *bd, 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 < bd->cfg.erase_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 d75fb0b..23f3945 100644 --- a/bd/lfs_testbd.h +++ b/bd/lfs_testbd.h @@ -44,6 +44,11 @@ typedef int32_t lfs_testbd_swear_t; // testbd config, this is required for testing struct lfs_testbd_cfg { + // Block device specific configuration, see the related config structs. + // May be NULL if the underlying implementation goes unused. + const struct lfs_rambd_cfg *rambd_cfg; + const struct lfs_filebd_cfg *filebd_cfg; + // Minimum size of block read. All read operations must be a // multiple of this value. lfs_size_t read_size; @@ -74,9 +79,6 @@ struct lfs_testbd_cfg { // the program with exit. Simulates power-loss. 0 disables. uint32_t power_cycles; - // Optional buffer for RAM block device. - void *buffer; - // Optional buffer for wear void *wear_buffer; }; @@ -92,7 +94,7 @@ typedef struct lfs_testbd { uint32_t power_cycles; lfs_testbd_wear_t *wear; - struct lfs_testbd_cfg cfg; + const struct lfs_testbd_cfg *cfg; } lfs_testbd_t; diff --git a/scripts/test.py b/scripts/test.py index 5750c2e..b6fb3eb 100755 --- a/scripts/test.py +++ b/scripts/test.py @@ -112,6 +112,20 @@ PROLOGUE = """ }; __attribute__((unused)) const struct lfs_testbd_cfg bdcfg = { + .rambd_cfg = &(const struct lfs_rambd_cfg){ + .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, + }, + .filebd_cfg = &(const struct lfs_filebd_cfg){ + .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, + }, .read_size = LFS_READ_SIZE, .prog_size = LFS_PROG_SIZE, .erase_size = LFS_BLOCK_SIZE, |