mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 16:14:13 +01:00
Compare commits
1 Commits
test-revam
...
test-revam
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1c0386bda |
18
lfs.c
18
lfs.c
@@ -10,8 +10,6 @@
|
||||
#define LFS_BLOCK_NULL ((lfs_block_t)-1)
|
||||
#define LFS_BLOCK_INLINE ((lfs_block_t)-2)
|
||||
|
||||
static void lfs_alloc_ack(lfs_t *lfs);
|
||||
|
||||
/// Caching block device operations ///
|
||||
static inline void lfs_cache_drop(lfs_t *lfs, lfs_cache_t *rcache) {
|
||||
// do not zero, cheaper if cache is readonly or only going to be
|
||||
@@ -26,15 +24,6 @@ static inline void lfs_cache_zero(lfs_t *lfs, lfs_cache_t *pcache) {
|
||||
pcache->block = LFS_BLOCK_NULL;
|
||||
}
|
||||
|
||||
/// Invalidate the lookahead buffer. This is done during mounting and failed traversals ///
|
||||
static inline void lfs_setup_invalid_lookahead_buffer(lfs_t *lfs)
|
||||
{
|
||||
lfs->free.off = lfs->seed % lfs->cfg->block_size;
|
||||
lfs->free.size = 0;
|
||||
lfs->free.i = 0;
|
||||
lfs_alloc_ack(lfs);
|
||||
}
|
||||
|
||||
static int lfs_bd_read(lfs_t *lfs,
|
||||
const lfs_cache_t *pcache, lfs_cache_t *rcache, lfs_size_t hint,
|
||||
lfs_block_t block, lfs_off_t off,
|
||||
@@ -488,7 +477,6 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
||||
memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size);
|
||||
int err = lfs_fs_traverseraw(lfs, lfs_alloc_lookahead, lfs, true);
|
||||
if (err) {
|
||||
lfs_setup_invalid_lookahead_buffer(lfs);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@@ -3784,7 +3772,10 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
||||
lfs->gdisk = lfs->gstate;
|
||||
|
||||
// setup free lookahead
|
||||
lfs_setup_invalid_lookahead_buffer(lfs);
|
||||
lfs->free.off = lfs->seed % lfs->cfg->block_size;
|
||||
lfs->free.size = 0;
|
||||
lfs->free.i = 0;
|
||||
lfs_alloc_ack(lfs);
|
||||
|
||||
LFS_TRACE("lfs_mount -> %d", 0);
|
||||
return 0;
|
||||
@@ -4603,7 +4594,6 @@ static int lfs1_mount(lfs_t *lfs, struct lfs1 *lfs1,
|
||||
lfs->lfs1->root[1] = LFS_BLOCK_NULL;
|
||||
|
||||
// setup free lookahead
|
||||
// TODO should this also call lfs_setup_invalid_lookahead_buffer(lfs); the free.off is different in the current version of lfs
|
||||
lfs->free.off = 0;
|
||||
lfs->free.size = 0;
|
||||
lfs->free.i = 0;
|
||||
|
||||
@@ -323,90 +323,6 @@ code = '''
|
||||
lfs_unmount(&lfs) => 0;
|
||||
'''
|
||||
|
||||
[[case]] # what if we have a bad block during an allocation scan?
|
||||
in = "lfs.c"
|
||||
define.LFS_ERASE_CYCLES = 0xffffffff
|
||||
define.LFS_BADBLOCK_BEHAVIOR = 'LFS_TESTBD_BADBLOCK_READERROR'
|
||||
code = '''
|
||||
lfs_format(&lfs, &cfg) => 0;
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
// first fill to exhaustion to find available space
|
||||
lfs_file_open(&lfs, &file, "pacman", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||
strcpy((char*)buffer, "waka");
|
||||
size = strlen("waka");
|
||||
lfs_size_t filesize = 0;
|
||||
while (true) {
|
||||
lfs_ssize_t res = lfs_file_write(&lfs, &file, buffer, size);
|
||||
assert(res == (lfs_ssize_t)size || res == LFS_ERR_NOSPC);
|
||||
if (res == LFS_ERR_NOSPC) {
|
||||
break;
|
||||
}
|
||||
filesize += size;
|
||||
}
|
||||
lfs_file_close(&lfs, &file) => 0;
|
||||
// now fill all but a couple of blocks of the filesystem with data
|
||||
filesize -= 3*LFS_BLOCK_SIZE;
|
||||
lfs_file_open(&lfs, &file, "pacman", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||
strcpy((char*)buffer, "waka");
|
||||
size = strlen("waka");
|
||||
for (lfs_size_t i = 0; i < filesize/size; i++) {
|
||||
lfs_file_write(&lfs, &file, buffer, size) => size;
|
||||
}
|
||||
lfs_file_close(&lfs, &file) => 0;
|
||||
// also save head of file so we can error during lookahead scan
|
||||
lfs_block_t fileblock = file.ctz.head;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
|
||||
// remount to force an alloc scan
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
|
||||
// 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_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||
strcpy((char*)buffer, "chomp");
|
||||
size = strlen("chomp");
|
||||
while (true) {
|
||||
lfs_ssize_t res = lfs_file_write(&lfs, &file, buffer, size);
|
||||
assert(res == (lfs_ssize_t)size || res == LFS_ERR_CORRUPT);
|
||||
if (res == LFS_ERR_CORRUPT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
lfs_file_close(&lfs, &file) => 0;
|
||||
|
||||
// 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_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||
strcpy((char*)buffer, "chomp");
|
||||
size = strlen("chomp");
|
||||
while (true) {
|
||||
lfs_ssize_t res = lfs_file_write(&lfs, &file, buffer, size);
|
||||
assert(res == (lfs_ssize_t)size || res == LFS_ERR_NOSPC);
|
||||
if (res == LFS_ERR_NOSPC) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
lfs_file_close(&lfs, &file) => 0;
|
||||
|
||||
lfs_unmount(&lfs) => 0;
|
||||
|
||||
// check that the disk isn't hurt
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_file_open(&lfs, &file, "pacman", LFS_O_RDONLY) => 0;
|
||||
strcpy((char*)buffer, "waka");
|
||||
size = strlen("waka");
|
||||
for (lfs_size_t i = 0; i < filesize/size; i++) {
|
||||
uint8_t rbuffer[4];
|
||||
lfs_file_read(&lfs, &file, rbuffer, size) => size;
|
||||
assert(memcmp(rbuffer, buffer, size) == 0);
|
||||
}
|
||||
lfs_file_close(&lfs, &file) => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
'''
|
||||
|
||||
|
||||
# Below, I don't like these tests. They're fragile and depend _heavily_
|
||||
# on the geometry of the block device. But they are valuable. Eventually they
|
||||
# should be removed and replaced with generalized tests.
|
||||
|
||||
85
tests/test_new.toml
Normal file
85
tests/test_new.toml
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
#open(1, "5file5.xxxxxxxxxxxx", 0x503) -> 0
|
||||
# write(1, , 2007)[^ 1499 us] -> 2007
|
||||
# write(1, , 2007)[^ 1411 us] -> 2007
|
||||
# write(1, , 2007)[^ 1390 us] -> 2007
|
||||
# write(1, , 2007)[^ 1401 us] -> 2007
|
||||
# close(1) -> 0
|
||||
# open(1, "1file1.xxxx", 0x503) -> 0
|
||||
# mount
|
||||
# open(0, "5file5.xxxxxxxxxxxx", 0x3) -> 0
|
||||
# open(1, "5file5.xxxxxxxxxxxx", 0x503) -> 0
|
||||
# close(1) -> 0
|
||||
# open(1, "1file1.xxxx", 0x2) -> 0
|
||||
# write(0, , 63) -> 63
|
||||
#a.out: lfs.c:2169: lfs_ctz_find: Assertion `head >= 2 && head <= lfs->cfg->block_count' failed.
|
||||
# close(0)Aborted
|
||||
|
||||
[[case]]
|
||||
define.FILESIZE5 = '4*CHUNKSIZE5'
|
||||
define.FILESIZE1 = '4*CHUNKSIZE1'
|
||||
define.CHUNKSIZE5 = 2007
|
||||
define.CHUNKSIZE1 = 63
|
||||
code = '''
|
||||
lfs_file_t files[2];
|
||||
uint8_t chunk5[CHUNKSIZE5];
|
||||
memset(chunk5, 'a', CHUNKSIZE5);
|
||||
uint8_t chunk1[CHUNKSIZE1];
|
||||
memset(chunk1, 'b', CHUNKSIZE1);
|
||||
|
||||
lfs_format(&lfs, &cfg) => 0;
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_file_open(&lfs, &files[1], "5file5.xxxxxxxxxxxx",
|
||||
LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||
for (int i = 0; i < FILESIZE5/CHUNKSIZE5; i++) {
|
||||
lfs_file_write(&lfs, &files[1], chunk5, CHUNKSIZE5) => CHUNKSIZE5;
|
||||
}
|
||||
lfs_file_close(&lfs, &files[1]) => 0;
|
||||
lfs_file_open(&lfs, &files[1], "1file1.xxxx",
|
||||
LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||
// these should not change the result
|
||||
// lfs_file_close(&lfs, &files[1]) => 0;
|
||||
// lfs_unmount(&lfs) => 0;
|
||||
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_file_open(&lfs, &files[0], "5file5.xxxxxxxxxxxx",
|
||||
LFS_O_RDWR) => 0;
|
||||
|
||||
lfs_file_open(&lfs, &files[1], "5file5.xxxxxxxxxxxx",
|
||||
LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC) => 0;
|
||||
lfs_file_close(&lfs, &files[1]) => 0;
|
||||
|
||||
lfs_file_open(&lfs, &files[1], "1file1.xxxx",
|
||||
LFS_O_WRONLY) => 0;
|
||||
for (int i = 0; i < FILESIZE1/CHUNKSIZE1; i++) {
|
||||
lfs_file_write(&lfs, &files[1], chunk1, CHUNKSIZE1) => CHUNKSIZE1;
|
||||
}
|
||||
lfs_file_close(&lfs, &files[1]) => 0;
|
||||
|
||||
memset(chunk5, 'c', CHUNKSIZE5);
|
||||
for (int i = 0; i < FILESIZE5/CHUNKSIZE5; i++) {
|
||||
lfs_file_write(&lfs, &files[0], chunk5, CHUNKSIZE5) => CHUNKSIZE5;
|
||||
}
|
||||
lfs_file_close(&lfs, &files[0]) => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
|
||||
// check results
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_file_open(&lfs, &files[0], "5file5.xxxxxxxxxxxx",
|
||||
LFS_O_RDONLY) => 0;
|
||||
for (int i = 0; i < FILESIZE5/CHUNKSIZE5; i++) {
|
||||
uint8_t rchunk[CHUNKSIZE5];
|
||||
lfs_file_read(&lfs, &files[0], rchunk, CHUNKSIZE5) => CHUNKSIZE5;
|
||||
assert(memcmp(rchunk, chunk5, CHUNKSIZE5) == 0);
|
||||
}
|
||||
lfs_file_close(&lfs, &files[0]) => 0;
|
||||
lfs_file_open(&lfs, &files[0], "1file1.xxxx",
|
||||
LFS_O_RDONLY) => 0;
|
||||
for (int i = 0; i < FILESIZE1/CHUNKSIZE1; i++) {
|
||||
uint8_t rchunk[CHUNKSIZE1];
|
||||
lfs_file_read(&lfs, &files[0], rchunk, CHUNKSIZE1) => CHUNKSIZE1;
|
||||
assert(memcmp(rchunk, chunk1, CHUNKSIZE1) == 0);
|
||||
}
|
||||
lfs_file_close(&lfs, &files[0]) => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
'''
|
||||
Reference in New Issue
Block a user