Compare commits

..

2 Commits

Author SHA1 Message Date
Christopher Haster
64a1997da3 Added error when opening multiple files with a statically allocated buffer
Opening multiple files simultaneously is not supported without dynamic memory,
but the previous behaviour would just let the files overwrite each other, which
could lead to bad errors down the line

found by husigeza
2018-04-29 16:45:14 +03:00
Christopher Haster
9637b96069 Fixed lookahead overflow and removed unbounded lookahead pointers
As pointed out by davidefer, the lookahead pointer modular arithmetic
does not work around integer overflow when the pointer size is not a
multiple of the block count.

To avoid overflow problems, the easy solution is to stop trying to
work around integer overflows and keep the lookahead offset inside the
block device. To make this work, the ack was modified into a resetable
counter that is decremented every block allocation.

As a plus, quite a bit of the allocation logic ended up simplified.
2018-04-11 14:38:25 -05:00
2 changed files with 6 additions and 30 deletions

5
lfs.c
View File

@@ -305,7 +305,6 @@ 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.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;
@@ -1356,6 +1355,10 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
// allocate buffer if needed
file->cache.block = 0xffffffff;
if (lfs->cfg->file_buffer) {
if (lfs->files) {
// already in use
return LFS_ERR_NOMEM;
}
file->cache.buffer = lfs->cfg->file_buffer;
} else if ((file->flags & 3) == LFS_O_RDONLY) {
file->cache.buffer = lfs_malloc(lfs->cfg->read_size);

View File

@@ -110,35 +110,10 @@ 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;
@@ -393,6 +368,7 @@ 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
@@ -448,8 +424,5 @@ tests/test.py << TEST
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---"
tests/stats.py