From 5df2b9b0e766bbe93302fb163790d13f3eef3361 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 11 Jan 2018 16:27:33 -0600 Subject: [PATCH] littlefs: Fixed file truncation without writes In the open call, the LFS_O_TRUNC flag was correctly zeroing the file, but it wasn't actually writing the change out to disk. This went unnoticed because in the cases where the truncate was followed by a file write, the updated contents would be written out correctly. Marking the file as dirty if the file isn't already truncated fixes the problem with the least impact. Also added better test cases around truncating files. --- features/filesystem/littlefs/littlefs/lfs.c | 3 ++ .../littlefs/littlefs/tests/test_files.sh | 29 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/features/filesystem/littlefs/littlefs/lfs.c b/features/filesystem/littlefs/littlefs/lfs.c index cc6713a03d..f025c6e6fd 100644 --- a/features/filesystem/littlefs/littlefs/lfs.c +++ b/features/filesystem/littlefs/littlefs/lfs.c @@ -1261,6 +1261,9 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, file->pos = 0; if (flags & LFS_O_TRUNC) { + if (file->size != 0) { + file->flags |= LFS_F_DIRTY; + } file->head = 0xffffffff; file->size = 0; } diff --git a/features/filesystem/littlefs/littlefs/tests/test_files.sh b/features/filesystem/littlefs/littlefs/tests/test_files.sh index 6086107c89..444346371b 100755 --- a/features/filesystem/littlefs/littlefs/tests/test_files.sh +++ b/features/filesystem/littlefs/littlefs/tests/test_files.sh @@ -34,7 +34,8 @@ tests/test.py << TEST lfs_size_t chunk = 31; srand(0); lfs_mount(&lfs, &cfg) => 0; - lfs_file_open(&lfs, &file[0], "$2", LFS_O_WRONLY | LFS_O_CREAT) => 0; + lfs_file_open(&lfs, &file[0], "$2", + ${3:-LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC}) => 0; for (lfs_size_t i = 0; i < size; i += chunk) { chunk = (chunk < size - i) ? chunk : size - i; for (lfs_size_t b = 0; b < chunk; b++) { @@ -53,7 +54,10 @@ tests/test.py << TEST lfs_size_t chunk = 29; srand(0); lfs_mount(&lfs, &cfg) => 0; - lfs_file_open(&lfs, &file[0], "$2", LFS_O_RDONLY) => 0; + lfs_stat(&lfs, "$2", &info) => 0; + info.type => LFS_TYPE_REG; + info.size => size; + lfs_file_open(&lfs, &file[0], "$2", ${3:-LFS_O_RDONLY}) => 0; for (lfs_size_t i = 0; i < size; i += chunk) { chunk = (chunk < size - i) ? chunk : size - i; lfs_file_read(&lfs, &file[0], buffer, chunk) => chunk; @@ -78,10 +82,27 @@ echo "--- Large file test ---" w_test $LARGESIZE largeavacado r_test $LARGESIZE largeavacado +echo "--- Zero file test ---" +w_test 0 noavacado +r_test 0 noavacado + +echo "--- Truncate small test ---" +w_test $SMALLSIZE mediumavacado +r_test $SMALLSIZE mediumavacado +w_test $MEDIUMSIZE mediumavacado +r_test $MEDIUMSIZE mediumavacado + +echo "--- Truncate zero test ---" +w_test $SMALLSIZE noavacado +r_test $SMALLSIZE noavacado +w_test 0 noavacado +r_test 0 noavacado + echo "--- Non-overlap check ---" r_test $SMALLSIZE smallavacado r_test $MEDIUMSIZE mediumavacado r_test $LARGESIZE largeavacado +r_test 0 noavacado echo "--- Dir check ---" tests/test.py << TEST @@ -105,6 +126,10 @@ tests/test.py << TEST strcmp(info.name, "largeavacado") => 0; info.type => LFS_TYPE_REG; info.size => $LARGESIZE; + lfs_dir_read(&lfs, &dir[0], &info) => 1; + strcmp(info.name, "noavacado") => 0; + info.type => LFS_TYPE_REG; + info.size => 0; lfs_dir_read(&lfs, &dir[0], &info) => 0; lfs_dir_close(&lfs, &dir[0]) => 0; lfs_unmount(&lfs) => 0;