mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 08:48:31 +01:00
Compare commits
2 Commits
readme-upd
...
fix-lookah
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f935fc0be6 | ||
|
|
6a89ecba39 |
44
lfs.c
44
lfs.c
@@ -270,8 +270,7 @@ int lfs_deorphan(lfs_t *lfs);
|
||||
static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
|
||||
lfs_t *lfs = p;
|
||||
|
||||
lfs_block_t off = (((lfs_soff_t)(block - lfs->free.begin)
|
||||
% (lfs_soff_t)(lfs->cfg->block_count))
|
||||
lfs_block_t off = ((block - lfs->free.off)
|
||||
+ lfs->cfg->block_count) % lfs->cfg->block_count;
|
||||
|
||||
if (off < lfs->free.size) {
|
||||
@@ -283,20 +282,22 @@ static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
|
||||
|
||||
static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
||||
while (true) {
|
||||
while (lfs->free.off != lfs->free.size) {
|
||||
lfs_block_t off = lfs->free.off;
|
||||
lfs->free.off += 1;
|
||||
while (lfs->free.i != lfs->free.size) {
|
||||
lfs_block_t off = lfs->free.i;
|
||||
lfs->free.i += 1;
|
||||
lfs->free.ack -= 1;
|
||||
|
||||
if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) {
|
||||
// found a free block
|
||||
*block = (lfs->free.begin + off) % lfs->cfg->block_count;
|
||||
*block = (lfs->free.off + off) % lfs->cfg->block_count;
|
||||
|
||||
// eagerly find next off so an alloc ack can
|
||||
// discredit old lookahead blocks
|
||||
while (lfs->free.off != lfs->free.size &&
|
||||
(lfs->free.buffer[lfs->free.off / 32] &
|
||||
(1U << (lfs->free.off % 32)))) {
|
||||
lfs->free.off += 1;
|
||||
while (lfs->free.i != lfs->free.size &&
|
||||
(lfs->free.buffer[lfs->free.i / 32]
|
||||
& (1U << (lfs->free.i % 32)))) {
|
||||
lfs->free.i += 1;
|
||||
lfs->free.ack -= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -304,15 +305,16 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
||||
}
|
||||
|
||||
// check if we have looked at all blocks since last ack
|
||||
if (lfs->free.off == lfs->free.ack - lfs->free.begin) {
|
||||
LFS_WARN("No more free space %d", lfs->free.off + lfs->free.begin);
|
||||
//if (lfs->free.i == lfs->free.ack - lfs->free.off) {
|
||||
if (lfs->free.ack == 0) {
|
||||
LFS_WARN("No more free space %d", lfs->free.i + lfs->free.off);
|
||||
return LFS_ERR_NOSPC;
|
||||
}
|
||||
|
||||
lfs->free.begin += lfs->free.size;
|
||||
lfs->free.size = lfs_min(lfs->cfg->lookahead,
|
||||
lfs->free.ack - lfs->free.begin);
|
||||
lfs->free.off = 0;
|
||||
lfs->free.off = (lfs->free.off + lfs->free.size)
|
||||
% lfs->cfg->block_count;
|
||||
lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->free.ack);
|
||||
lfs->free.i = 0;
|
||||
|
||||
// find mask of free blocks from tree
|
||||
memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8);
|
||||
@@ -324,7 +326,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
||||
}
|
||||
|
||||
static void lfs_alloc_ack(lfs_t *lfs) {
|
||||
lfs->free.ack = lfs->free.begin+lfs->free.off + lfs->cfg->block_count;
|
||||
lfs->free.ack = lfs->cfg->block_count;
|
||||
}
|
||||
|
||||
|
||||
@@ -2103,9 +2105,9 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
|
||||
|
||||
// create free lookahead
|
||||
memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8);
|
||||
lfs->free.begin = 0;
|
||||
lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
|
||||
lfs->free.off = 0;
|
||||
lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
|
||||
lfs->free.i = 0;
|
||||
lfs_alloc_ack(lfs);
|
||||
|
||||
// create superblock dir
|
||||
@@ -2182,9 +2184,9 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
||||
}
|
||||
|
||||
// setup free lookahead
|
||||
lfs->free.begin = 0;
|
||||
lfs->free.size = 0;
|
||||
lfs->free.off = 0;
|
||||
lfs->free.size = 0;
|
||||
lfs->free.i = 0;
|
||||
lfs_alloc_ack(lfs);
|
||||
|
||||
// load superblock
|
||||
|
||||
4
lfs.h
4
lfs.h
@@ -259,9 +259,9 @@ typedef struct lfs_superblock {
|
||||
} lfs_superblock_t;
|
||||
|
||||
typedef struct lfs_free {
|
||||
lfs_block_t begin;
|
||||
lfs_block_t size;
|
||||
lfs_block_t off;
|
||||
lfs_block_t size;
|
||||
lfs_block_t i;
|
||||
lfs_block_t ack;
|
||||
uint32_t *buffer;
|
||||
} lfs_free_t;
|
||||
|
||||
@@ -110,10 +110,35 @@ lfs_alloc_singleproc multiprocreuse
|
||||
lfs_verify multiprocreuse
|
||||
lfs_verify singleprocreuse
|
||||
|
||||
echo "--- Cleanup ---"
|
||||
lfs_remove multiprocreuse
|
||||
lfs_remove singleprocreuse
|
||||
|
||||
echo "--- Lookahead overflow test ---"
|
||||
lfs_mkdir overflow
|
||||
for name in bacon eggs pancakes
|
||||
do
|
||||
tests/test.py << TEST
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
|
||||
// // setup lookahead to almost overflow
|
||||
// lfs.free.begin = ((lfs_size_t)-1) - 2*$SIZE;
|
||||
// lfs.free.size = 0;
|
||||
// lfs.free.off = 0;
|
||||
|
||||
lfs_file_open(&lfs, &file[0], "overflow/$name",
|
||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
|
||||
size = strlen("$name");
|
||||
memcpy(buffer, "$name", size);
|
||||
for (int i = 0; i < $SIZE; i++) {
|
||||
lfs_file_write(&lfs, &file[0], buffer, size) => size;
|
||||
}
|
||||
lfs_file_close(&lfs, &file[0]) => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
done
|
||||
lfs_verify overflow
|
||||
lfs_remove overflow
|
||||
|
||||
echo "--- Exhaustion test ---"
|
||||
tests/test.py << TEST
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
@@ -368,7 +393,6 @@ echo "--- Outdated lookahead and split dir test ---"
|
||||
rm -rf blocks
|
||||
tests/test.py << TEST
|
||||
lfs_format(&lfs, &cfg) => 0;
|
||||
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
|
||||
// fill completely with two files
|
||||
@@ -424,5 +448,8 @@ tests/test.py << TEST
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
|
||||
|
||||
|
||||
echo "--- Results ---"
|
||||
tests/stats.py
|
||||
|
||||
Reference in New Issue
Block a user