mirror of https://github.com/ARMmbed/mbed-os.git
Merge commit '6e99fa9319d17f0aef418ae3989befc04ecf9096' into new-update
commit
37edc35091
|
@ -9,6 +9,10 @@ script:
|
|||
-include stdio.h -Werror' make all size
|
||||
|
||||
# run tests
|
||||
- CFLAGS="-DLFS_READ_SIZE=16 -DLFS_PROG_SIZE=16" make test
|
||||
- make test
|
||||
|
||||
# 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=2047" make test
|
||||
|
|
139
littlefs/lfs.c
139
littlefs/lfs.c
|
@ -262,9 +262,12 @@ int lfs_deorphan(lfs_t *lfs);
|
|||
static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
|
||||
lfs_t *lfs = p;
|
||||
|
||||
lfs_block_t off = (block - lfs->free.start) % lfs->cfg->block_count;
|
||||
if (off < lfs->cfg->lookahead) {
|
||||
lfs->free.lookahead[off / 32] |= 1U << (off % 32);
|
||||
lfs_block_t off = (((lfs_soff_t)(block - lfs->free.begin)
|
||||
% (lfs_soff_t)(lfs->cfg->block_count))
|
||||
+ lfs->cfg->block_count) % lfs->cfg->block_count;
|
||||
|
||||
if (off < lfs->free.lookahead) {
|
||||
lfs->free.buffer[off / 32] |= 1U << (off % 32);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -282,30 +285,30 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
|||
while (true) {
|
||||
while (true) {
|
||||
// check if we have looked at all blocks since last ack
|
||||
if (lfs->free.start + lfs->free.off == lfs->free.end) {
|
||||
if (lfs->free.begin + lfs->free.off == lfs->free.end) {
|
||||
LFS_WARN("No more free space %ld", lfs->free.end);
|
||||
return LFS_ERR_NOSPC;
|
||||
}
|
||||
|
||||
if (lfs->free.off >= lfs->cfg->lookahead) {
|
||||
if (lfs->free.off >= lfs->free.lookahead) {
|
||||
break;
|
||||
}
|
||||
|
||||
lfs_block_t off = lfs->free.off;
|
||||
lfs->free.off += 1;
|
||||
|
||||
if (!(lfs->free.lookahead[off / 32] & (1U << (off % 32)))) {
|
||||
if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) {
|
||||
// found a free block
|
||||
*block = (lfs->free.start + off) % lfs->cfg->block_count;
|
||||
*block = (lfs->free.begin + off) % lfs->cfg->block_count;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
lfs->free.start += lfs->cfg->lookahead;
|
||||
lfs->free.begin += lfs->free.lookahead;
|
||||
lfs->free.off = 0;
|
||||
|
||||
// find mask of free blocks from tree
|
||||
memset(lfs->free.lookahead, 0, lfs->cfg->lookahead/8);
|
||||
memset(lfs->free.buffer, 0, lfs->free.lookahead/8);
|
||||
int err = lfs_traverse(lfs, lfs_alloc_lookahead, lfs);
|
||||
if (err) {
|
||||
return err;
|
||||
|
@ -314,7 +317,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
|||
}
|
||||
|
||||
static void lfs_alloc_ack(lfs_t *lfs) {
|
||||
lfs->free.end = lfs->free.start + lfs->free.off + lfs->cfg->block_count;
|
||||
lfs->free.end = lfs->free.begin + lfs->free.off + lfs->cfg->block_count;
|
||||
}
|
||||
|
||||
|
||||
|
@ -343,6 +346,10 @@ static inline bool lfs_pairsync(
|
|||
(paira[0] == pairb[1] && paira[1] == pairb[0]);
|
||||
}
|
||||
|
||||
static inline lfs_size_t lfs_entry_size(const lfs_entry_t *entry) {
|
||||
return 4 + entry->d.elen + entry->d.alen + entry->d.nlen;
|
||||
}
|
||||
|
||||
static int lfs_dir_alloc(lfs_t *lfs, lfs_dir_t *dir) {
|
||||
// allocate pair of dir blocks
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
@ -568,8 +575,7 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir,
|
|||
lfs_entry_t *entry, const void *data) {
|
||||
// check if we fit, if top bit is set we do not and move on
|
||||
while (true) {
|
||||
if (dir->d.size + 4+entry->d.elen+entry->d.alen+entry->d.nlen
|
||||
<= lfs->cfg->block_size) {
|
||||
if (dir->d.size + lfs_entry_size(entry) <= lfs->cfg->block_size) {
|
||||
entry->off = dir->d.size - 4;
|
||||
return lfs_dir_commit(lfs, dir, (struct lfs_region[]){
|
||||
{entry->off, 0, &entry->d, sizeof(entry->d)},
|
||||
|
@ -611,7 +617,8 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir,
|
|||
|
||||
static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
|
||||
// either shift out the one entry or remove the whole dir block
|
||||
if (dir->d.size == sizeof(dir->d)+4) {
|
||||
if ((dir->d.size & 0x7fffffff) == sizeof(dir->d)+4
|
||||
+ lfs_entry_size(entry)) {
|
||||
lfs_dir_t pdir;
|
||||
int res = lfs_pred(lfs, dir->pair, &pdir);
|
||||
if (res < 0) {
|
||||
|
@ -620,18 +627,17 @@ static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
|
|||
|
||||
if (!(pdir.d.size & 0x80000000)) {
|
||||
return lfs_dir_commit(lfs, dir, (struct lfs_region[]){
|
||||
{entry->off, 4+entry->d.elen+entry->d.alen+entry->d.nlen,
|
||||
NULL, 0},
|
||||
{entry->off, lfs_entry_size(entry), NULL, 0},
|
||||
}, 1);
|
||||
} else {
|
||||
pdir.d.size &= dir->d.size | 0x7fffffff;
|
||||
pdir.d.tail[0] = dir->d.tail[0];
|
||||
pdir.d.tail[1] = dir->d.tail[1];
|
||||
return lfs_dir_commit(lfs, dir, NULL, 0);
|
||||
return lfs_dir_commit(lfs, &pdir, NULL, 0);
|
||||
}
|
||||
} else {
|
||||
return lfs_dir_commit(lfs, dir, (struct lfs_region[]){
|
||||
{entry->off, 4+entry->d.elen+entry->d.alen+entry->d.nlen,
|
||||
NULL, 0},
|
||||
{entry->off, lfs_entry_size(entry), NULL, 0},
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
|
@ -659,8 +665,8 @@ static int lfs_dir_next(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
|
|||
}
|
||||
|
||||
entry->off = dir->off;
|
||||
dir->off += 4+entry->d.elen+entry->d.alen+entry->d.nlen;
|
||||
dir->pos += 4+entry->d.elen+entry->d.alen+entry->d.nlen;
|
||||
dir->off += lfs_entry_size(entry);
|
||||
dir->pos += lfs_entry_size(entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -706,6 +712,9 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
|
|||
suffix += sufflen;
|
||||
}
|
||||
|
||||
// update what we've found
|
||||
*path = pathname;
|
||||
|
||||
// find path
|
||||
while (true) {
|
||||
int err = lfs_dir_next(lfs, dir, entry);
|
||||
|
@ -747,8 +756,6 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
|
|||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
*path = pathname;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -766,7 +773,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) {
|
||||
if (err != LFS_ERR_NOENT || strchr(path, '/') != NULL) {
|
||||
return err ? err : LFS_ERR_EXISTS;
|
||||
}
|
||||
|
||||
|
@ -814,8 +821,8 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
|
|||
return err;
|
||||
}
|
||||
|
||||
// check for root, can only be something like '/././../.'
|
||||
if (strspn(path, "/.") == strlen(path)) {
|
||||
// can only be something like '/././../.'
|
||||
dir->head[0] = dir->pair[0];
|
||||
dir->head[1] = dir->pair[1];
|
||||
dir->pos = sizeof(dir->d) - 2;
|
||||
|
@ -975,6 +982,7 @@ static int lfs_index_find(lfs_t *lfs,
|
|||
return err;
|
||||
}
|
||||
|
||||
assert(head >= 2 && head <= lfs->cfg->block_count);
|
||||
current -= 1 << skip;
|
||||
}
|
||||
|
||||
|
@ -993,6 +1001,7 @@ static int lfs_index_extend(lfs_t *lfs,
|
|||
if (err) {
|
||||
return err;
|
||||
}
|
||||
assert(*block >= 2 && *block <= lfs->cfg->block_count);
|
||||
|
||||
err = lfs_bd_erase(lfs, *block);
|
||||
if (err) {
|
||||
|
@ -1054,6 +1063,8 @@ static int lfs_index_extend(lfs_t *lfs,
|
|||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
assert(head >= 2 && head <= lfs->cfg->block_count);
|
||||
}
|
||||
|
||||
*off = 4*skips;
|
||||
|
@ -1111,7 +1122,7 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
|
|||
|
||||
lfs_entry_t entry;
|
||||
err = lfs_dir_find(lfs, &cwd, &entry, &path);
|
||||
if (err && err != LFS_ERR_NOENT) {
|
||||
if (err && (err != LFS_ERR_NOENT || strchr(path, '/') != NULL)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1369,6 +1380,11 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
|||
}
|
||||
}
|
||||
|
||||
if (file->pos >= file->size) {
|
||||
// eof if past end
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = lfs_min(size, file->size - file->pos);
|
||||
nsize = size;
|
||||
|
||||
|
@ -1424,22 +1440,34 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
|
|||
file->pos = file->size;
|
||||
}
|
||||
|
||||
if (!(file->flags & LFS_F_WRITING) && file->pos > file->size) {
|
||||
// fill with zeros
|
||||
lfs_off_t pos = file->pos;
|
||||
file->pos = file->size;
|
||||
|
||||
while (file->pos < pos) {
|
||||
lfs_ssize_t res = lfs_file_write(lfs, file, &(uint8_t){0}, 1);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (nsize > 0) {
|
||||
// check if we need a new block
|
||||
if (!(file->flags & LFS_F_WRITING) ||
|
||||
file->off == lfs->cfg->block_size) {
|
||||
if (!(file->flags & LFS_F_WRITING)) {
|
||||
if (!(file->flags & LFS_F_WRITING) && file->pos > 0) {
|
||||
// find out which block we're extending from
|
||||
int err = lfs_index_find(lfs, &file->cache, NULL,
|
||||
file->head, file->size,
|
||||
file->pos, &file->block, &file->off);
|
||||
file->pos-1, &file->block, &file->off);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// mark cache as dirty since we may have read data into it
|
||||
file->cache.block = 0xffffffff;
|
||||
file->flags |= LFS_F_WRITING;
|
||||
}
|
||||
|
||||
// extend file with new blocks
|
||||
|
@ -1450,6 +1478,8 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
|
|||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
file->flags |= LFS_F_WRITING;
|
||||
}
|
||||
|
||||
// program as much as we can in current block
|
||||
|
@ -1492,17 +1522,23 @@ lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
|
|||
}
|
||||
|
||||
// update pos
|
||||
lfs_off_t pos = file->pos;
|
||||
|
||||
if (whence == LFS_SEEK_SET) {
|
||||
file->pos = off;
|
||||
} else if (whence == LFS_SEEK_CUR) {
|
||||
if (-off > file->pos) {
|
||||
return LFS_ERR_INVAL;
|
||||
}
|
||||
|
||||
file->pos = file->pos + off;
|
||||
} else if (whence == LFS_SEEK_END) {
|
||||
if (-off > file->size) {
|
||||
return LFS_ERR_INVAL;
|
||||
}
|
||||
|
||||
file->pos = file->size + off;
|
||||
}
|
||||
|
||||
return pos;
|
||||
return file->pos;
|
||||
}
|
||||
|
||||
lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file) {
|
||||
|
@ -1525,6 +1561,14 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
|
|||
|
||||
/// General fs oprations ///
|
||||
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
|
||||
// check for root, can only be something like '/././../.'
|
||||
if (strspn(path, "/.") == strlen(path)) {
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->type = LFS_TYPE_DIR;
|
||||
strcpy(info->name, "/");
|
||||
return 0;
|
||||
}
|
||||
|
||||
lfs_dir_t cwd;
|
||||
int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
|
||||
if (err) {
|
||||
|
@ -1592,7 +1636,7 @@ int lfs_remove(lfs_t *lfs, const char *path) {
|
|||
f->pair[0] = 0xffffffff;
|
||||
f->pair[1] = 0xffffffff;
|
||||
} else if (f->poff > entry.off) {
|
||||
f->poff -= 4 + entry.d.elen + entry.d.alen + entry.d.nlen;
|
||||
f->poff -= lfs_entry_size(&entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1632,7 +1676,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
|
|||
|
||||
lfs_entry_t preventry;
|
||||
err = lfs_dir_find(lfs, &newcwd, &preventry, &newpath);
|
||||
if (err && err != LFS_ERR_NOENT) {
|
||||
if (err && (err != LFS_ERR_NOENT || strchr(newpath, '/') != NULL)) {
|
||||
return err;
|
||||
}
|
||||
bool prevexists = (err != LFS_ERR_NOENT);
|
||||
|
@ -1696,7 +1740,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
|
|||
f->pair[0] = 0xffffffff;
|
||||
f->pair[1] = 0xffffffff;
|
||||
} else if (f->poff > oldentry.off) {
|
||||
f->poff -= 4+oldentry.d.elen+oldentry.d.alen+oldentry.d.nlen;
|
||||
f->poff -= lfs_entry_size(&oldentry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1740,12 +1784,15 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||
}
|
||||
}
|
||||
|
||||
// setup lookahead
|
||||
// setup lookahead, round down to nearest 32-bits
|
||||
lfs->free.lookahead = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
|
||||
lfs->free.lookahead = 32 * (lfs->free.lookahead / 32);
|
||||
assert(lfs->free.lookahead > 0);
|
||||
if (lfs->cfg->lookahead_buffer) {
|
||||
lfs->free.lookahead = lfs->cfg->lookahead_buffer;
|
||||
lfs->free.buffer = lfs->cfg->lookahead_buffer;
|
||||
} else {
|
||||
lfs->free.lookahead = malloc(lfs->cfg->lookahead/8);
|
||||
if (!lfs->free.lookahead) {
|
||||
lfs->free.buffer = malloc(lfs->free.lookahead/8);
|
||||
if (!lfs->free.buffer) {
|
||||
return LFS_ERR_NOMEM;
|
||||
}
|
||||
}
|
||||
|
@ -1770,7 +1817,7 @@ static int lfs_deinit(lfs_t *lfs) {
|
|||
}
|
||||
|
||||
if (!lfs->cfg->lookahead_buffer) {
|
||||
free(lfs->free.lookahead);
|
||||
free(lfs->free.buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1783,10 +1830,10 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||
}
|
||||
|
||||
// create free lookahead
|
||||
memset(lfs->free.lookahead, 0, lfs->cfg->lookahead/8);
|
||||
lfs->free.start = 0;
|
||||
memset(lfs->free.buffer, 0, lfs->free.lookahead/8);
|
||||
lfs->free.begin = 0;
|
||||
lfs->free.off = 0;
|
||||
lfs->free.end = lfs->free.start + lfs->cfg->block_count;
|
||||
lfs->free.end = lfs->free.begin + lfs->cfg->block_count;
|
||||
|
||||
// create superblock dir
|
||||
lfs_alloc_ack(lfs);
|
||||
|
@ -1862,9 +1909,9 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||
}
|
||||
|
||||
// setup free lookahead
|
||||
lfs->free.start = -lfs->cfg->lookahead;
|
||||
lfs->free.off = lfs->cfg->lookahead;
|
||||
lfs->free.end = lfs->free.start + lfs->cfg->block_count;
|
||||
lfs->free.begin = -lfs->free.lookahead;
|
||||
lfs->free.off = lfs->free.lookahead;
|
||||
lfs->free.end = lfs->free.begin + lfs->cfg->block_count;
|
||||
|
||||
// load superblock
|
||||
lfs_dir_t dir;
|
||||
|
@ -1931,7 +1978,7 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) {
|
|||
return err;
|
||||
}
|
||||
|
||||
dir.off += 4+entry.d.elen+entry.d.alen+entry.d.nlen;
|
||||
dir.off += lfs_entry_size(&entry);
|
||||
if ((0xf & entry.d.type) == (0xf & LFS_TYPE_REG)) {
|
||||
int err = lfs_index_traverse(lfs, &lfs->rcache, NULL,
|
||||
entry.d.u.file.head, entry.d.u.file.size, cb, data);
|
||||
|
|
|
@ -225,10 +225,11 @@ typedef struct lfs_superblock {
|
|||
} lfs_superblock_t;
|
||||
|
||||
typedef struct lfs_free {
|
||||
lfs_size_t lookahead;
|
||||
lfs_block_t begin;
|
||||
lfs_block_t end;
|
||||
lfs_block_t start;
|
||||
lfs_block_t off;
|
||||
uint32_t *lookahead;
|
||||
uint32_t *buffer;
|
||||
} lfs_free_t;
|
||||
|
||||
// The littlefs type
|
||||
|
@ -237,12 +238,12 @@ typedef struct lfs {
|
|||
|
||||
lfs_block_t root[2];
|
||||
lfs_file_t *files;
|
||||
bool deorphaned;
|
||||
|
||||
lfs_cache_t rcache;
|
||||
lfs_cache_t pcache;
|
||||
|
||||
lfs_free_t free;
|
||||
bool deorphaned;
|
||||
} lfs_t;
|
||||
|
||||
|
||||
|
|
|
@ -124,7 +124,6 @@ tests/test.py << TEST
|
|||
TEST
|
||||
|
||||
echo "--- Directory remove ---"
|
||||
# TESTING HERE
|
||||
tests/test.py << TEST
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_remove(&lfs, "potato") => LFS_ERR_INVAL;
|
||||
|
@ -283,5 +282,38 @@ tests/test.py << TEST
|
|||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
echo "--- Multi-block remove ---"
|
||||
tests/test.py << TEST
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_remove(&lfs, "cactus") => LFS_ERR_INVAL;
|
||||
|
||||
for (int i = 0; i < $LARGESIZE; i++) {
|
||||
sprintf((char*)buffer, "cactus/test%d", i);
|
||||
lfs_remove(&lfs, (char*)buffer) => 0;
|
||||
}
|
||||
|
||||
lfs_remove(&lfs, "cactus") => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
tests/test.py << TEST
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_dir_open(&lfs, &dir[0], "/") => 0;
|
||||
lfs_dir_read(&lfs, &dir[0], &info) => 1;
|
||||
strcmp(info.name, ".") => 0;
|
||||
info.type => LFS_TYPE_DIR;
|
||||
lfs_dir_read(&lfs, &dir[0], &info) => 1;
|
||||
strcmp(info.name, "..") => 0;
|
||||
info.type => LFS_TYPE_DIR;
|
||||
lfs_dir_read(&lfs, &dir[0], &info) => 1;
|
||||
strcmp(info.name, "burito") => 0;
|
||||
info.type => LFS_TYPE_REG;
|
||||
lfs_dir_read(&lfs, &dir[0], &info) => 1;
|
||||
strcmp(info.name, "coldpotato") => 0;
|
||||
info.type => LFS_TYPE_DIR;
|
||||
lfs_dir_read(&lfs, &dir[0], &info) => 0;
|
||||
lfs_dir_close(&lfs, &dir[0]) => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
echo "--- Results ---"
|
||||
tests/stats.py
|
||||
|
|
|
@ -31,6 +31,10 @@ tests/test.py << TEST
|
|||
strcmp(info.name, "hottea") => 0;
|
||||
lfs_stat(&lfs, "/tea/hottea", &info) => 0;
|
||||
strcmp(info.name, "hottea") => 0;
|
||||
|
||||
lfs_mkdir(&lfs, "/milk1") => 0;
|
||||
lfs_stat(&lfs, "/milk1", &info) => 0;
|
||||
strcmp(info.name, "milk1") => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
|
@ -43,6 +47,10 @@ tests/test.py << TEST
|
|||
strcmp(info.name, "hottea") => 0;
|
||||
lfs_stat(&lfs, "///tea///hottea", &info) => 0;
|
||||
strcmp(info.name, "hottea") => 0;
|
||||
|
||||
lfs_mkdir(&lfs, "///milk2") => 0;
|
||||
lfs_stat(&lfs, "///milk2", &info) => 0;
|
||||
strcmp(info.name, "milk2") => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
|
@ -57,6 +65,10 @@ tests/test.py << TEST
|
|||
strcmp(info.name, "hottea") => 0;
|
||||
lfs_stat(&lfs, "/./tea/./hottea", &info) => 0;
|
||||
strcmp(info.name, "hottea") => 0;
|
||||
|
||||
lfs_mkdir(&lfs, "/./milk3") => 0;
|
||||
lfs_stat(&lfs, "/./milk3", &info) => 0;
|
||||
strcmp(info.name, "milk3") => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
|
@ -71,6 +83,10 @@ tests/test.py << TEST
|
|||
strcmp(info.name, "hottea") => 0;
|
||||
lfs_stat(&lfs, "coffee/../soda/../tea/hottea", &info) => 0;
|
||||
strcmp(info.name, "hottea") => 0;
|
||||
|
||||
lfs_mkdir(&lfs, "coffee/../milk4") => 0;
|
||||
lfs_stat(&lfs, "coffee/../milk4", &info) => 0;
|
||||
strcmp(info.name, "milk4") => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
|
@ -79,6 +95,27 @@ tests/test.py << TEST
|
|||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_stat(&lfs, "coffee/../../../../../../tea/hottea", &info) => 0;
|
||||
strcmp(info.name, "hottea") => 0;
|
||||
|
||||
lfs_mkdir(&lfs, "coffee/../../../../../../milk5") => 0;
|
||||
lfs_stat(&lfs, "coffee/../../../../../../milk5", &info) => 0;
|
||||
strcmp(info.name, "milk5") => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
echo "--- Root tests ---"
|
||||
tests/test.py << TEST
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_stat(&lfs, "/", &info) => 0;
|
||||
info.type => LFS_TYPE_DIR;
|
||||
strcmp(info.name, "/") => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
echo "--- Sketchy path tests ---"
|
||||
tests/test.py << TEST
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_mkdir(&lfs, "dirt/ground") => LFS_ERR_NOENT;
|
||||
lfs_mkdir(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
|
|
|
@ -133,15 +133,15 @@ tests/test.py << TEST
|
|||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => size;
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_CUR) => pos+size;
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_CUR) => pos;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) => pos+size;
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) >= 0 => 1;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
|
@ -174,15 +174,15 @@ tests/test.py << TEST
|
|||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => size;
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_CUR) => pos+size;
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_CUR) => pos;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) => pos+size;
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) >= 0 => 1;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
|
@ -211,7 +211,7 @@ tests/test.py << TEST
|
|||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
|
||||
lfs_file_write(&lfs, &file[0], buffer, size) => size;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos+size;
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "doggodogdog", size) => 0;
|
||||
|
||||
|
@ -219,11 +219,11 @@ tests/test.py << TEST
|
|||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => size;
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "doggodogdog", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) => pos+size;
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) >= 0 => 1;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
|
@ -254,7 +254,7 @@ tests/test.py << TEST
|
|||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
|
||||
lfs_file_write(&lfs, &file[0], buffer, size) => size;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos+size;
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "doggodogdog", size) => 0;
|
||||
|
||||
|
@ -262,11 +262,11 @@ tests/test.py << TEST
|
|||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => size;
|
||||
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "doggodogdog", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) => pos+size;
|
||||
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) >= 0 => 1;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
|
@ -277,5 +277,69 @@ tests/test.py << TEST
|
|||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
echo "--- Boundary seek and write ---"
|
||||
tests/test.py << TEST
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_file_open(&lfs, &file[0], "hello/kitty42", LFS_O_RDWR) => 0;
|
||||
|
||||
size = strlen("hedgehoghog");
|
||||
const lfs_soff_t offsets[] = {512, 1020, 513, 1021, 511, 1019};
|
||||
|
||||
for (int i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++) {
|
||||
lfs_soff_t off = offsets[i];
|
||||
memcpy(buffer, "hedgehoghog", size);
|
||||
lfs_file_seek(&lfs, &file[0], off, LFS_SEEK_SET) => off;
|
||||
lfs_file_write(&lfs, &file[0], buffer, size) => size;
|
||||
lfs_file_seek(&lfs, &file[0], off, LFS_SEEK_SET) => off;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "hedgehoghog", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_SET) => 0;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "kittycatcat", size) => 0;
|
||||
|
||||
lfs_file_sync(&lfs, &file[0]) => 0;
|
||||
}
|
||||
|
||||
lfs_file_close(&lfs, &file[0]) => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
echo "--- Out-of-bounds seek ---"
|
||||
tests/test.py << TEST
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
lfs_file_open(&lfs, &file[0], "hello/kitty42", LFS_O_RDWR) => 0;
|
||||
|
||||
size = strlen("kittycatcat");
|
||||
lfs_file_size(&lfs, &file[0]) => $LARGESIZE*size;
|
||||
lfs_file_seek(&lfs, &file[0], ($LARGESIZE+$SMALLSIZE)*size,
|
||||
LFS_SEEK_SET) => ($LARGESIZE+$SMALLSIZE)*size;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => 0;
|
||||
|
||||
memcpy(buffer, "porcupineee", size);
|
||||
lfs_file_write(&lfs, &file[0], buffer, size) => size;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], ($LARGESIZE+$SMALLSIZE)*size,
|
||||
LFS_SEEK_SET) => ($LARGESIZE+$SMALLSIZE)*size;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "porcupineee", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], $LARGESIZE*size,
|
||||
LFS_SEEK_SET) => $LARGESIZE*size;
|
||||
lfs_file_read(&lfs, &file[0], buffer, size) => size;
|
||||
memcmp(buffer, "\0\0\0\0\0\0\0\0\0\0\0", size) => 0;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], -(($LARGESIZE+$SMALLSIZE)*size),
|
||||
LFS_SEEK_CUR) => LFS_ERR_INVAL;
|
||||
lfs_file_tell(&lfs, &file[0]) => ($LARGESIZE+1)*size;
|
||||
|
||||
lfs_file_seek(&lfs, &file[0], -(($LARGESIZE+2*$SMALLSIZE)*size),
|
||||
LFS_SEEK_END) => LFS_ERR_INVAL;
|
||||
lfs_file_tell(&lfs, &file[0]) => ($LARGESIZE+1)*size;
|
||||
|
||||
lfs_file_close(&lfs, &file[0]) => 0;
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
echo "--- Results ---"
|
||||
tests/stats.py
|
||||
|
|
Loading…
Reference in New Issue