Compare commits

..

7 Commits

Author SHA1 Message Date
Christopher Haster
abd90cb84c Fixed 32-bit/64-bit Ubuntu multilib issue in Travis 2019-07-01 19:34:06 -05:00
Christopher Haster
b73ac594f2 Fixed issues with reading and caching inline files
Kind of a two-fold issue. One, the programming to the middle of inline
files was causing the cache to get updated to a half programmed state.
While fine, as all programs do occur in order in a block, this is less
efficient when writing to inline files as it would cause the inline file
to need to be reread even if it fits in the cache.

Two, the rereading of the inline file was broken and passed the file's
tag all the way to where a user would expect an error. This was easy to
fix but adds to the reasons we should have test coverage information.

Found by ebinans
2019-07-01 15:11:53 -05:00
Christopher Haster
614f7b1e68 Fixed accidental truncate after seek on inline files
The cause was mistakenly setting file->ctz.size directly instead of
file->pos, which file->ctz.size gets overwritten with later in
lfs_file_flush.

Also added better seek test cases specifically for inline files. This
should also catch most of the inline corner cases related to
lfs_file_size/lfs_file_tell.

Found by ebinans
2019-07-01 15:11:53 -05:00
Christopher Haster
a9a61a3e78 Added redundant compaction to lfs_format/lfs_migrate
This ensures that both blocks in the superblock pair are written with
the superblock info. While this does use an additional erase cycle, it
prevents older versions of littlefs from accidentally being picked up
in the case that the disk is mounted on a system that doesn't support
the newer version.

This does bring back the risk of picking up old littlefs versions on
a disk that has been formatted with a filesystem that doesn't use
block 2 (such as FAT), but this risk already exists, and moving between
versions of littlefs is more likely with the recent v1 -> v2 update.

Suggested by rojer
2019-07-01 15:11:38 -05:00
Christopher Haster
36973d8fd5 Fixed missing cache flush in lfs_migrate
The data written to the prog cache would make littlefs internally
consistent, but because this was never written to disk, the filesystem
would become unmountable.

Unfortunately, this wasn't found during testing because caches automatically
flush if data is written up to a program boundary (maybe this was a mistake?).

Found by rojer
2019-07-01 15:11:38 -05:00
Christopher Haster
f06dc5737f Merge pull request #201 from nickray/python2-markings
Mark all Python 2 scripts as Python 2
2019-07-01 15:11:16 -05:00
Nicolas Stalder
3fb242f3ae Mark all Python 2 scripts as Python 2 2019-06-07 04:09:44 +02:00
7 changed files with 107 additions and 12 deletions

View File

@@ -66,7 +66,10 @@ jobs:
- CC="arm-linux-gnueabi-gcc --static -mthumb"
- EXEC="qemu-arm"
install:
- sudo apt-get install gcc-arm-linux-gnueabi qemu-user
- sudo apt-get install
gcc-arm-linux-gnueabi
libc6-dev-armel-cross
qemu-user
- arm-linux-gnueabi-gcc --version
- qemu-arm -version
@@ -78,7 +81,10 @@ jobs:
- CC="powerpc-linux-gnu-gcc --static"
- EXEC="qemu-ppc"
install:
- sudo apt-get install gcc-powerpc-linux-gnu qemu-user
- sudo apt-get install
gcc-powerpc-linux-gnu
libc6-dev-powerpc-cross
qemu-user
- powerpc-linux-gnu-gcc --version
- qemu-ppc -version
@@ -90,9 +96,10 @@ jobs:
- CC="mips-linux-gnu-gcc --static"
- EXEC="qemu-mips"
install:
- sudo add-apt-repository -y "deb http://archive.ubuntu.com/ubuntu/ xenial main universe"
- sudo apt-get -qq update
- sudo apt-get install gcc-mips-linux-gnu qemu-user
- sudo apt-get install
gcc-mips-linux-gnu
libc6-dev-mips-cross
qemu-user
- mips-linux-gnu-gcc --version
- qemu-mips -version

26
lfs.c
View File

@@ -194,7 +194,7 @@ static int lfs_bd_prog(lfs_t *lfs,
off += diff;
size -= diff;
pcache->size = off - pcache->off;
pcache->size = lfs_max(pcache->size, off - pcache->off);
if (pcache->size == lfs->cfg->cache_size) {
// eagerly flush out pcache if we fill up
int err = lfs_bd_flush(lfs, pcache, rcache, validate);
@@ -617,7 +617,7 @@ static int lfs_dir_getread(lfs_t *lfs, const lfs_mdir_t *dir,
lfs->cfg->cache_size);
int err = lfs_dir_getslice(lfs, dir, gmask, gtag,
rcache->off, rcache->buffer, rcache->size);
if (err) {
if (err < 0) {
return err;
}
}
@@ -2548,7 +2548,7 @@ relocate:
}
}
} else {
file->ctz.size = lfs_max(file->pos, file->ctz.size);
file->pos = lfs_max(file->pos, file->ctz.size);
}
// actual file updates
@@ -3338,6 +3338,14 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
if (err) {
goto cleanup;
}
// force compaction to prevent accidentally mounting any
// older version of littlefs that may live on disk
root.erased = false;
err = lfs_dir_commit(lfs, &root, NULL, 0);
if (err) {
goto cleanup;
}
}
cleanup:
@@ -4399,6 +4407,11 @@ int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg) {
goto cleanup;
}
}
err = lfs_bd_flush(lfs, &lfs->pcache, &lfs->rcache, true);
if (err) {
goto cleanup;
}
}
// Create new superblock. This marks a successful migration!
@@ -4442,6 +4455,13 @@ int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg) {
if (err) {
goto cleanup;
}
// force compaction to prevent accidentally mounting v1
dir2.erased = false;
err = lfs_dir_commit(lfs, &dir2, NULL, 0);
if (err) {
goto cleanup;
}
}
cleanup:

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python2
# This script replaces prefixes of files, and symbols in that file.
# Useful for creating different versions of the codebase that don't

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python2
import struct
import sys

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python2
import struct
import sys

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python2
import re
import sys

View File

@@ -357,5 +357,73 @@ tests/test.py << TEST
lfs_unmount(&lfs) => 0;
TEST
echo "--- Inline write and seek ---"
for SIZE in $SMALLSIZE $MEDIUMSIZE $LARGESIZE
do
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "hello/tinykitty$SIZE",
LFS_O_RDWR | LFS_O_CREAT) => 0;
int j = 0;
int k = 0;
memcpy(buffer, "abcdefghijklmnopqrstuvwxyz", 26);
for (unsigned i = 0; i < $SIZE; i++) {
lfs_file_write(&lfs, &file[0], &buffer[j++ % 26], 1) => 1;
lfs_file_tell(&lfs, &file[0]) => i+1;
lfs_file_size(&lfs, &file[0]) => i+1;
}
lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_SET) => 0;
lfs_file_tell(&lfs, &file[0]) => 0;
lfs_file_size(&lfs, &file[0]) => $SIZE;
for (unsigned i = 0; i < $SIZE; i++) {
uint8_t c;
lfs_file_read(&lfs, &file[0], &c, 1) => 1;
c => buffer[k++ % 26];
}
lfs_file_sync(&lfs, &file[0]) => 0;
lfs_file_tell(&lfs, &file[0]) => $SIZE;
lfs_file_size(&lfs, &file[0]) => $SIZE;
lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_SET) => 0;
for (unsigned i = 0; i < $SIZE; i++) {
lfs_file_write(&lfs, &file[0], &buffer[j++ % 26], 1) => 1;
lfs_file_tell(&lfs, &file[0]) => i+1;
lfs_file_size(&lfs, &file[0]) => $SIZE;
lfs_file_sync(&lfs, &file[0]) => 0;
lfs_file_tell(&lfs, &file[0]) => i+1;
lfs_file_size(&lfs, &file[0]) => $SIZE;
if (i < $SIZE-2) {
uint8_t c[3];
lfs_file_seek(&lfs, &file[0], -1, LFS_SEEK_CUR) => i;
lfs_file_read(&lfs, &file[0], &c, 3) => 3;
lfs_file_tell(&lfs, &file[0]) => i+3;
lfs_file_size(&lfs, &file[0]) => $SIZE;
lfs_file_seek(&lfs, &file[0], i+1, LFS_SEEK_SET) => i+1;
lfs_file_tell(&lfs, &file[0]) => i+1;
lfs_file_size(&lfs, &file[0]) => $SIZE;
}
}
lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_SET) => 0;
lfs_file_tell(&lfs, &file[0]) => 0;
lfs_file_size(&lfs, &file[0]) => $SIZE;
for (unsigned i = 0; i < $SIZE; i++) {
uint8_t c;
lfs_file_read(&lfs, &file[0], &c, 1) => 1;
c => buffer[k++ % 26];
}
lfs_file_sync(&lfs, &file[0]) => 0;
lfs_file_tell(&lfs, &file[0]) => $SIZE;
lfs_file_size(&lfs, &file[0]) => $SIZE;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
done
echo "--- Results ---"
tests/stats.py