Merge commit '0f4e334388e0e05554a78d14d0a5ef73f02209b2'

pull/5538/head
Christopher Haster 2017-11-16 18:16:58 -06:00
commit 9f8d0d6ae8
12 changed files with 86 additions and 50 deletions

View File

@ -11,20 +11,20 @@ script:
-n 'tests*'
# Run littlefs functional tests
- CFLAGS="-Wno-error=format" make -Clittlefs test
- CFLAGS="-Wno-error=format" make -Clittlefs test QUIET=1
# Run littlefs functional tests with different configurations
# Note: r/w size of 64 is default in mbed
- CFLAGS="-Wno-error=format -DLFS_READ_SIZE=64 -DLFS_PROG_SIZE=64"
make -Clittlefs test
make -Clittlefs test QUIET=1
- CFLAGS="-Wno-error=format -DLFS_READ_SIZE=1 -DLFS_PROG_SIZE=1"
make -Clittlefs test
make -Clittlefs test QUIET=1
- CFLAGS="-Wno-error=format -DLFS_READ_SIZE=512 -DLFS_PROG_SIZE=512"
make -Clittlefs test
make -Clittlefs test QUIET=1
- CFLAGS="-Wno-error=format -DLFS_BLOCK_COUNT=1023"
make -Clittlefs test
make -Clittlefs test QUIET=1
- CFLAGS="-Wno-error=format -DLFS_LOOKAHEAD=2048"
make -Clittlefs test
make -Clittlefs test QUIET=1
# Self-host with littlefs-fuse for fuzz test
- make -C littlefs-fuse
@ -37,7 +37,7 @@ script:
- cp -r $(git ls-tree --name-only HEAD littlefs/) mount/littlefs
- cd mount/littlefs
- ls
- CFLAGS="-Wno-error=format" make -B test_dirs
- CFLAGS="-Wno-error=format" make -B test_dirs QUIET=1
install:
# Get arm-none-eabi-gcc

View File

@ -34,7 +34,7 @@ static int lfs_toerror(int err) {
case LFS_ERR_OK: return 0;
case LFS_ERR_IO: return -EIO;
case LFS_ERR_NOENT: return -ENOENT;
case LFS_ERR_EXISTS: return -EEXIST;
case LFS_ERR_EXIST: return -EEXIST;
case LFS_ERR_NOTDIR: return -ENOTDIR;
case LFS_ERR_ISDIR: return -EISDIR;
case LFS_ERR_INVAL: return -EINVAL;

View File

@ -25,7 +25,6 @@
- ['LFS_TYPE_([A-Z]+)', 'DT_\1']
- ['LFS_O_([A-Z]+)', 'O_\1']
- ['LFS_SEEK_([A-Z]+)', 'SEEK_\1']
- ['LFS_ERR_EXISTS', '-EEXIST']
- ['LFS_ERR_([A-Z]+)', '-E\1']
- ['lfs_(s?)size_t', '\1size_t']
- ['lfs_soff_t', 'off_t']

View File

@ -22,7 +22,6 @@
- ['LFS_TYPE_([A-Z]+)', 'DT_\1']
- ['LFS_SEEK_([A-Z]+)', 'SEEK_\1']
- ['LFS_ERR_EXISTS', '-EEXIST']
- ['LFS_ERR_([A-Z]+)', '-E\1']
- ['lfs_(s?)size_t', '\1size_t']
- ['lfs_soff_t', 'off_t']

View File

@ -9,13 +9,13 @@ script:
-include stdio.h -Werror' make all size
# run tests
- make test
- make test QUIET=1
# run tests with a few different configurations
- CFLAGS="-DLFS_READ_SIZE=1 -DLFS_PROG_SIZE=1" make test
- CFLAGS="-DLFS_READ_SIZE=512 -DLFS_PROG_SIZE=512" make test
- CFLAGS="-DLFS_BLOCK_COUNT=1023" make test
- CFLAGS="-DLFS_LOOKAHEAD=2048" make test
- CFLAGS="-DLFS_READ_SIZE=1 -DLFS_PROG_SIZE=1" make test QUIET=1
- CFLAGS="-DLFS_READ_SIZE=512 -DLFS_PROG_SIZE=512" make test QUIET=1
- CFLAGS="-DLFS_BLOCK_COUNT=1023" make test QUIET=1
- CFLAGS="-DLFS_LOOKAHEAD=2048" make test QUIET=1
# self-host with littlefs-fuse for fuzz test
- make -C littlefs-fuse
@ -28,7 +28,7 @@ script:
- cp -r $(git ls-tree --name-only HEAD) mount/littlefs
- cd mount/littlefs
- ls
- make -B test_dirs
- make -B test_dirs QUIET=1
before_install:
- fusermount -V

View File

@ -34,7 +34,11 @@ size: $(OBJ)
test: test_format test_dirs test_files test_seek test_parallel \
test_alloc test_paths test_orphan test_move test_corrupt
test_%: tests/test_%.sh
ifdef QUIET
./$< | sed '/^[^-=]/d'
else
./$<
endif
-include $(DEP)

View File

@ -138,8 +138,8 @@ int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block,
snprintf(emu->child, LFS_NAME_MAX, "%x", block);
FILE *f = fopen(emu->path, "r+b");
if (!f && errno != ENOENT) {
return -errno;
if (!f) {
return (errno == EACCES) ? 0 : -errno;
}
// Check that file was erased
@ -189,14 +189,14 @@ int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block) {
return -errno;
}
if (!err && S_ISREG(st.st_mode)) {
if (!err && S_ISREG(st.st_mode) && (S_IWUSR & st.st_mode)) {
int err = unlink(emu->path);
if (err) {
return -errno;
}
}
if (err || S_ISREG(st.st_mode)) {
if (errno == ENOENT || (S_ISREG(st.st_mode) && (S_IWUSR & st.st_mode))) {
FILE *f = fopen(emu->path, "w");
if (!f) {
return -errno;

View File

@ -531,18 +531,19 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_dir_t *dir,
}
// successful commit, check checksum to make sure
crc = 0xffffffff;
uint32_t ncrc = 0xffffffff;
err = lfs_bd_crc(lfs, dir->pair[0], 0,
0x7fffffff & dir->d.size, &crc);
(0x7fffffff & dir->d.size)-4, &ncrc);
if (err) {
return err;
}
if (crc == 0) {
break;
if (ncrc != crc) {
goto relocate;
}
}
break;
relocate:
//commit was corrupted
LFS_DEBUG("Bad block at %ld", dir->pair[0]);
@ -818,7 +819,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
lfs_entry_t entry;
err = lfs_dir_find(lfs, &cwd, &entry, &path);
if (err != LFS_ERR_NOENT || strchr(path, '/') != NULL) {
return err ? err : LFS_ERR_EXISTS;
return err ? err : LFS_ERR_EXIST;
}
// build up new directory
@ -1053,17 +1054,18 @@ static int lfs_ctz_find(lfs_t *lfs,
static int lfs_ctz_extend(lfs_t *lfs,
lfs_cache_t *rcache, lfs_cache_t *pcache,
lfs_block_t head, lfs_size_t size,
lfs_off_t *block, lfs_block_t *off) {
lfs_block_t *block, lfs_off_t *off) {
while (true) {
if (true) {
// go ahead and grab a block
int err = lfs_alloc(lfs, block);
if (err) {
return err;
}
assert(*block >= 2 && *block <= lfs->cfg->block_count);
// go ahead and grab a block
lfs_block_t nblock;
int err = lfs_alloc(lfs, &nblock);
if (err) {
return err;
}
assert(nblock >= 2 && nblock <= lfs->cfg->block_count);
err = lfs_bd_erase(lfs, *block);
if (true) {
err = lfs_bd_erase(lfs, nblock);
if (err) {
if (err == LFS_ERR_CORRUPT) {
goto relocate;
@ -1072,6 +1074,7 @@ static int lfs_ctz_extend(lfs_t *lfs,
}
if (size == 0) {
*block = nblock;
*off = 0;
return 0;
}
@ -1091,7 +1094,7 @@ static int lfs_ctz_extend(lfs_t *lfs,
}
err = lfs_cache_prog(lfs, pcache, rcache,
*block, i, &data, 1);
nblock, i, &data, 1);
if (err) {
if (err == LFS_ERR_CORRUPT) {
goto relocate;
@ -1100,6 +1103,7 @@ static int lfs_ctz_extend(lfs_t *lfs,
}
}
*block = nblock;
*off = size;
return 0;
}
@ -1110,7 +1114,7 @@ static int lfs_ctz_extend(lfs_t *lfs,
for (lfs_off_t i = 0; i < skips; i++) {
int err = lfs_cache_prog(lfs, pcache, rcache,
*block, 4*i, &head, 4);
nblock, 4*i, &head, 4);
if (err) {
if (err == LFS_ERR_CORRUPT) {
goto relocate;
@ -1129,12 +1133,13 @@ static int lfs_ctz_extend(lfs_t *lfs,
assert(head >= 2 && head <= lfs->cfg->block_count);
}
*block = nblock;
*off = 4*skips;
return 0;
}
relocate:
LFS_DEBUG("Bad block at %ld", *block);
LFS_DEBUG("Bad block at %ld", nblock);
// just clear cache and try a new block
pcache->block = 0xffffffff;
@ -1214,7 +1219,7 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
} else if (entry.d.type == LFS_TYPE_DIR) {
return LFS_ERR_ISDIR;
} else if (flags & LFS_O_EXCL) {
return LFS_ERR_EXISTS;
return LFS_ERR_EXIST;
}
// setup file struct
@ -1398,7 +1403,9 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) {
return err;
}
if ((file->flags & LFS_F_DIRTY) && !lfs_pairisnull(file->pair)) {
if ((file->flags & LFS_F_DIRTY) &&
!(file->flags & LFS_F_ERRED) &&
!lfs_pairisnull(file->pair)) {
// update dir entry
lfs_dir_t cwd;
int err = lfs_dir_fetch(lfs, &cwd, file->pair);
@ -1532,6 +1539,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
file->head, file->size,
file->pos-1, &file->block, &file->off);
if (err) {
file->flags |= LFS_F_ERRED;
return err;
}
@ -1545,6 +1553,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
file->block, file->pos,
&file->block, &file->off);
if (err) {
file->flags |= LFS_F_ERRED;
return err;
}
@ -1560,6 +1569,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
if (err == LFS_ERR_CORRUPT) {
goto relocate;
}
file->flags |= LFS_F_ERRED;
return err;
}
@ -1567,6 +1577,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
relocate:
err = lfs_file_relocate(lfs, file);
if (err) {
file->flags |= LFS_F_ERRED;
return err;
}
}
@ -1579,6 +1590,7 @@ relocate:
lfs_alloc_ack(lfs);
}
file->flags &= ~LFS_F_ERRED;
return size;
}

View File

@ -45,7 +45,7 @@ enum lfs_error {
LFS_ERR_IO = -5, // Error during device operation
LFS_ERR_CORRUPT = -52, // Corrupted
LFS_ERR_NOENT = -2, // No directory entry
LFS_ERR_EXISTS = -17, // Entry already exists
LFS_ERR_EXIST = -17, // Entry already exists
LFS_ERR_NOTDIR = -20, // Entry is not a dir
LFS_ERR_ISDIR = -21, // Entry is a dir
LFS_ERR_INVAL = -22, // Invalid parameter
@ -75,6 +75,7 @@ enum lfs_open_flags {
LFS_F_DIRTY = 0x10000, // File does not match storage
LFS_F_WRITING = 0x20000, // File has been written since last flush
LFS_F_READING = 0x40000, // File has been read since last flush
LFS_F_ERRED = 0x80000, // An error occured during write
};
// File seek flags

View File

@ -121,6 +121,7 @@ tests/test.py << TEST
size = strlen("exhaustion");
memcpy(buffer, "exhaustion", size);
lfs_file_write(&lfs, &file[0], buffer, size) => size;
lfs_file_sync(&lfs, &file[0]) => 0;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
@ -142,6 +143,7 @@ tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_RDONLY);
size = strlen("exhaustion");
lfs_file_size(&lfs, &file[0]) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "exhaustion", size) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
@ -166,6 +168,7 @@ tests/test.py << TEST
size = strlen("exhaustion");
memcpy(buffer, "exhaustion", size);
lfs_file_write(&lfs, &file[0], buffer, size) => size;
lfs_file_sync(&lfs, &file[0]) => 0;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
@ -187,6 +190,7 @@ tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_RDONLY);
size = strlen("exhaustion");
lfs_file_size(&lfs, &file[0]) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "exhaustion", size) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
@ -196,14 +200,14 @@ TEST
echo "--- Dir exhaustion test ---"
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "exhaustion", &info) => 0;
lfs_size_t fullsize = info.size;
lfs_remove(&lfs, "exhaustion") => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs_size_t i = 0; i < fullsize - 2*512; i += size) {
for (lfs_size_t i = 0;
i < (cfg.block_count-6)*(cfg.block_size-8);
i += size) {
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs_file_close(&lfs, &file[0]) => 0;
@ -214,7 +218,11 @@ tests/test.py << TEST
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_APPEND);
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
lfs_file_write(&lfs, &file[0], buffer, size) => size;
for (lfs_size_t i = 0;
i < (cfg.block_size-8);
i += size) {
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs_file_close(&lfs, &file[0]) => 0;
lfs_mkdir(&lfs, "exhaustiondir") => LFS_ERR_NOSPC;
@ -224,14 +232,14 @@ TEST
echo "--- Chained dir exhaustion test ---"
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "exhaustion", &info) => 0;
lfs_size_t fullsize = info.size;
lfs_remove(&lfs, "exhaustion") => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs_size_t i = 0; i < fullsize - 19*512; i += size) {
for (lfs_size_t i = 0;
i < (cfg.block_count-24)*(cfg.block_size-8);
i += size) {
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs_file_close(&lfs, &file[0]) => 0;
@ -247,7 +255,9 @@ tests/test.py << TEST
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs_size_t i = 0; i < fullsize - 20*512; i += size) {
for (lfs_size_t i = 0;
i < (cfg.block_count-26)*(cfg.block_size-8);
i += size) {
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs_file_close(&lfs, &file[0]) => 0;

View File

@ -82,6 +82,17 @@ do
lfs_chktree
done
echo "--- Block persistance ---"
for i in {0..33}
do
rm -rf blocks
mkdir blocks
lfs_mktree
chmod a-w blocks/$(printf '%x' $i)
lfs_mktree
lfs_chktree
done
echo "--- Big region corruption ---"
rm -rf blocks
mkdir blocks

View File

@ -56,7 +56,7 @@ TEST
echo "--- Directory failures ---"
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "potato") => LFS_ERR_EXISTS;
lfs_mkdir(&lfs, "potato") => LFS_ERR_EXIST;
lfs_dir_open(&lfs, &dir[0], "tomato") => LFS_ERR_NOENT;
lfs_dir_open(&lfs, &dir[0], "burito") => LFS_ERR_NOTDIR;
lfs_file_open(&lfs, &file[0], "tomato", LFS_O_RDONLY) => LFS_ERR_NOENT;