Generated v2 prefixes

This commit is contained in:
geky-bot
2024-03-08 23:23:45 +00:00
11 changed files with 174 additions and 17 deletions
+4
View File
@@ -258,6 +258,9 @@ License Identifiers that are here available: http://spdx.org/licenses/
use with the MirageOS library operating system project. It is interoperable
with the reference implementation, with some caveats.
- [nim-littlefs] - A Nim wrapper and API for littlefs. Includes a fuse
implementation based on [littlefs-fuse]
[BSD-3-Clause]: https://spdx.org/licenses/BSD-3-Clause.html
[littlefs-disk-img-viewer]: https://github.com/tniessen/littlefs-disk-img-viewer
[littlefs-fuse]: https://github.com/geky/littlefs-fuse
@@ -274,3 +277,4 @@ License Identifiers that are here available: http://spdx.org/licenses/
[littlefs-python]: https://pypi.org/project/littlefs-python/
[littlefs2-rust]: https://crates.io/crates/littlefs2
[chamelon]: https://github.com/yomimono/chamelon
[nim-littlefs]: https://github.com/Graveflo/nim-littlefs
+101 -7
View File
@@ -129,6 +129,8 @@ int lfs2_emubd_create(const struct lfs2_config *cfg,
bd->proged = 0;
bd->erased = 0;
bd->power_cycles = bd->cfg->power_cycles;
bd->ooo_block = -1;
bd->ooo_data = NULL;
bd->disk = NULL;
if (bd->cfg->disk_path) {
@@ -195,6 +197,7 @@ int lfs2_emubd_destroy(const struct lfs2_config *cfg) {
free(bd->blocks);
// clean up other resources
lfs2_emubd_decblock(bd->ooo_data);
if (bd->disk) {
bd->disk->rc -= 1;
if (bd->disk->rc == 0) {
@@ -209,6 +212,75 @@ int lfs2_emubd_destroy(const struct lfs2_config *cfg) {
}
// powerloss hook
static int lfs2_emubd_powerloss(const struct lfs2_config *cfg) {
lfs2_emubd_t *bd = cfg->context;
// emulate out-of-order writes?
lfs2_emubd_block_t *ooo_data = NULL;
if (bd->cfg->powerloss_behavior == LFS2_EMUBD_POWERLOSS_OOO
&& bd->ooo_block != -1) {
// since writes between syncs are allowed to be out-of-order, it
// shouldn't hurt to restore the first write on powerloss, right?
ooo_data = bd->blocks[bd->ooo_block];
bd->blocks[bd->ooo_block] = lfs2_emubd_incblock(bd->ooo_data);
// mirror to disk file?
if (bd->disk
&& (bd->blocks[bd->ooo_block]
|| bd->cfg->erase_value != -1)) {
off_t res1 = lseek(bd->disk->fd,
(off_t)bd->ooo_block*bd->cfg->erase_size,
SEEK_SET);
if (res1 < 0) {
return -errno;
}
ssize_t res2 = write(bd->disk->fd,
(bd->blocks[bd->ooo_block])
? bd->blocks[bd->ooo_block]->data
: bd->disk->scratch,
bd->cfg->erase_size);
if (res2 < 0) {
return -errno;
}
}
}
// simulate power loss
bd->cfg->powerloss_cb(bd->cfg->powerloss_data);
// if we continue, undo out-of-order write emulation
if (bd->cfg->powerloss_behavior == LFS2_EMUBD_POWERLOSS_OOO
&& bd->ooo_block != -1) {
lfs2_emubd_decblock(bd->blocks[bd->ooo_block]);
bd->blocks[bd->ooo_block] = ooo_data;
// mirror to disk file?
if (bd->disk
&& (bd->blocks[bd->ooo_block]
|| bd->cfg->erase_value != -1)) {
off_t res1 = lseek(bd->disk->fd,
(off_t)bd->ooo_block*bd->cfg->erase_size,
SEEK_SET);
if (res1 < 0) {
return -errno;
}
ssize_t res2 = write(bd->disk->fd,
(bd->blocks[bd->ooo_block])
? bd->blocks[bd->ooo_block]->data
: bd->disk->scratch,
bd->cfg->erase_size);
if (res2 < 0) {
return -errno;
}
}
}
return 0;
}
// block device API
@@ -344,8 +416,11 @@ int lfs2_emubd_prog(const struct lfs2_config *cfg, lfs2_block_t block,
if (bd->power_cycles > 0) {
bd->power_cycles -= 1;
if (bd->power_cycles == 0) {
// simulate power loss
bd->cfg->powerloss_cb(bd->cfg->powerloss_data);
int err = lfs2_emubd_powerloss(cfg);
if (err) {
LFS2_EMUBD_TRACE("lfs2_emubd_prog -> %d", err);
return err;
}
}
}
@@ -361,10 +436,17 @@ int lfs2_emubd_erase(const struct lfs2_config *cfg, lfs2_block_t block) {
// check if erase is valid
LFS2_ASSERT(block < bd->cfg->erase_count);
// emulate out-of-order writes? save first write
if (bd->cfg->powerloss_behavior == LFS2_EMUBD_POWERLOSS_OOO
&& bd->ooo_block == -1) {
bd->ooo_block = block;
bd->ooo_data = lfs2_emubd_incblock(bd->blocks[block]);
}
// get the block
lfs2_emubd_block_t *b = lfs2_emubd_mutblock(cfg, &bd->blocks[block]);
if (!b) {
LFS2_EMUBD_TRACE("lfs2_emubd_prog -> %d", LFS2_ERR_NOMEM);
LFS2_EMUBD_TRACE("lfs2_emubd_erase -> %d", LFS2_ERR_NOMEM);
return LFS2_ERR_NOMEM;
}
@@ -430,8 +512,11 @@ int lfs2_emubd_erase(const struct lfs2_config *cfg, lfs2_block_t block) {
if (bd->power_cycles > 0) {
bd->power_cycles -= 1;
if (bd->power_cycles == 0) {
// simulate power loss
bd->cfg->powerloss_cb(bd->cfg->powerloss_data);
int err = lfs2_emubd_powerloss(cfg);
if (err) {
LFS2_EMUBD_TRACE("lfs2_emubd_erase -> %d", err);
return err;
}
}
}
@@ -441,14 +526,21 @@ int lfs2_emubd_erase(const struct lfs2_config *cfg, lfs2_block_t block) {
int lfs2_emubd_sync(const struct lfs2_config *cfg) {
LFS2_EMUBD_TRACE("lfs2_emubd_sync(%p)", (void*)cfg);
lfs2_emubd_t *bd = cfg->context;
// do nothing
(void)cfg;
// emulate out-of-order writes? reset first write, writes
// cannot be out-of-order across sync
if (bd->cfg->powerloss_behavior == LFS2_EMUBD_POWERLOSS_OOO) {
lfs2_emubd_decblock(bd->ooo_data);
bd->ooo_block = -1;
bd->ooo_data = NULL;
}
LFS2_EMUBD_TRACE("lfs2_emubd_sync -> %d", 0);
return 0;
}
/// Additional extended API for driving test features ///
static int lfs2_emubd_crc_(const struct lfs2_config *cfg,
@@ -633,6 +725,8 @@ int lfs2_emubd_copy(const struct lfs2_config *cfg, lfs2_emubd_t *copy) {
copy->proged = bd->proged;
copy->erased = bd->erased;
copy->power_cycles = bd->power_cycles;
copy->ooo_block = bd->ooo_block;
copy->ooo_data = lfs2_emubd_incblock(bd->ooo_data);
copy->disk = bd->disk;
if (copy->disk) {
copy->disk->rc += 1;
+9 -6
View File
@@ -36,17 +36,18 @@ extern "C"
// Not that read-noop is not allowed. Read _must_ return a consistent (but
// may be arbitrary) value on every read.
typedef enum lfs2_emubd_badblock_behavior {
LFS2_EMUBD_BADBLOCK_PROGERROR,
LFS2_EMUBD_BADBLOCK_ERASEERROR,
LFS2_EMUBD_BADBLOCK_READERROR,
LFS2_EMUBD_BADBLOCK_PROGNOOP,
LFS2_EMUBD_BADBLOCK_ERASENOOP,
LFS2_EMUBD_BADBLOCK_PROGERROR = 0, // Error on prog
LFS2_EMUBD_BADBLOCK_ERASEERROR = 1, // Error on erase
LFS2_EMUBD_BADBLOCK_READERROR = 2, // Error on read
LFS2_EMUBD_BADBLOCK_PROGNOOP = 3, // Prog does nothing silently
LFS2_EMUBD_BADBLOCK_ERASENOOP = 4, // Erase does nothing silently
} lfs2_emubd_badblock_behavior_t;
// Mode determining how power-loss behaves during testing. For now this
// only supports a noop behavior, leaving the data on-disk untouched.
typedef enum lfs2_emubd_powerloss_behavior {
LFS2_EMUBD_POWERLOSS_NOOP,
LFS2_EMUBD_POWERLOSS_NOOP = 0, // Progs are atomic
LFS2_EMUBD_POWERLOSS_OOO = 1, // Blocks are written out-of-order
} lfs2_emubd_powerloss_behavior_t;
// Type for measuring read/program/erase operations
@@ -152,6 +153,8 @@ typedef struct lfs2_emubd {
lfs2_emubd_io_t proged;
lfs2_emubd_io_t erased;
lfs2_emubd_powercycles_t power_cycles;
lfs2_ssize_t ooo_block;
lfs2_emubd_block_t *ooo_data;
lfs2_emubd_disk_t *disk;
const struct lfs2_emubd_config *cfg;
+16 -4
View File
@@ -710,11 +710,14 @@ static lfs2_stag_t lfs2_dir_getslice(lfs2_t *lfs2, const lfs2_mdir_t *dir,
lfs2_tag_t ntag = dir->etag;
lfs2_stag_t gdiff = 0;
// synthetic moves
if (lfs2_gstate_hasmovehere(&lfs2->gdisk, dir->pair) &&
lfs2_tag_id(gmask) != 0 &&
lfs2_tag_id(lfs2->gdisk.tag) <= lfs2_tag_id(gtag)) {
// synthetic moves
gdiff -= LFS2_MKTAG(0, 1, 0);
lfs2_tag_id(gmask) != 0) {
if (lfs2_tag_id(lfs2->gdisk.tag) == lfs2_tag_id(gtag)) {
return LFS2_ERR_NOENT;
} else if (lfs2_tag_id(lfs2->gdisk.tag) < lfs2_tag_id(gtag)) {
gdiff -= LFS2_MKTAG(0, 1, 0);
}
}
// iterate over dir block backwards (for faster lookups)
@@ -3401,6 +3404,15 @@ static int lfs2_file_sync_(lfs2_t *lfs2, lfs2_file_t *file) {
if ((file->flags & LFS2_F_DIRTY) &&
!lfs2_pair_isnull(file->m.pair)) {
// before we commit metadata, we need sync the disk to make sure
// data writes don't complete after metadata writes
if (!(file->flags & LFS2_F_INLINE)) {
err = lfs2_bd_sync(lfs2, &lfs2->pcache, &lfs2->rcache, false);
if (err) {
return err;
}
}
// update dir entry
uint16_t type;
const void *buffer;
+8
View File
@@ -181,6 +181,10 @@ code = '''
defines.N = [5, 11]
if = 'BLOCK_COUNT >= 4*N'
reentrant = true
defines.POWERLOSS_BEHAVIOR = [
'LFS2_EMUBD_POWERLOSS_NOOP',
'LFS2_EMUBD_POWERLOSS_OOO',
]
code = '''
lfs2_t lfs2;
int err = lfs2_mount(&lfs2, cfg);
@@ -439,6 +443,10 @@ code = '''
defines.N = [5, 25]
if = 'N < BLOCK_COUNT/2'
reentrant = true
defines.POWERLOSS_BEHAVIOR = [
'LFS2_EMUBD_POWERLOSS_NOOP',
'LFS2_EMUBD_POWERLOSS_OOO',
]
code = '''
lfs2_t lfs2;
int err = lfs2_mount(&lfs2, cfg);
+8
View File
@@ -310,6 +310,10 @@ defines.SIZE = [32, 0, 7, 2049]
defines.CHUNKSIZE = [31, 16, 65]
defines.INLINE_MAX = [0, -1, 8]
reentrant = true
defines.POWERLOSS_BEHAVIOR = [
'LFS2_EMUBD_POWERLOSS_NOOP',
'LFS2_EMUBD_POWERLOSS_OOO',
]
code = '''
lfs2_t lfs2;
int err = lfs2_mount(&lfs2, cfg);
@@ -500,6 +504,10 @@ code = '''
[cases.test_files_many_power_loss]
defines.N = 300
reentrant = true
defines.POWERLOSS_BEHAVIOR = [
'LFS2_EMUBD_POWERLOSS_NOOP',
'LFS2_EMUBD_POWERLOSS_OOO',
]
code = '''
lfs2_t lfs2;
int err = lfs2_mount(&lfs2, cfg);
+4
View File
@@ -195,6 +195,10 @@ code = '''
defines.SIZE = [10, 100]
defines.FILES = [4, 10, 26]
reentrant = true
defines.POWERLOSS_BEHAVIOR = [
'LFS2_EMUBD_POWERLOSS_NOOP',
'LFS2_EMUBD_POWERLOSS_OOO',
]
code = '''
lfs2_t lfs2;
lfs2_file_t files[FILES];
+8
View File
@@ -357,6 +357,10 @@ code = '''
[cases.test_move_reentrant_file]
reentrant = true
defines.POWERLOSS_BEHAVIOR = [
'LFS2_EMUBD_POWERLOSS_NOOP',
'LFS2_EMUBD_POWERLOSS_OOO',
]
code = '''
lfs2_t lfs2;
int err = lfs2_mount(&lfs2, cfg);
@@ -839,6 +843,10 @@ code = '''
[cases.test_reentrant_dir]
reentrant = true
defines.POWERLOSS_BEHAVIOR = [
'LFS2_EMUBD_POWERLOSS_NOOP',
'LFS2_EMUBD_POWERLOSS_OOO',
]
code = '''
lfs2_t lfs2;
int err = lfs2_mount(&lfs2, cfg);
+4
View File
@@ -329,6 +329,10 @@ code = '''
# must be power-of-2 for quadratic probing to be exhaustive
defines.COUNT = [4, 64, 128]
reentrant = true
defines.POWERLOSS_BEHAVIOR = [
'LFS2_EMUBD_POWERLOSS_NOOP',
'LFS2_EMUBD_POWERLOSS_OOO',
]
code = '''
lfs2_t lfs2;
int err = lfs2_mount(&lfs2, cfg);
+8
View File
@@ -32,6 +32,10 @@ code = '''
# reentrant format
[cases.test_superblocks_reentrant_format]
reentrant = true
defines.POWERLOSS_BEHAVIOR = [
'LFS2_EMUBD_POWERLOSS_NOOP',
'LFS2_EMUBD_POWERLOSS_OOO',
]
code = '''
lfs2_t lfs2;
int err = lfs2_mount(&lfs2, cfg);
@@ -174,6 +178,10 @@ code = '''
defines.BLOCK_CYCLES = [2, 1]
defines.N = 24
reentrant = true
defines.POWERLOSS_BEHAVIOR = [
'LFS2_EMUBD_POWERLOSS_NOOP',
'LFS2_EMUBD_POWERLOSS_OOO',
]
code = '''
lfs2_t lfs2;
int err = lfs2_mount(&lfs2, cfg);
+4
View File
@@ -231,6 +231,10 @@ defines.SMALLSIZE = [4, 512]
defines.MEDIUMSIZE = [0, 3, 4, 5, 31, 32, 33, 511, 512, 513, 1023, 1024, 1025]
defines.LARGESIZE = 2048
reentrant = true
defines.POWERLOSS_BEHAVIOR = [
'LFS2_EMUBD_POWERLOSS_NOOP',
'LFS2_EMUBD_POWERLOSS_OOO',
]
code = '''
lfs2_t lfs2;
int err = lfs2_mount(&lfs2, cfg);