Compare commits

..

2 Commits

Author SHA1 Message Date
Christopher Haster
9acf6a08b1 Stop wear-leveling during migration
Stop proactively relocate blocks during migrations, this can cause a number of
failure states such: clobbering the v1 superblock if we relocate root, and
invalidating directory pointers if we relocate the head of a directory. On top
of this, relocations increase the overall complexity of lfs_migration, which is
already a delicate operation.
2019-11-26 17:47:06 -06:00
Christopher Haster
88ed8623be Fixed issue with directories falling out of date after block relocation
This is caused by dir->head not being updated when dir->m.pair may be.
This causes the two to fall out of sync and later dir rewinds to fail.

This bug stems all the way back from the first commits of littlefs, so
it's surprising it has avoided detection for this long. Perhaps because
lfs_dir_rewind is not used often.
2019-11-26 10:57:15 -06:00
6 changed files with 41 additions and 189 deletions

View File

@@ -20,7 +20,6 @@ script:
# run tests with a few different configurations # run tests with a few different configurations
- make test QUIET=1 CFLAGS+="-DLFS_READ_SIZE=1 -DLFS_CACHE_SIZE=4" - make test QUIET=1 CFLAGS+="-DLFS_READ_SIZE=1 -DLFS_CACHE_SIZE=4"
- make test QUIET=1 CFLAGS+="-DLFS_READ_SIZE=512 -DLFS_CACHE_SIZE=512 -DLFS_BLOCK_CYCLES=16" - make test QUIET=1 CFLAGS+="-DLFS_READ_SIZE=512 -DLFS_CACHE_SIZE=512 -DLFS_BLOCK_CYCLES=16"
- make test QUIET=1 CFLAGS+="-DLFS_READ_SIZE=8 -DLFS_CACHE_SIZE=16 -DLFS_BLOCK_CYCLES=2"
- make test QUIET=1 CFLAGS+="-DLFS_BLOCK_COUNT=1023 -DLFS_LOOKAHEAD_SIZE=256" - make test QUIET=1 CFLAGS+="-DLFS_BLOCK_COUNT=1023 -DLFS_LOOKAHEAD_SIZE=256"
- make clean test QUIET=1 CFLAGS+="-DLFS_INLINE_MAX=0" - make clean test QUIET=1 CFLAGS+="-DLFS_INLINE_MAX=0"

View File

@@ -110,7 +110,7 @@ directory functions, with the deviation that the allocation of filesystem
structures must be provided by the user. structures must be provided by the user.
All POSIX operations, such as remove and rename, are atomic, even in event All POSIX operations, such as remove and rename, are atomic, even in event
of power-loss. Additionally, file updates are not actually committed to of power-loss. Additionally, no file updates are not actually committed to
the filesystem until sync or close is called on the file. the filesystem until sync or close is called on the file.
## Other notes ## Other notes

92
lfs.c
View File

@@ -929,11 +929,6 @@ static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs,
if (res == LFS_CMP_EQ) { if (res == LFS_CMP_EQ) {
// found a match // found a match
tempbesttag = tag; tempbesttag = tag;
} else if ((LFS_MKTAG(0x7ff, 0x3ff, 0) & tag) ==
(LFS_MKTAG(0x7ff, 0x3ff, 0) & tempbesttag)) {
// found an identical tag, but contents didn't match
// this must mean that our besttag has been overwritten
tempbesttag = -1;
} else if (res == LFS_CMP_GT && } else if (res == LFS_CMP_GT &&
lfs_tag_id(tag) <= lfs_tag_id(tempbesttag)) { lfs_tag_id(tag) <= lfs_tag_id(tempbesttag)) {
// found a greater match, keep track to keep things sorted // found a greater match, keep track to keep things sorted
@@ -980,10 +975,9 @@ static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs,
static int lfs_dir_fetch(lfs_t *lfs, static int lfs_dir_fetch(lfs_t *lfs,
lfs_mdir_t *dir, const lfs_block_t pair[2]) { lfs_mdir_t *dir, const lfs_block_t pair[2]) {
// note, mask=-1, tag=-1 can never match a tag since this // note, mask=-1, tag=0 can never match a tag since this
// pattern has the invalid bit set // pattern has the invalid bit set
return (int)lfs_dir_fetchmatch(lfs, dir, pair, return (int)lfs_dir_fetchmatch(lfs, dir, pair, -1, 0, NULL, NULL, NULL);
(lfs_tag_t)-1, (lfs_tag_t)-1, NULL, NULL, NULL);
} }
static int lfs_dir_getgstate(lfs_t *lfs, const lfs_mdir_t *dir, static int lfs_dir_getgstate(lfs_t *lfs, const lfs_mdir_t *dir,
@@ -1383,7 +1377,6 @@ static int lfs_dir_split(lfs_t *lfs,
lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount, lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount,
lfs_mdir_t *source, uint16_t split, uint16_t end) { lfs_mdir_t *source, uint16_t split, uint16_t end) {
// create tail directory // create tail directory
lfs_alloc_ack(lfs);
lfs_mdir_t tail; lfs_mdir_t tail;
int err = lfs_dir_alloc(lfs, &tail); int err = lfs_dir_alloc(lfs, &tail);
if (err) { if (err) {
@@ -1654,6 +1647,7 @@ relocate:
if (err && (err != LFS_ERR_NOSPC && !exhausted)) { if (err && (err != LFS_ERR_NOSPC && !exhausted)) {
return err; return err;
} }
continue; continue;
} }
@@ -1946,7 +1940,7 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
LFS_TRACE("lfs_dir_open(%p, %p, \"%s\")", (void*)lfs, (void*)dir, path); LFS_TRACE("lfs_dir_open(%p, %p, \"%s\")", (void*)lfs, (void*)dir, path);
lfs_stag_t tag = lfs_dir_find(lfs, &dir->m, &path, NULL); lfs_stag_t tag = lfs_dir_find(lfs, &dir->m, &path, NULL);
if (tag < 0) { if (tag < 0) {
LFS_TRACE("lfs_dir_open -> %"PRId32, tag); LFS_TRACE("lfs_dir_open -> %d", tag);
return tag; return tag;
} }
@@ -1965,7 +1959,7 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
lfs_stag_t res = lfs_dir_get(lfs, &dir->m, LFS_MKTAG(0x700, 0x3ff, 0), lfs_stag_t res = lfs_dir_get(lfs, &dir->m, LFS_MKTAG(0x700, 0x3ff, 0),
LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair); LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair);
if (res < 0) { if (res < 0) {
LFS_TRACE("lfs_dir_open -> %"PRId32, res); LFS_TRACE("lfs_dir_open -> %d", res);
return res; return res;
} }
lfs_pair_fromle32(pair); lfs_pair_fromle32(pair);
@@ -2074,14 +2068,10 @@ int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) {
dir->pos = lfs_min(2, off); dir->pos = lfs_min(2, off);
off -= dir->pos; off -= dir->pos;
// skip superblock entry while (off != 0) {
dir->id = (off > 0 && lfs_pair_cmp(dir->head, lfs->root) == 0); dir->id = lfs_min(dir->m.count, off);
dir->pos += dir->id;
while (off > 0) { off -= dir->id;
int diff = lfs_min(dir->m.count - dir->id, off);
dir->id += diff;
dir->pos += diff;
off -= diff;
if (dir->id == dir->m.count) { if (dir->id == dir->m.count) {
if (!dir->m.split) { if (!dir->m.split) {
@@ -2094,8 +2084,6 @@ int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) {
LFS_TRACE("lfs_dir_seek -> %d", err); LFS_TRACE("lfs_dir_seek -> %d", err);
return err; return err;
} }
dir->id = 0;
} }
} }
@@ -2752,14 +2740,14 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
// flush out any writes // flush out any writes
int err = lfs_file_flush(lfs, file); int err = lfs_file_flush(lfs, file);
if (err) { if (err) {
LFS_TRACE("lfs_file_read -> %d", err); LFS_TRACE("lfs_file_read -> %"PRId32, err);
return err; return err;
} }
} }
if (file->pos >= file->ctz.size) { if (file->pos >= file->ctz.size) {
// eof if past end // eof if past end
LFS_TRACE("lfs_file_read -> %d", 0); LFS_TRACE("lfs_file_read -> %"PRId32, 0);
return 0; return 0;
} }
@@ -2775,7 +2763,7 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
file->ctz.head, file->ctz.size, file->ctz.head, file->ctz.size,
file->pos, &file->block, &file->off); file->pos, &file->block, &file->off);
if (err) { if (err) {
LFS_TRACE("lfs_file_read -> %d", err); LFS_TRACE("lfs_file_read -> %"PRId32, err);
return err; return err;
} }
} else { } else {
@@ -2795,7 +2783,7 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0), LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0),
file->off, data, diff); file->off, data, diff);
if (err) { if (err) {
LFS_TRACE("lfs_file_read -> %d", err); LFS_TRACE("lfs_file_read -> %"PRId32, err);
return err; return err;
} }
} else { } else {
@@ -2803,7 +2791,7 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
NULL, &file->cache, lfs->cfg->block_size, NULL, &file->cache, lfs->cfg->block_size,
file->block, file->off, data, diff); file->block, file->off, data, diff);
if (err) { if (err) {
LFS_TRACE("lfs_file_read -> %d", err); LFS_TRACE("lfs_file_read -> %"PRId32, err);
return err; return err;
} }
} }
@@ -2832,7 +2820,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
// drop any reads // drop any reads
int err = lfs_file_flush(lfs, file); int err = lfs_file_flush(lfs, file);
if (err) { if (err) {
LFS_TRACE("lfs_file_write -> %d", err); LFS_TRACE("lfs_file_write -> %"PRId32, err);
return err; return err;
} }
} }
@@ -2843,7 +2831,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
if (file->pos + size > lfs->file_max) { if (file->pos + size > lfs->file_max) {
// Larger than file limit? // Larger than file limit?
LFS_TRACE("lfs_file_write -> %d", LFS_ERR_FBIG); LFS_TRACE("lfs_file_write -> %"PRId32, LFS_ERR_FBIG);
return LFS_ERR_FBIG; return LFS_ERR_FBIG;
} }
@@ -2869,7 +2857,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
int err = lfs_file_outline(lfs, file); int err = lfs_file_outline(lfs, file);
if (err) { if (err) {
file->flags |= LFS_F_ERRED; file->flags |= LFS_F_ERRED;
LFS_TRACE("lfs_file_write -> %d", err); LFS_TRACE("lfs_file_write -> %"PRId32, err);
return err; return err;
} }
} }
@@ -2886,7 +2874,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
file->pos-1, &file->block, &file->off); file->pos-1, &file->block, &file->off);
if (err) { if (err) {
file->flags |= LFS_F_ERRED; file->flags |= LFS_F_ERRED;
LFS_TRACE("lfs_file_write -> %d", err); LFS_TRACE("lfs_file_write -> %"PRId32, err);
return err; return err;
} }
@@ -2901,7 +2889,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
&file->block, &file->off); &file->block, &file->off);
if (err) { if (err) {
file->flags |= LFS_F_ERRED; file->flags |= LFS_F_ERRED;
LFS_TRACE("lfs_file_write -> %d", err); LFS_TRACE("lfs_file_write -> %"PRId32, err);
return err; return err;
} }
} else { } else {
@@ -2922,7 +2910,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
goto relocate; goto relocate;
} }
file->flags |= LFS_F_ERRED; file->flags |= LFS_F_ERRED;
LFS_TRACE("lfs_file_write -> %d", err); LFS_TRACE("lfs_file_write -> %"PRId32, err);
return err; return err;
} }
@@ -2931,7 +2919,7 @@ relocate:
err = lfs_file_relocate(lfs, file); err = lfs_file_relocate(lfs, file);
if (err) { if (err) {
file->flags |= LFS_F_ERRED; file->flags |= LFS_F_ERRED;
LFS_TRACE("lfs_file_write -> %d", err); LFS_TRACE("lfs_file_write -> %"PRId32, err);
return err; return err;
} }
} }
@@ -2958,7 +2946,7 @@ lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
// write out everything beforehand, may be noop if rdonly // write out everything beforehand, may be noop if rdonly
int err = lfs_file_flush(lfs, file); int err = lfs_file_flush(lfs, file);
if (err) { if (err) {
LFS_TRACE("lfs_file_seek -> %d", err); LFS_TRACE("lfs_file_seek -> %"PRId32, err);
return err; return err;
} }
@@ -2974,7 +2962,7 @@ lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
if (npos > lfs->file_max) { if (npos > lfs->file_max) {
// file position out of range // file position out of range
LFS_TRACE("lfs_file_seek -> %d", LFS_ERR_INVAL); LFS_TRACE("lfs_file_seek -> %"PRId32, LFS_ERR_INVAL);
return LFS_ERR_INVAL; return LFS_ERR_INVAL;
} }
@@ -3022,7 +3010,7 @@ int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
if (file->pos != oldsize) { if (file->pos != oldsize) {
lfs_soff_t res = lfs_file_seek(lfs, file, 0, LFS_SEEK_END); lfs_soff_t res = lfs_file_seek(lfs, file, 0, LFS_SEEK_END);
if (res < 0) { if (res < 0) {
LFS_TRACE("lfs_file_truncate -> %"PRId32, res); LFS_TRACE("lfs_file_truncate -> %d", res);
return (int)res; return (int)res;
} }
} }
@@ -3031,7 +3019,7 @@ int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
while (file->pos < size) { while (file->pos < size) {
lfs_ssize_t res = lfs_file_write(lfs, file, &(uint8_t){0}, 1); lfs_ssize_t res = lfs_file_write(lfs, file, &(uint8_t){0}, 1);
if (res < 0) { if (res < 0) {
LFS_TRACE("lfs_file_truncate -> %"PRId32, res); LFS_TRACE("lfs_file_truncate -> %d", res);
return (int)res; return (int)res;
} }
} }
@@ -3040,7 +3028,7 @@ int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
// restore pos // restore pos
lfs_soff_t res = lfs_file_seek(lfs, file, pos, LFS_SEEK_SET); lfs_soff_t res = lfs_file_seek(lfs, file, pos, LFS_SEEK_SET);
if (res < 0) { if (res < 0) {
LFS_TRACE("lfs_file_truncate -> %"PRId32, res); LFS_TRACE("lfs_file_truncate -> %d", res);
return (int)res; return (int)res;
} }
@@ -3060,7 +3048,7 @@ int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file) {
LFS_TRACE("lfs_file_rewind(%p, %p)", (void*)lfs, (void*)file); LFS_TRACE("lfs_file_rewind(%p, %p)", (void*)lfs, (void*)file);
lfs_soff_t res = lfs_file_seek(lfs, file, 0, LFS_SEEK_SET); lfs_soff_t res = lfs_file_seek(lfs, file, 0, LFS_SEEK_SET);
if (res < 0) { if (res < 0) {
LFS_TRACE("lfs_file_rewind -> %"PRId32, res); LFS_TRACE("lfs_file_rewind -> %d", res);
return (int)res; return (int)res;
} }
@@ -3089,7 +3077,7 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
lfs_mdir_t cwd; lfs_mdir_t cwd;
lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL);
if (tag < 0) { if (tag < 0) {
LFS_TRACE("lfs_stat -> %"PRId32, tag); LFS_TRACE("lfs_stat -> %d", tag);
return (int)tag; return (int)tag;
} }
@@ -3110,7 +3098,7 @@ int lfs_remove(lfs_t *lfs, const char *path) {
lfs_mdir_t cwd; lfs_mdir_t cwd;
lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL);
if (tag < 0 || lfs_tag_id(tag) == 0x3ff) { if (tag < 0 || lfs_tag_id(tag) == 0x3ff) {
LFS_TRACE("lfs_remove -> %"PRId32, (tag < 0) ? tag : LFS_ERR_INVAL); LFS_TRACE("lfs_remove -> %d", (tag < 0) ? tag : LFS_ERR_INVAL);
return (tag < 0) ? (int)tag : LFS_ERR_INVAL; return (tag < 0) ? (int)tag : LFS_ERR_INVAL;
} }
@@ -3121,7 +3109,7 @@ int lfs_remove(lfs_t *lfs, const char *path) {
lfs_stag_t res = lfs_dir_get(lfs, &cwd, LFS_MKTAG(0x700, 0x3ff, 0), lfs_stag_t res = lfs_dir_get(lfs, &cwd, LFS_MKTAG(0x700, 0x3ff, 0),
LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair); LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair);
if (res < 0) { if (res < 0) {
LFS_TRACE("lfs_remove -> %"PRId32, res); LFS_TRACE("lfs_remove -> %d", res);
return (int)res; return (int)res;
} }
lfs_pair_fromle32(pair); lfs_pair_fromle32(pair);
@@ -3184,7 +3172,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
lfs_mdir_t oldcwd; lfs_mdir_t oldcwd;
lfs_stag_t oldtag = lfs_dir_find(lfs, &oldcwd, &oldpath, NULL); lfs_stag_t oldtag = lfs_dir_find(lfs, &oldcwd, &oldpath, NULL);
if (oldtag < 0 || lfs_tag_id(oldtag) == 0x3ff) { if (oldtag < 0 || lfs_tag_id(oldtag) == 0x3ff) {
LFS_TRACE("lfs_rename -> %"PRId32, (oldtag < 0) ? oldtag : LFS_ERR_INVAL); LFS_TRACE("lfs_rename -> %d", (oldtag < 0) ? oldtag : LFS_ERR_INVAL);
return (oldtag < 0) ? (int)oldtag : LFS_ERR_INVAL; return (oldtag < 0) ? (int)oldtag : LFS_ERR_INVAL;
} }
@@ -3194,7 +3182,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
lfs_stag_t prevtag = lfs_dir_find(lfs, &newcwd, &newpath, &newid); lfs_stag_t prevtag = lfs_dir_find(lfs, &newcwd, &newpath, &newid);
if ((prevtag < 0 || lfs_tag_id(prevtag) == 0x3ff) && if ((prevtag < 0 || lfs_tag_id(prevtag) == 0x3ff) &&
!(prevtag == LFS_ERR_NOENT && newid != 0x3ff)) { !(prevtag == LFS_ERR_NOENT && newid != 0x3ff)) {
LFS_TRACE("lfs_rename -> %"PRId32, (prevtag < 0) ? prevtag : LFS_ERR_INVAL); LFS_TRACE("lfs_rename -> %d", (prevtag < 0) ? prevtag : LFS_ERR_INVAL);
return (prevtag < 0) ? (int)prevtag : LFS_ERR_INVAL; return (prevtag < 0) ? (int)prevtag : LFS_ERR_INVAL;
} }
@@ -3215,7 +3203,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
lfs_stag_t res = lfs_dir_get(lfs, &newcwd, LFS_MKTAG(0x700, 0x3ff, 0), lfs_stag_t res = lfs_dir_get(lfs, &newcwd, LFS_MKTAG(0x700, 0x3ff, 0),
LFS_MKTAG(LFS_TYPE_STRUCT, newid, 8), prevpair); LFS_MKTAG(LFS_TYPE_STRUCT, newid, 8), prevpair);
if (res < 0) { if (res < 0) {
LFS_TRACE("lfs_rename -> %"PRId32, res); LFS_TRACE("lfs_rename -> %d", res);
return (int)res; return (int)res;
} }
lfs_pair_fromle32(prevpair); lfs_pair_fromle32(prevpair);
@@ -3310,7 +3298,7 @@ lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
id = 0; id = 0;
int err = lfs_dir_fetch(lfs, &cwd, lfs->root); int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
if (err) { if (err) {
LFS_TRACE("lfs_getattr -> %d", err); LFS_TRACE("lfs_getattr -> %"PRId32, err);
return err; return err;
} }
} }
@@ -3321,7 +3309,7 @@ lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
buffer); buffer);
if (tag < 0) { if (tag < 0) {
if (tag == LFS_ERR_NOENT) { if (tag == LFS_ERR_NOENT) {
LFS_TRACE("lfs_getattr -> %d", LFS_ERR_NOATTR); LFS_TRACE("lfs_getattr -> %"PRId32, LFS_ERR_NOATTR);
return LFS_ERR_NOATTR; return LFS_ERR_NOATTR;
} }
@@ -3777,7 +3765,7 @@ int lfs_fs_traverse(lfs_t *lfs,
if (tag == LFS_ERR_NOENT) { if (tag == LFS_ERR_NOENT) {
continue; continue;
} }
LFS_TRACE("lfs_fs_traverse -> %"PRId32, tag); LFS_TRACE("lfs_fs_traverse -> %d", tag);
return tag; return tag;
} }
lfs_ctz_fromle32(&ctz); lfs_ctz_fromle32(&ctz);
@@ -4092,11 +4080,11 @@ lfs_ssize_t lfs_fs_size(lfs_t *lfs) {
lfs_size_t size = 0; lfs_size_t size = 0;
int err = lfs_fs_traverse(lfs, lfs_fs_size_count, &size); int err = lfs_fs_traverse(lfs, lfs_fs_size_count, &size);
if (err) { if (err) {
LFS_TRACE("lfs_fs_size -> %d", err); LFS_TRACE("lfs_fs_size -> %"PRId32, err);
return err; return err;
} }
LFS_TRACE("lfs_fs_size -> %d", err); LFS_TRACE("lfs_fs_size -> %"PRId32, err);
return size; return size;
} }
@@ -4634,7 +4622,7 @@ int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg) {
id, entry1.d.nlen), name}, id, entry1.d.nlen), name},
{LFS_MKTAG( {LFS_MKTAG(
isdir ? LFS_TYPE_DIRSTRUCT : LFS_TYPE_CTZSTRUCT, isdir ? LFS_TYPE_DIRSTRUCT : LFS_TYPE_CTZSTRUCT,
id, sizeof(entry1.d.u)), &entry1.d.u})); id, sizeof(&entry1.d.u)), &entry1.d.u}));
lfs1_entry_fromle32(&entry1.d); lfs1_entry_fromle32(&entry1.d);
if (err) { if (err) {
goto cleanup; goto cleanup;
@@ -4657,7 +4645,7 @@ int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg) {
lfs_pair_tole32(dir2.pair); lfs_pair_tole32(dir2.pair);
err = lfs_dir_commit(lfs, &dir2, LFS_MKATTRS( err = lfs_dir_commit(lfs, &dir2, LFS_MKATTRS(
{LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 8), {LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 0),
dir1.d.tail})); dir1.d.tail}));
lfs_pair_fromle32(dir2.pair); lfs_pair_fromle32(dir2.pair);
if (err) { if (err) {

View File

@@ -250,14 +250,6 @@ scripts/test.py << TEST
lfs_unmount(&lfs) => 0; lfs_unmount(&lfs) => 0;
TEST TEST
## Below, these tests depend _very_ heavily on the geometry of the
## block device being tested, they should be removed and replaced
## by generalized tests. For now we'll just skip if the geometry
## is customized.
if [[ ! $MAKEFLAGS =~ "LFS_BLOCK_CYCLES" ]]
then
echo "--- Chained dir exhaustion test ---" echo "--- Chained dir exhaustion test ---"
scripts/test.py << TEST scripts/test.py << TEST
lfs_mount(&lfs, &cfg) => 0; lfs_mount(&lfs, &cfg) => 0;
@@ -489,6 +481,4 @@ scripts/test.py << TEST
lfs_unmount(&lfs) => 0; lfs_unmount(&lfs) => 0;
TEST TEST
fi
scripts/results.py scripts/results.py

View File

@@ -23,57 +23,6 @@ scripts/test.py << TEST
lfs_unmount(&lfs) => 0; lfs_unmount(&lfs) => 0;
TEST TEST
echo "--- Dangling split dir test ---"
scripts/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
for (int j = 0; j < $ITERATIONS; j++) {
for (int i = 0; i < $COUNT; i++) {
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
lfs_file_open(&lfs, &file, path, LFS_O_CREAT | LFS_O_WRONLY) => 0;
lfs_file_close(&lfs, &file) => 0;
}
lfs_dir_open(&lfs, &dir, "child") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
lfs_dir_read(&lfs, &dir, &info) => 1;
for (int i = 0; i < $COUNT; i++) {
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
lfs_dir_read(&lfs, &dir, &info) => 1;
strcmp(info.name, path) => 0;
}
lfs_dir_read(&lfs, &dir, &info) => 0;
lfs_dir_close(&lfs, &dir) => 0;
if (j == $ITERATIONS-1) {
break;
}
for (int i = 0; i < $COUNT; i++) {
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
lfs_remove(&lfs, path) => 0;
}
}
lfs_unmount(&lfs) => 0;
TEST
scripts/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir, "child") => 0;
lfs_dir_read(&lfs, &dir, &info) => 1;
lfs_dir_read(&lfs, &dir, &info) => 1;
for (int i = 0; i < $COUNT; i++) {
sprintf(path, "test%03d_loooooooooooooooooong_name", i);
lfs_dir_read(&lfs, &dir, &info) => 1;
strcmp(info.name, path) => 0;
}
lfs_dir_read(&lfs, &dir, &info) => 0;
lfs_dir_close(&lfs, &dir) => 0;
for (int i = 0; i < $COUNT; i++) {
sprintf(path, "child/test%03d_loooooooooooooooooong_name", i);
lfs_remove(&lfs, path) => 0;
}
lfs_unmount(&lfs) => 0;
TEST
echo "--- Outdated head test ---" echo "--- Outdated head test ---"
scripts/test.py << TEST scripts/test.py << TEST
lfs_mount(&lfs, &cfg) => 0; lfs_mount(&lfs, &cfg) => 0;

View File

@@ -428,78 +428,4 @@ scripts/test.py << TEST
TEST TEST
done done
echo "--- Root seek test ---"
./scripts/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
for (int i = 3; i < $MEDIUMSIZE; i++) {
sprintf(path, "hi%03d", i);
lfs_mkdir(&lfs, path) => 0;
}
lfs_dir_open(&lfs, &dir, "/") => 0;
for (int i = 0; i < $MEDIUMSIZE; i++) {
if (i == 0) {
sprintf(path, ".");
} else if (i == 1) {
sprintf(path, "..");
} else if (i == 2) {
sprintf(path, "hello");
} else {
sprintf(path, "hi%03d", i);
}
lfs_dir_read(&lfs, &dir, &info) => 1;
strcmp(path, info.name) => 0;
}
lfs_dir_read(&lfs, &dir, &info) => 0;
lfs_dir_close(&lfs, &dir) => 0;
for (int j = 0; j < $MEDIUMSIZE; j++) {
lfs_soff_t off = -1;
lfs_dir_open(&lfs, &dir, "/") => 0;
for (int i = 0; i < $MEDIUMSIZE; i++) {
if (i == 0) {
sprintf(path, ".");
} else if (i == 1) {
sprintf(path, "..");
} else if (i == 2) {
sprintf(path, "hello");
} else {
sprintf(path, "hi%03d", i);
}
if (i == j) {
off = lfs_dir_tell(&lfs, &dir);
off >= 0 => true;
}
lfs_dir_read(&lfs, &dir, &info) => 1;
strcmp(path, info.name) => 0;
}
lfs_dir_read(&lfs, &dir, &info) => 0;
lfs_dir_close(&lfs, &dir) => 0;
lfs_dir_open(&lfs, &dir, "/") => 0;
lfs_dir_seek(&lfs, &dir, off) => 0;
for (int i = j; i < $MEDIUMSIZE; i++) {
if (i == 0) {
sprintf(path, ".");
} else if (i == 1) {
sprintf(path, "..");
} else if (i == 2) {
sprintf(path, "hello");
} else {
sprintf(path, "hi%03d", i);
}
lfs_dir_read(&lfs, &dir, &info) => 1;
strcmp(path, info.name) => 0;
}
lfs_dir_read(&lfs, &dir, &info) => 0;
lfs_dir_close(&lfs, &dir) => 0;
}
lfs_unmount(&lfs) => 0;
TEST
scripts/results.py scripts/results.py