mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 00:38:29 +01:00
Fixed issue with long names causing unbounded recursion
This was caused by any commit containing entries large enough to _always_ force a compaction. This would cause littlefs to think that it would need to split infinitely because there was no base case. The fix here is pretty simple: treat any commit with only a single entry as unsplittable. This forces littlefs to first try overcompacting (fitting more in a block than what has optimal runtime), and then failing that return LFS_ERR_NOSPC for higher layers to handle. found by TheLoneWolfling
This commit is contained in:
5
lfs.c
5
lfs.c
@@ -1414,7 +1414,8 @@ static int lfs_dir_compact(lfs_t *lfs,
|
|||||||
bool relocated = false;
|
bool relocated = false;
|
||||||
bool exhausted = false;
|
bool exhausted = false;
|
||||||
|
|
||||||
while (true) {
|
// should we split?
|
||||||
|
while (end - begin > 1) {
|
||||||
// find size
|
// find size
|
||||||
lfs_size_t size = 0;
|
lfs_size_t size = 0;
|
||||||
int err = lfs_dir_traverse(lfs,
|
int err = lfs_dir_traverse(lfs,
|
||||||
@@ -1429,7 +1430,7 @@ static int lfs_dir_compact(lfs_t *lfs,
|
|||||||
|
|
||||||
// space is complicated, we need room for tail, crc, gstate,
|
// space is complicated, we need room for tail, crc, gstate,
|
||||||
// cleanup delete, and we cap at half a block to give room
|
// cleanup delete, and we cap at half a block to give room
|
||||||
// for metadata updates
|
// for metadata updates.
|
||||||
if (size <= lfs_min(lfs->cfg->block_size - 36,
|
if (size <= lfs_min(lfs->cfg->block_size - 36,
|
||||||
lfs_alignup(lfs->cfg->block_size/2, lfs->cfg->prog_size))) {
|
lfs_alignup(lfs->cfg->block_size/2, lfs->cfg->prog_size))) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -165,5 +165,29 @@ tests/test.py << TEST
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
TEST
|
TEST
|
||||||
|
|
||||||
|
echo "--- Really big path test ---"
|
||||||
|
tests/test.py << TEST
|
||||||
|
lfs_mount(&lfs, &cfg) => 0;
|
||||||
|
memset(buffer, 'w', LFS_NAME_MAX);
|
||||||
|
buffer[LFS_NAME_MAX+1] = '\0';
|
||||||
|
lfs_mkdir(&lfs, (char*)buffer) => 0;
|
||||||
|
lfs_remove(&lfs, (char*)buffer) => 0;
|
||||||
|
lfs_file_open(&lfs, &file[0], (char*)buffer,
|
||||||
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
|
lfs_file_close(&lfs, &file[0]) => 0;
|
||||||
|
lfs_remove(&lfs, (char*)buffer) => 0;
|
||||||
|
|
||||||
|
memcpy(buffer, "coffee/", strlen("coffee/"));
|
||||||
|
memset(buffer+strlen("coffee/"), 'w', LFS_NAME_MAX);
|
||||||
|
buffer[strlen("coffee/")+LFS_NAME_MAX+1] = '\0';
|
||||||
|
lfs_mkdir(&lfs, (char*)buffer) => 0;
|
||||||
|
lfs_remove(&lfs, (char*)buffer) => 0;
|
||||||
|
lfs_file_open(&lfs, &file[0], (char*)buffer,
|
||||||
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||||
|
lfs_file_close(&lfs, &file[0]) => 0;
|
||||||
|
lfs_remove(&lfs, (char*)buffer) => 0;
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
TEST
|
||||||
|
|
||||||
echo "--- Results ---"
|
echo "--- Results ---"
|
||||||
tests/stats.py
|
tests/stats.py
|
||||||
|
|||||||
Reference in New Issue
Block a user