t: Switched back to mid-based traversal clobbering
Implementing gc_compact_thresh over bshrubs highlighted that it's really
not that difficult, and probably required, for traversal bshrubs to be
tracked correctly during mdir commits/compacts/splits/etc. And if we
track bshrubs across mdir commits, we might as well clobber traversals
at the mid level, allowing traversals to always reach btrees/bshrubs not
under active mutation.
One key thing to note: we should never be traversing a bshrub that is
not referenced elsewhere, either on-disk in an mdir or in-ram via an
opened file. So any compacted traversal bshrubs are not wasted prog
cycles.
This moves most of the clobbering logic back up into the high-level
functions (lfsr_remove/rename mainly), where we know which mids may be
clobbered.
This has a code cost, but it's really not all that much for more
thorough/correct filesystem traversals under mutation:
code stack
before: 35268 2680
after: 35368 (+0.3%) 2680 (+0.0%)
Unfortunately, lingering rbyd references in our btraversal structs are
still an issue, and some bshrub tests are failing... Though I do have
some ideas on how to fix this.
This commit is contained in:
@@ -5945,7 +5945,7 @@ static bool lfsr_omdir_ismidopen(lfs_t *lfs, lfsr_smid_t mid) {
|
|||||||
|
|
||||||
// needed in lfsr_omdir_clobber
|
// needed in lfsr_omdir_clobber
|
||||||
static void lfsr_traversal_clobber(lfs_t *lfs, lfsr_traversal_t *t,
|
static void lfsr_traversal_clobber(lfs_t *lfs, lfsr_traversal_t *t,
|
||||||
lfsr_smid_t mid);
|
lfsr_smid_t shift);
|
||||||
|
|
||||||
// traversal invalidation things
|
// traversal invalidation things
|
||||||
static void lfsr_omdir_clobber(lfs_t *lfs, lfsr_omdir_t *o, bool dirty) {
|
static void lfsr_omdir_clobber(lfs_t *lfs, lfsr_omdir_t *o, bool dirty) {
|
||||||
@@ -5958,7 +5958,7 @@ static void lfsr_omdir_clobber(lfs_t *lfs, lfsr_omdir_t *o, bool dirty) {
|
|||||||
|
|
||||||
// clobber any traversals referencing our mdir
|
// clobber any traversals referencing our mdir
|
||||||
if (t->mt.o == o) {
|
if (t->mt.o == o) {
|
||||||
lfsr_traversal_clobber(lfs, t, -1);
|
lfsr_traversal_clobber(lfs, t, +1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7839,30 +7839,23 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clobber any related traversals
|
// mark all traversals as dirty
|
||||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||||
if (o->type == LFS_TYPE_TRAVERSAL) {
|
if (o->type == LFS_TYPE_TRAVERSAL) {
|
||||||
// don't clobber the current mdir, we assume upper layers know
|
|
||||||
// what they're doing
|
|
||||||
if (&o->mdir == mdir) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// mark all traversals as dirty
|
|
||||||
((lfsr_traversal_t*)o)->mt.flags |= LFS_F_DIRTY;
|
((lfsr_traversal_t*)o)->mt.flags |= LFS_F_DIRTY;
|
||||||
|
}
|
||||||
// clobber any mdir related traversals
|
|
||||||
if (lfsr_mdir_cmp(&o->mdir, mdir) == 0) {
|
|
||||||
lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o,
|
|
||||||
lfsr_mid_bid(lfs, mdir->mid) + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if mroot/mtree changed, clobber any mroot/mtree traversals
|
// if mroot/mtree changed, clobber any mroot/mtree traversals
|
||||||
if ((lfsr_mdir_cmp(&mroot_, &lfs->mroot) != 0
|
if (lfsr_mdir_cmp(&mroot_, &lfs->mroot) != 0
|
||||||
|| lfsr_mtree_cmp(&mtree_, &lfs->mtree) != 0)
|
|| lfsr_mtree_cmp(&mtree_, &lfs->mtree) != 0) {
|
||||||
&& o->mdir.mid == -1) {
|
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||||
lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o,
|
if (o->type == LFS_TYPE_TRAVERSAL
|
||||||
0);
|
&& o->mdir.mid == -1
|
||||||
|
// don't clobber the current mdir, assume upper layers
|
||||||
|
// know what they're doing
|
||||||
|
&& &o->mdir != mdir) {
|
||||||
|
lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8419,8 +8412,9 @@ static int lfsr_mtree_traverse_(lfs_t *lfs,
|
|||||||
// not traversing all blocks? have we exceeded our mdir's weight?
|
// not traversing all blocks? have we exceeded our mdir's weight?
|
||||||
// return to mtree iteration
|
// return to mtree iteration
|
||||||
if (lfsr_t_ismtreeonly(mt->flags)
|
if (lfsr_t_ismtreeonly(mt->flags)
|
||||||
|| lfsr_mid_rid(lfs, mdir->mid)
|
// mid may be -1 here if we were clobbered
|
||||||
>= (lfsr_srid_t)mdir->rbyd.weight) {
|
|| (lfsr_rid_t)lfsr_mid_rid(lfs, mdir->mid)
|
||||||
|
>= mdir->rbyd.weight) {
|
||||||
mdir->mid = lfsr_mid_bid(lfs, mdir->mid) + 1;
|
mdir->mid = lfsr_mid_bid(lfs, mdir->mid) + 1;
|
||||||
mt->state = LFSR_MTRAVERSAL_MDIRS;
|
mt->state = LFSR_MTRAVERSAL_MDIRS;
|
||||||
continue;
|
continue;
|
||||||
@@ -9210,6 +9204,13 @@ int lfsr_remove(lfs_t *lfs, const char *path) {
|
|||||||
} else {
|
} else {
|
||||||
((lfsr_dir_t*)o)->pos -= 1;
|
((lfsr_dir_t*)o)->pos -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clobber entangled traversals
|
||||||
|
} else if (o->type == LFS_TYPE_TRAVERSAL) {
|
||||||
|
if (lfsr_f_iszombie(o->flags)) {
|
||||||
|
o->flags &= ~LFS_F_ZOMBIE;
|
||||||
|
lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9363,6 +9364,12 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
|
|||||||
((lfsr_dir_t*)o)->pos -= 1;
|
((lfsr_dir_t*)o)->pos -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clobber entangled traversals
|
||||||
|
} else if (o->type == LFS_TYPE_TRAVERSAL
|
||||||
|
&& ((exists && o->mdir.mid == new_mdir.mid)
|
||||||
|
|| o->mdir.mid == lfs->grm.mids[0])) {
|
||||||
|
lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o, +1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10961,7 +10968,7 @@ lfs_ssize_t lfsr_file_write(lfs_t *lfs, lfsr_file_t *file,
|
|||||||
|
|
||||||
// checkpoint the allocator
|
// checkpoint the allocator
|
||||||
lfs_alloc_ckpoint(lfs);
|
lfs_alloc_ckpoint(lfs);
|
||||||
// clobber any entangled traversals
|
// clobber entangled traversals
|
||||||
lfsr_omdir_clobber(lfs, &file->o, true);
|
lfsr_omdir_clobber(lfs, &file->o, true);
|
||||||
// mark as unsynced in case we fail
|
// mark as unsynced in case we fail
|
||||||
file->o.flags |= LFS_F_UNSYNC;
|
file->o.flags |= LFS_F_UNSYNC;
|
||||||
@@ -11121,7 +11128,7 @@ int lfsr_file_flush(lfs_t *lfs, lfsr_file_t *file) {
|
|||||||
|
|
||||||
// checkpoint the allocator
|
// checkpoint the allocator
|
||||||
lfs_alloc_ckpoint(lfs);
|
lfs_alloc_ckpoint(lfs);
|
||||||
// clobber any entangled traversals
|
// clobber entangled traversals
|
||||||
lfsr_omdir_clobber(lfs, &file->o, true);
|
lfsr_omdir_clobber(lfs, &file->o, true);
|
||||||
|
|
||||||
// flush our buffer if it contains any unwritten data
|
// flush our buffer if it contains any unwritten data
|
||||||
@@ -11296,6 +11303,11 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
|
|||||||
file->buffer.size);
|
file->buffer.size);
|
||||||
file_->buffer.size = file->buffer.size;
|
file_->buffer.size = file->buffer.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clobber entangled traversals
|
||||||
|
} else if (o->type == LFS_TYPE_TRAVERSAL
|
||||||
|
&& o->mdir.mid == file->o.mdir.mid) {
|
||||||
|
lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o, +1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11384,7 +11396,7 @@ int lfsr_file_truncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
|||||||
|
|
||||||
// checkpoint the allocator
|
// checkpoint the allocator
|
||||||
lfs_alloc_ckpoint(lfs);
|
lfs_alloc_ckpoint(lfs);
|
||||||
// clobber any entangled traversals
|
// clobber entangled traversals
|
||||||
lfsr_omdir_clobber(lfs, &file->o, true);
|
lfsr_omdir_clobber(lfs, &file->o, true);
|
||||||
// mark as unsynced in case we fail
|
// mark as unsynced in case we fail
|
||||||
file->o.flags |= LFS_F_UNSYNC;
|
file->o.flags |= LFS_F_UNSYNC;
|
||||||
@@ -11490,7 +11502,7 @@ int lfsr_file_fruncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
|||||||
|
|
||||||
// checkpoint the allocator
|
// checkpoint the allocator
|
||||||
lfs_alloc_ckpoint(lfs);
|
lfs_alloc_ckpoint(lfs);
|
||||||
// clobber any entangled traversals
|
// clobber entangled traversals
|
||||||
lfsr_omdir_clobber(lfs, &file->o, true);
|
lfsr_omdir_clobber(lfs, &file->o, true);
|
||||||
// mark as unsynced in case we fail
|
// mark as unsynced in case we fail
|
||||||
file->o.flags |= LFS_F_UNSYNC;
|
file->o.flags |= LFS_F_UNSYNC;
|
||||||
@@ -12881,23 +12893,13 @@ done:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void lfsr_traversal_clobber(lfs_t *lfs, lfsr_traversal_t *t,
|
static void lfsr_traversal_clobber(lfs_t *lfs, lfsr_traversal_t *t,
|
||||||
lfsr_smid_t mid) {
|
lfsr_smid_t shift) {
|
||||||
(void)lfs;
|
(void)lfs;
|
||||||
// clobber low-level traversal
|
|
||||||
if (mid != -1) {
|
|
||||||
// increment the mid (to make progress) and reset to mdir iteration
|
// increment the mid (to make progress) and reset to mdir iteration
|
||||||
t->mt.state = LFSR_MTRAVERSAL_MDIRS;
|
t->mt.state = LFSR_MTRAVERSAL_MDIR;
|
||||||
t->o.mdir.mid = mid;
|
t->o.mdir.mid += shift;
|
||||||
t->o.mdir.rbyd.blocks[0] = -1;
|
|
||||||
t->o.mdir.rbyd.blocks[1] = -1;
|
|
||||||
t->mt.o = NULL;
|
t->mt.o = NULL;
|
||||||
} else {
|
t->mt.bshrub.u.bshrub.blocks[0] = -1;
|
||||||
// move to next omdir
|
|
||||||
LFS_ASSERT(t->mt.state == LFSR_MTRAVERSAL_OMDIRS
|
|
||||||
|| t->mt.state == LFSR_MTRAVERSAL_OBTREE);
|
|
||||||
t->mt.state = LFSR_MTRAVERSAL_OMDIRS;
|
|
||||||
t->mt.o = t->mt.o->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// and clear any pending blocks
|
// and clear any pending blocks
|
||||||
t->blocks[0] = -1;
|
t->blocks[0] = -1;
|
||||||
|
|||||||
+183
-27
@@ -1696,10 +1696,6 @@ code = '''
|
|||||||
lfsr_file_open(&lfs, &file, "spider",
|
lfsr_file_open(&lfs, &file, "spider",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
@@ -1716,7 +1712,6 @@ code = '''
|
|||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
|
|
||||||
done:;
|
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfsr_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@@ -1815,6 +1810,9 @@ code = '''
|
|||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
|
assert(tinfo.block == 0 || tinfo.block == 1);
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
|
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
@@ -1938,10 +1936,6 @@ code = '''
|
|||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lfs_tinfo tinfo;
|
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
@@ -2016,10 +2010,6 @@ code = '''
|
|||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lfs_tinfo tinfo;
|
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
@@ -2094,10 +2084,6 @@ code = '''
|
|||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lfs_tinfo tinfo;
|
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
@@ -2428,6 +2414,14 @@ code = '''
|
|||||||
lfsr_file_write(&lfs, &file, wbuf1, SIZE) => SIZE;
|
lfsr_file_write(&lfs, &file, wbuf1, SIZE) => SIZE;
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
|
// traverse btree
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_BTREE);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -2509,6 +2503,11 @@ code = '''
|
|||||||
lfsr_file_write(&lfs, &file, wbuf1, SIZE) => SIZE;
|
lfsr_file_write(&lfs, &file, wbuf1, SIZE) => SIZE;
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -2754,6 +2753,11 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfsr_file_write(&lfs, &file1, wbuf1, SIZE) => SIZE;
|
lfsr_file_write(&lfs, &file1, wbuf1, SIZE) => SIZE;
|
||||||
|
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -2919,7 +2923,6 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfsr_file_close(&lfs, &file1) => 0;
|
lfsr_file_close(&lfs, &file1) => 0;
|
||||||
|
|
||||||
if (DESYNC) {
|
|
||||||
// traverse btree
|
// traverse btree
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS_BTYPE_BTREE);
|
assert(tinfo.btype == LFS_BTYPE_BTREE);
|
||||||
@@ -2928,7 +2931,6 @@ code = '''
|
|||||||
assert(tinfo.btype == LFS_BTYPE_DATA);
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS_BTYPE_DATA);
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
}
|
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -3013,13 +3015,11 @@ code = '''
|
|||||||
}
|
}
|
||||||
lfsr_file_close(&lfs, &file1) => 0;
|
lfsr_file_close(&lfs, &file1) => 0;
|
||||||
|
|
||||||
if (DESYNC) {
|
|
||||||
// traverse two data blocks
|
// traverse two data blocks
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS_BTYPE_DATA);
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS_BTYPE_DATA);
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
}
|
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -3101,6 +3101,11 @@ code = '''
|
|||||||
// remove the file
|
// remove the file
|
||||||
lfsr_remove(&lfs, "spider") => 0;
|
lfsr_remove(&lfs, "spider") => 0;
|
||||||
|
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -3129,7 +3134,7 @@ code = '''
|
|||||||
|
|
||||||
uint32_t prng = 42;
|
uint32_t prng = 42;
|
||||||
|
|
||||||
// create two files
|
// create three files
|
||||||
lfsr_file_t file;
|
lfsr_file_t file;
|
||||||
lfsr_file_open(&lfs, &file, "spider",
|
lfsr_file_open(&lfs, &file, "spider",
|
||||||
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
@@ -3149,6 +3154,15 @@ code = '''
|
|||||||
lfsr_file_write(&lfs, &file, wbuf2, SIZE) => SIZE;
|
lfsr_file_write(&lfs, &file, wbuf2, SIZE) => SIZE;
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
|
lfsr_file_open(&lfs, &file, "wolfspider",
|
||||||
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
|
uint8_t wbuf3[SIZE];
|
||||||
|
for (lfs_size_t j = 0; j < SIZE; j++) {
|
||||||
|
wbuf3[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||||
|
}
|
||||||
|
lfsr_file_write(&lfs, &file, wbuf3, SIZE) => SIZE;
|
||||||
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
// try traversing
|
// try traversing
|
||||||
lfsr_traversal_t t;
|
lfsr_traversal_t t;
|
||||||
lfsr_traversal_open(&lfs, &t,
|
lfsr_traversal_open(&lfs, &t,
|
||||||
@@ -3171,6 +3185,16 @@ code = '''
|
|||||||
// rename one file over another
|
// rename one file over another
|
||||||
lfsr_rename(&lfs, "spider", "tarantula") => 0;
|
lfsr_rename(&lfs, "spider", "tarantula") => 0;
|
||||||
|
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -3184,6 +3208,11 @@ code = '''
|
|||||||
assert(memcmp(rbuf, wbuf1, SIZE) == 0);
|
assert(memcmp(rbuf, wbuf1, SIZE) == 0);
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
|
lfsr_file_open(&lfs, &file, "wolfspider", LFS_O_RDONLY) => 0;
|
||||||
|
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||||
|
assert(memcmp(rbuf, wbuf3, SIZE) == 0);
|
||||||
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfsr_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@@ -3219,6 +3248,15 @@ code = '''
|
|||||||
lfsr_file_write(&lfs, &file, wbuf2, SIZE) => SIZE;
|
lfsr_file_write(&lfs, &file, wbuf2, SIZE) => SIZE;
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
|
lfsr_file_open(&lfs, &file, "wolfspider",
|
||||||
|
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0;
|
||||||
|
uint8_t wbuf3[SIZE];
|
||||||
|
for (lfs_size_t j = 0; j < SIZE; j++) {
|
||||||
|
wbuf3[j] = 'a' + (TEST_PRNG(&prng) % 26);
|
||||||
|
}
|
||||||
|
lfsr_file_write(&lfs, &file, wbuf3, SIZE) => SIZE;
|
||||||
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
// try traversing
|
// try traversing
|
||||||
lfsr_traversal_t t;
|
lfsr_traversal_t t;
|
||||||
lfsr_traversal_open(&lfs, &t,
|
lfsr_traversal_open(&lfs, &t,
|
||||||
@@ -3241,6 +3279,11 @@ code = '''
|
|||||||
// rename one file over another
|
// rename one file over another
|
||||||
lfsr_rename(&lfs, "tarantula", "spider") => 0;
|
lfsr_rename(&lfs, "tarantula", "spider") => 0;
|
||||||
|
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -3254,6 +3297,11 @@ code = '''
|
|||||||
|
|
||||||
lfsr_file_open(&lfs, &file, "tarantula", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
lfsr_file_open(&lfs, &file, "tarantula", LFS_O_RDONLY) => LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
lfsr_file_open(&lfs, &file, "wolfspider", LFS_O_RDONLY) => 0;
|
||||||
|
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||||
|
assert(memcmp(rbuf, wbuf3, SIZE) == 0);
|
||||||
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfsr_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@@ -3313,6 +3361,26 @@ code = '''
|
|||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// traverse mdir
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse mdir
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -3403,6 +3471,24 @@ code = '''
|
|||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// traverse another data block
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse mdir
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -3503,6 +3589,14 @@ code = '''
|
|||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// traverse another data block
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -3583,6 +3677,21 @@ code = '''
|
|||||||
lfsr_remove(&lfs, "uloborus") => 0;
|
lfsr_remove(&lfs, "uloborus") => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// traverse mroot
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -3664,6 +3773,14 @@ code = '''
|
|||||||
lfsr_remove(&lfs, "uloborus") => 0;
|
lfsr_remove(&lfs, "uloborus") => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// traverse another data block
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -3863,6 +3980,14 @@ code = '''
|
|||||||
lfsr_remove(&lfs, "uloborus") => 0;
|
lfsr_remove(&lfs, "uloborus") => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// traverse another data block
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
// we should be at end of traversal now
|
// we should be at end of traversal now
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
|
||||||
lfsr_traversal_close(&lfs, &t) => 0;
|
lfsr_traversal_close(&lfs, &t) => 0;
|
||||||
@@ -4169,7 +4294,20 @@ code = '''
|
|||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// traverse untouched mdir
|
// traverse another data block
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse mdir
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse mdir
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
@@ -4333,8 +4471,10 @@ code = '''
|
|||||||
lfsr_file_close(&lfs, &file) => 0;
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
// traverse another data block
|
||||||
// traverse untouched mdir
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse mdir
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
@@ -4661,7 +4801,15 @@ code = '''
|
|||||||
lfsr_remove(&lfs, "vulsor") => 0;
|
lfsr_remove(&lfs, "vulsor") => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// traverse untouched mdir
|
// traverse another data block
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse mdir
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
@@ -5004,7 +5152,15 @@ code = '''
|
|||||||
lfsr_remove(&lfs, "vulsor") => 0;
|
lfsr_remove(&lfs, "vulsor") => 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// traverse untouched mdir
|
// traverse another data block
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse two data blocks
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS_BTYPE_DATA);
|
||||||
|
// traverse mdir
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
assert(tinfo.btype == LFS_BTYPE_MDIR);
|
||||||
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
lfsr_traversal_read(&lfs, &t, &tinfo) => 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user