From 3fb242f3ae91c270255f6f126ea9585854bb0312 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Fri, 7 Jun 2019 04:09:44 +0200 Subject: [PATCH 1/6] Mark all Python 2 scripts as Python 2 --- scripts/prefix.py | 2 +- tests/corrupt.py | 2 +- tests/stats.py | 2 +- tests/test.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/prefix.py b/scripts/prefix.py index ca547b6..4c33ad4 100755 --- a/scripts/prefix.py +++ b/scripts/prefix.py @@ -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 diff --git a/tests/corrupt.py b/tests/corrupt.py index 44f4f66..c452c42 100755 --- a/tests/corrupt.py +++ b/tests/corrupt.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 import struct import sys diff --git a/tests/stats.py b/tests/stats.py index ab21b59..c2d0fab 100755 --- a/tests/stats.py +++ b/tests/stats.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 import struct import sys diff --git a/tests/test.py b/tests/test.py index e93ccec..2d4f599 100755 --- a/tests/test.py +++ b/tests/test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 import re import sys From 36973d8fd56c3bf6bc0002060a45ff2c3c2b48d5 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 28 May 2019 11:35:22 -0500 Subject: [PATCH 2/6] 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 --- lfs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lfs.c b/lfs.c index a12fdcf..7bd63e5 100644 --- a/lfs.c +++ b/lfs.c @@ -4399,6 +4399,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! From a9a61a3e7860deaabc8645cbf586ad9ce85de3bc Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 28 May 2019 18:16:51 -0500 Subject: [PATCH 3/6] 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 --- lfs.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lfs.c b/lfs.c index 7bd63e5..8ebf4ed 100644 --- a/lfs.c +++ b/lfs.c @@ -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: @@ -4447,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: From 614f7b1e68ca796af6074fd21ceb812f3c609fa1 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 28 May 2019 13:55:03 -0500 Subject: [PATCH 4/6] 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 --- lfs.c | 2 +- tests/test_seek.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/lfs.c b/lfs.c index 8ebf4ed..ca6d587 100644 --- a/lfs.c +++ b/lfs.c @@ -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 diff --git a/tests/test_seek.sh b/tests/test_seek.sh index 2cd711a..1803317 100755 --- a/tests/test_seek.sh +++ b/tests/test_seek.sh @@ -357,5 +357,63 @@ 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; + } + + 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 From b73ac594f23e47382adcc7d541c314a918a8480d Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Fri, 31 May 2019 00:58:48 -0500 Subject: [PATCH 5/6] 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 --- lfs.c | 4 ++-- tests/test_seek.sh | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lfs.c b/lfs.c index ca6d587..c554135 100644 --- a/lfs.c +++ b/lfs.c @@ -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; } } diff --git a/tests/test_seek.sh b/tests/test_seek.sh index 1803317..97a6f15 100755 --- a/tests/test_seek.sh +++ b/tests/test_seek.sh @@ -395,6 +395,16 @@ tests/test.py << TEST 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; From abd90cb84c818a663b584575b019258d01d0065e Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 1 Jul 2019 18:37:05 -0500 Subject: [PATCH 6/6] Fixed 32-bit/64-bit Ubuntu multilib issue in Travis --- .travis.yml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index af7089f..dcfedf6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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