From 23c82bd7e5168b92adb3f71d83bd99582c60c617 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sat, 6 Jul 2024 00:01:38 -0500 Subject: [PATCH] t: Replaced LFS_T_EXCL with LFS_I_DIRTY flag in lfsr_tinfo This just forwards the internal LFS_I_DIRTY flag to the user via the lfsr_tinfo flags field. Benefits of this approach: - Gives the user more flexibility on what to do if the filesystem is modified, maybe you want to keep traversing depending on some other logic. - Can eventually add other flags to tinfo.flags, such as LFS_I_COMPACTED, LFS_I_REPAIRED, LFS_I_INCONSISTENT, etc. - Avoids confusion around the very different behaviors of LFS_O_EXCL and LFS_T_EXCL. I tried to come up with a better name (maybe LFS_T_WATCH?) but it was a bit of a struggle... Switching to a flags approach sidesteps the issue. - Can drop the LFS_ERR_BUSY error code for now. Code changes were fairly insignificant: code stack before: 35244 2680 after: 35224 (-0.1%) 2680 (+0.0%) The only concern is that the tests highlighted it's possible for our flag scheme to miss mutation if it happens after/during the last set of blocks... Not sure how to handle this yet... --- lfs.c | 35 +- lfs.h | 13 +- scripts/dbgerr.py | 1 - tests/test_traversal.toml | 691 +++++++++++++++++++++----------------- 4 files changed, 393 insertions(+), 347 deletions(-) diff --git a/lfs.c b/lfs.c index d99a5948..16e74ec0 100644 --- a/lfs.c +++ b/lfs.c @@ -5968,7 +5968,7 @@ static bool lfsr_omdir_ismidopen(lfs_t *lfs, lfsr_smid_t mid) { static void lfsr_fs_mkdirty(lfs_t *lfs) { for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) { if (o->type == LFS_TYPE_TRAVERSAL) { - o->flags |= LFS_F_DIRTY; + o->flags |= LFS_I_DIRTY; } } } @@ -8241,10 +8241,6 @@ static inline bool lfsr_t_ismtreeonly(uint32_t flags) { return flags & LFS_T_MTREEONLY; } -static inline bool lfsr_t_isexcl(uint32_t flags) { - return flags & LFS_T_EXCL; -} - static inline bool lfsr_t_ismkconsistent(uint32_t flags) { return flags & LFS_T_MKCONSISTENT; } @@ -8265,8 +8261,8 @@ static inline bool lfsr_t_isckdata(uint32_t flags) { return flags & (LFS_T_CKDATA ^ LFS_T_CKMETA); } -static inline bool lfsr_f_isdirty(uint32_t flags) { - return flags & LFS_F_DIRTY; +static inline bool lfsr_i_isdirty(uint32_t flags) { + return flags & LFS_I_DIRTY; } @@ -8683,7 +8679,7 @@ static int lfsr_mtree_gc(lfs_t *lfs, lfsr_traversal_t *t, } // mark as dirty - t->o.o.flags |= LFS_F_DIRTY; + t->o.o.flags |= LFS_I_DIRTY; } // compacting btree nodes? @@ -8761,7 +8757,7 @@ static int lfsr_mtree_gc(lfs_t *lfs, lfsr_traversal_t *t, t->u.bt.rid = t->u.bt.bid; // mark as dirty - t->o.o.flags |= LFS_F_DIRTY; + t->o.o.flags |= LFS_I_DIRTY; } if (tag_) { @@ -8914,7 +8910,6 @@ static lfs_sblock_t lfs_alloc(lfs_t *lfs, bool erase) { int err = lfsr_mtree_traverse(lfs, &t, NULL, NULL); if (err) { - LFS_ASSERT(err != LFS_ERR_BUSY); if (err == LFS_ERR_NOENT) { break; } @@ -12832,7 +12827,7 @@ int lfsr_traversal_open(lfs_t *lfs, lfsr_traversal_t *t, uint32_t flags) { LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags)); LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags)); // these flags are internal and shouldn't be provided by the user - LFS_ASSERT(!lfsr_f_isdirty(flags)); + LFS_ASSERT(!lfsr_i_isdirty(flags)); // some flags mutate the filesystem if (lfsr_t_ismkconsistent(flags) @@ -12871,16 +12866,11 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t, struct lfs_tinfo *tinfo) { LFS_ASSERT(lfsr_omdir_isopen(lfs, &t->o.o)); - // traversal dirty and excl? terminate early - if (lfsr_t_isexcl(t->o.o.flags) - && lfsr_f_isdirty(t->o.o.flags)) { - return LFS_ERR_BUSY; - } - while (true) { // some redund blocks left over? if (t->blocks[0] != -1) { // write our traversal info + tinfo->flags = t->o.o.flags & LFS_I_DIRTY; tinfo->btype = lfsr_t_btype(t->o.o.flags); tinfo->block = t->blocks[0]; @@ -12902,13 +12892,6 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t, return err; } - // traversal may itself set the dirty flag if it required - // mutation to make progress - if (lfsr_t_isexcl(t->o.o.flags) - && lfsr_f_isdirty(t->o.o.flags)) { - return LFS_ERR_BUSY; - } - // figure out type/blocks if (tag == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer; @@ -12935,7 +12918,7 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t, done:; // was a lookahead scan successful? if (lfsr_t_islookahead(t->o.o.flags) - && !lfsr_f_isdirty(t->o.o.flags)) { + && !lfsr_i_isdirty(t->o.o.flags)) { lfs_alloc_markfree(lfs); } @@ -12978,7 +12961,7 @@ static void lfsr_traversal_clobber(lfs_t *lfs, lfsr_traversal_t *t) { static int lfsr_traversal_rewind_(lfs_t *lfs, lfsr_traversal_t *t) { (void)lfs; // reset traversal - t->o.o.flags &= ~LFS_F_DIRTY; + t->o.o.flags &= ~LFS_I_DIRTY; t->o.o.state = LFSR_TSTATE_MROOTANCHOR; t->o.o.mdir.mid = -1; t->o.o.mdir.rbyd.weight = 0; diff --git a/lfs.h b/lfs.h index 3c1bff24..555bd5e5 100644 --- a/lfs.h +++ b/lfs.h @@ -98,7 +98,6 @@ enum lfs_error { LFS_ERR_UNKNOWN = -1, // Unknown error LFS_ERR_INVAL = -22, // Invalid parameter LFS_ERR_NOTSUP = -95, // Operation not supported - LFS_ERR_BUSY = -16, // Device or resource busy LFS_ERR_IO = -5, // Error during device operation LFS_ERR_CORRUPT = -84, // Corrupted LFS_ERR_NOENT = -2, // No directory entry @@ -169,8 +168,7 @@ enum lfs_btype { // Traversal flags enum lfs_traversal_flags { // traversal open flags - LFS_T_MTREEONLY = 0x0008, // Only traverse the mtree - LFS_T_EXCL = 0x0010, // Terminate if filesystem modified + LFS_T_MTREEONLY = 0x0010, // Only traverse the mtree LFS_T_MKCONSISTENT = 0x0020, // Make the filesystem consistent LFS_T_LOOKAHEAD = 0x0040, // Populate lookahead buffer LFS_T_COMPACT = 0x0080, // Compact metadata logs @@ -179,9 +177,11 @@ enum lfs_traversal_flags { // TODO // LFS_T_REPAIRMETA = 0x0400, // Repair metadata blocks // LFS_T_REPAIRDATA = 0x0c00, // Repair metadata + data blocks +}; - // internally used flags - LFS_F_DIRTY = 0x1000, // Filesystem has been modified +enum lfs_tinfo_flags { + // traversal info flags + LFS_I_DIRTY = 0x1000, // Filesystem has been modified }; @@ -385,6 +385,9 @@ struct lfs_fsinfo { // Traversal info structure struct lfs_tinfo { + // Traversal flags + uint16_t flags; + // Type of the block uint8_t btype; diff --git a/scripts/dbgerr.py b/scripts/dbgerr.py index 3287c7f5..216222cb 100755 --- a/scripts/dbgerr.py +++ b/scripts/dbgerr.py @@ -6,7 +6,6 @@ ERRS = [ ('UNKNOWN', -1, "Unknown error" ), ('INVAL', -22, "Invalid parameter" ), ('NOTSUP', -95, "Operation not supported" ), - ('BUSY', -16, "Device or resource busy" ), ('IO', -5, "Error during device operation" ), ('CORRUPT', -84, "Corrupted" ), ('NOENT', -2, "No directory entry" ), diff --git a/tests/test_traversal.toml b/tests/test_traversal.toml index 1c31a40c..08bb9a8b 100644 --- a/tests/test_traversal.toml +++ b/tests/test_traversal.toml @@ -27,9 +27,11 @@ code = ''' | ((COMPACT) ? LFS_T_COMPACT : 0)) => 0; struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -58,18 +60,22 @@ code = ''' | ((COMPACT) ? LFS_T_COMPACT : 0)) => 0; struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 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_rewind(&lfs, &t) => 0; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -98,9 +104,11 @@ code = ''' | ((COMPACT) ? LFS_T_COMPACT : 0)) => 0; struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -158,6 +166,7 @@ code = ''' printf("traversal: btype %d block 0x%x\n", tinfo.btype, tinfo.block); + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR || tinfo.btype == LFS_BTYPE_BTREE); // keep track of seen blocks @@ -279,6 +288,7 @@ code = ''' printf("traversal: btype %d block 0x%x\n", tinfo.btype, tinfo.block); + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR || tinfo.btype == LFS_BTYPE_BTREE || tinfo.btype == LFS_BTYPE_DATA); @@ -393,6 +403,7 @@ code = ''' printf("traversal: btype %d block 0x%x\n", tinfo.btype, tinfo.block); + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR || tinfo.btype == LFS_BTYPE_BTREE || tinfo.btype == LFS_BTYPE_DATA); @@ -518,6 +529,7 @@ code = ''' printf("traversal: btype %d block 0x%x\n", tinfo.btype, tinfo.block); + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR || tinfo.btype == LFS_BTYPE_BTREE); // keep track of seen blocks @@ -648,6 +660,7 @@ code = ''' printf("traversal: btype %d block 0x%x\n", tinfo.btype, tinfo.block); + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR || tinfo.btype == LFS_BTYPE_BTREE || tinfo.btype == LFS_BTYPE_DATA); @@ -771,6 +784,7 @@ code = ''' printf("traversal: btype %d block 0x%x\n", tinfo.btype, tinfo.block); + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR || tinfo.btype == LFS_BTYPE_BTREE || tinfo.btype == LFS_BTYPE_DATA); @@ -883,6 +897,7 @@ code = ''' goto done; } + assert(tinfo.flags == 0); if (tinfo.btype == LFS_BTYPE_MDIR) { if (k == i || k == i+1) { // clobber this block @@ -979,6 +994,7 @@ code = ''' goto done; } + assert(tinfo.flags == 0); if (tinfo.btype == LFS_BTYPE_MDIR) { if (k == i || k == i+1) { // clobber this block @@ -1010,6 +1026,8 @@ code = ''' if (err == LFS_ERR_CORRUPT) { break; } + + assert(tinfo.flags == 0); } lfsr_traversal_close(&lfs, &t) => 0; @@ -1077,6 +1095,7 @@ code = ''' goto done; } + assert(tinfo.flags == 0); if (tinfo.btype == LFS_BTYPE_MDIR) { if (k == i || k == i+1) { // clobber this block @@ -1108,6 +1127,8 @@ code = ''' if (err == LFS_ERR_CORRUPT) { break; } + + assert(tinfo.flags == 0); } lfsr_traversal_close(&lfs, &t) => 0; @@ -1157,6 +1178,7 @@ code = ''' goto done; } + assert(tinfo.flags == 0); if (tinfo.btype == LFS_BTYPE_BTREE) { if (k == i) { // clobber this block @@ -1186,6 +1208,8 @@ code = ''' if (err == LFS_ERR_CORRUPT) { break; } + + assert(tinfo.flags == 0); } lfsr_traversal_close(&lfs, &t) => 0; @@ -1251,6 +1275,7 @@ code = ''' goto done; } + assert(tinfo.flags == 0); if (tinfo.btype == LFS_BTYPE_BTREE) { if (k == i) { // clobber this block @@ -1280,6 +1305,8 @@ code = ''' if (err == LFS_ERR_CORRUPT) { break; } + + assert(tinfo.flags == 0); } lfsr_traversal_close(&lfs, &t) => 0; @@ -1347,6 +1374,7 @@ code = ''' goto done; } + assert(tinfo.flags == 0); if (tinfo.btype == LFS_BTYPE_BTREE) { if (k == i) { // clobber this block @@ -1376,6 +1404,8 @@ code = ''' if (err == LFS_ERR_CORRUPT) { break; } + + assert(tinfo.flags == 0); } lfsr_traversal_close(&lfs, &t) => 0; @@ -1425,6 +1455,7 @@ code = ''' goto done; } + assert(tinfo.flags == 0); if (tinfo.btype == LFS_BTYPE_DATA) { if (k == i) { // clobber this block @@ -1455,6 +1486,8 @@ code = ''' if (err == LFS_ERR_CORRUPT) { break; } + + assert(tinfo.flags == 0); } lfsr_traversal_close(&lfs, &t) => 0; @@ -1520,6 +1553,7 @@ code = ''' goto done; } + assert(tinfo.flags == 0); if (tinfo.btype == LFS_BTYPE_DATA) { if (k == i) { // clobber this block @@ -1550,6 +1584,8 @@ code = ''' if (err == LFS_ERR_CORRUPT) { break; } + + assert(tinfo.flags == 0); } lfsr_traversal_close(&lfs, &t) => 0; @@ -1617,6 +1653,7 @@ code = ''' goto done; } + assert(tinfo.flags == 0); if (tinfo.btype == LFS_BTYPE_DATA) { if (k == i) { // clobber this block @@ -1647,6 +1684,8 @@ code = ''' if (err == LFS_ERR_CORRUPT) { break; } + + assert(tinfo.flags == 0); } lfsr_traversal_close(&lfs, &t) => 0; @@ -1688,6 +1727,7 @@ code = ''' struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((WHEN <= 0) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); @@ -1699,6 +1739,7 @@ code = ''' } lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((WHEN <= 1) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); @@ -1715,74 +1756,6 @@ code = ''' lfsr_unmount(&lfs) => 0; ''' -[cases.test_traversal_mutation_excl] -defines.WHEN = [0, 1, 2] -defines.CKMETA = [false, true] -defines.CKDATA = [false, true] -defines.LOOKAHEAD = [false, true] -code = ''' - lfs_t lfs; - lfsr_format(&lfs, CFG) => 0; - lfsr_mount(&lfs, CFG) => 0; - - // try traversing - lfsr_traversal_t t; - lfsr_traversal_open(&lfs, &t, - LFS_T_EXCL - | ((CKMETA) ? LFS_T_CKMETA : 0) - | ((CKDATA) ? LFS_T_CKDATA : 0) - | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0)) => 0; - - if (WHEN == 0) { - lfsr_file_t file; - lfsr_file_open(&lfs, &file, "spider", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; - lfsr_file_close(&lfs, &file) => 0; - - // read should immediately error - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_close(&lfs, &t) => 0; - goto done; - } - - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => 0; - assert(tinfo.btype == LFS_BTYPE_MDIR); - assert(tinfo.block == 0 || tinfo.block == 1); - - if (WHEN == 1) { - lfsr_file_t file; - lfsr_file_open(&lfs, &file, "spider", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; - lfsr_file_close(&lfs, &file) => 0; - - // read should immediately error - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_close(&lfs, &t) => 0; - goto done; - } - - lfsr_traversal_read(&lfs, &t, &tinfo) => 0; - assert(tinfo.btype == LFS_BTYPE_MDIR); - assert(tinfo.block == 0 || tinfo.block == 1); - - if (WHEN == 2) { - lfsr_file_t file; - lfsr_file_open(&lfs, &file, "spider", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; - lfsr_file_close(&lfs, &file) => 0; - - // read should immediately error - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_close(&lfs, &t) => 0; - goto done; - } - -done:; - lfsr_unmount(&lfs) => 0; -''' - # test that we don't get extra anything after end of traversal [cases.test_traversal_mutation_idempotent] defines.CKMETA = [false, true] @@ -1811,6 +1784,7 @@ code = ''' lfsr_file_close(&lfs, &file) => 0; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -1839,62 +1813,8 @@ code = ''' lfsr_unmount(&lfs) => 0; ''' -[cases.test_traversal_mutation_excl_idempotent] -defines.CKMETA = [false, true] -defines.CKDATA = [false, true] -defines.LOOKAHEAD = [false, true] -code = ''' - lfs_t lfs; - lfsr_format(&lfs, CFG) => 0; - lfsr_mount(&lfs, CFG) => 0; - - // try traversing - lfsr_traversal_t t; - lfsr_traversal_open(&lfs, &t, - LFS_T_EXCL - | ((CKMETA) ? LFS_T_CKMETA : 0) - | ((CKDATA) ? LFS_T_CKDATA : 0) - | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0)) => 0; - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => 0; - assert(tinfo.btype == LFS_BTYPE_MDIR); - assert(tinfo.block == 0 || tinfo.block == 1); - - // mutate - lfsr_file_t file; - lfsr_file_open(&lfs, &file, "spider", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; - lfsr_file_close(&lfs, &file) => 0; - - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - - // try another mutation just for good measure - lfsr_file_open(&lfs, &file, "tarantula", - LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; - lfsr_file_close(&lfs, &file) => 0; - - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - - lfsr_traversal_close(&lfs, &t) => 0; - - lfsr_unmount(&lfs) => 0; -''' - [cases.test_traversal_mutation_mkdir] defines.WHEN = [0, 1, 2] -defines.EXCL = [false, true] defines.CKMETA = [false, true] defines.CKDATA = [false, true] defines.LOOKAHEAD = [false, true] @@ -1906,55 +1826,34 @@ code = ''' // try traversing lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0)) => 0; if (WHEN == 0) { lfsr_mkdir(&lfs, "spider") => 0; - - if (EXCL) { - // read should immediately error - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - goto done; - } } struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((WHEN <= 0) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); if (WHEN == 1) { lfsr_mkdir(&lfs, "spider") => 0; - - if (EXCL) { - // read should immediately error - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - goto done; - } } lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((WHEN <= 1) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); if (WHEN == 2) { lfsr_mkdir(&lfs, "spider") => 0; - - if (EXCL) { - // read should immediately error - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - goto done; - } } lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; -done:; lfsr_traversal_close(&lfs, &t) => 0; lfsr_unmount(&lfs) => 0; @@ -1962,7 +1861,6 @@ done:; [cases.test_traversal_mutation_rm] defines.WHEN = [0, 1, 2] -defines.EXCL = [false, true] defines.CKMETA = [false, true] defines.CKDATA = [false, true] defines.LOOKAHEAD = [false, true] @@ -1980,55 +1878,34 @@ code = ''' // try traversing lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0)) => 0; if (WHEN == 0) { lfsr_remove(&lfs, "spider") => 0; - - if (EXCL) { - // read should immediately error - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - goto done; - } } struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((WHEN <= 0) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); if (WHEN == 1) { lfsr_remove(&lfs, "spider") => 0; - - if (EXCL) { - // read should immediately error - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - goto done; - } } lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((WHEN <= 1) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); if (WHEN == 2) { lfsr_remove(&lfs, "spider") => 0; - - if (EXCL) { - // read should immediately error - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - goto done; - } } lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; -done:; lfsr_traversal_close(&lfs, &t) => 0; lfsr_unmount(&lfs) => 0; @@ -2036,7 +1913,6 @@ done:; [cases.test_traversal_mutation_mv] defines.WHEN = [0, 1, 2] -defines.EXCL = [false, true] defines.CKMETA = [false, true] defines.CKDATA = [false, true] defines.LOOKAHEAD = [false, true] @@ -2054,55 +1930,34 @@ code = ''' // try traversing lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0)) => 0; if (WHEN == 0) { lfsr_rename(&lfs, "spider", "scorpion") => 0; - - if (EXCL) { - // read should immediately error - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - goto done; - } } struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((WHEN <= 0) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); if (WHEN == 1) { lfsr_rename(&lfs, "spider", "scorpion") => 0; - - if (EXCL) { - // read should immediately error - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - goto done; - } } lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((WHEN <= 1) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); if (WHEN == 2) { lfsr_rename(&lfs, "spider", "scorpion") => 0; - - if (EXCL) { - // read should immediately error - struct lfs_tinfo tinfo; - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - goto done; - } } lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; -done:; lfsr_traversal_close(&lfs, &t) => 0; lfsr_unmount(&lfs) => 0; @@ -2110,7 +1965,6 @@ done:; # some more complex mutation tests [cases.test_traversal_mutation_fwrite] -defines.EXCL = [false, true] defines.CKMETA = [false, true] defines.CKDATA = [false, true] defines.LOOKAHEAD = [false, true] @@ -2143,8 +1997,7 @@ code = ''' // try traversing lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0)) => 0; @@ -2161,13 +2014,12 @@ code = ''' // step traversal struct lfs_tinfo tinfo; int err = lfsr_traversal_read(&lfs, &t, &tinfo); - assert(!err - || (!EXCL && err == LFS_ERR_NOENT) - || (EXCL && err == LFS_ERR_BUSY)); - if (err == LFS_ERR_NOENT - || err == LFS_ERR_BUSY) { + assert(!err || err == LFS_ERR_NOENT); + if (err == LFS_ERR_NOENT) { break; } + + assert(tinfo.flags == LFS_I_DIRTY); } lfsr_traversal_close(&lfs, &t) => 0; @@ -2183,7 +2035,6 @@ code = ''' ''' [cases.test_traversal_mutation_fwrite_open] -defines.EXCL = [false, true] defines.CKMETA = [false, true] defines.CKDATA = [false, true] defines.LOOKAHEAD = [false, true] @@ -2219,8 +2070,7 @@ code = ''' // try traversing lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0)) => 0; @@ -2238,13 +2088,12 @@ code = ''' // step traversal struct lfs_tinfo tinfo; int err = lfsr_traversal_read(&lfs, &t, &tinfo); - assert(!err - || (!EXCL && err == LFS_ERR_NOENT) - || (EXCL && err == LFS_ERR_BUSY)); - if (err == LFS_ERR_NOENT - || err == LFS_ERR_BUSY) { + assert(!err || err == LFS_ERR_NOENT); + if (err == LFS_ERR_NOENT) { break; } + + assert(tinfo.flags == LFS_I_DIRTY); } lfsr_traversal_close(&lfs, &t) => 0; @@ -2313,9 +2162,11 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); @@ -2392,16 +2243,20 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // rewrite the file @@ -2416,11 +2271,14 @@ code = ''' // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -2484,13 +2342,16 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // rewrite the file @@ -2505,8 +2366,10 @@ code = ''' // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -2568,9 +2431,11 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); @@ -2646,16 +2511,20 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // rewrite the file @@ -2667,11 +2536,14 @@ code = ''' // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -2737,13 +2609,16 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // rewrite the file @@ -2755,8 +2630,10 @@ code = ''' // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -2823,9 +2700,11 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); @@ -2905,16 +2784,20 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // close the file @@ -2925,11 +2808,14 @@ code = ''' // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((DESYNC) ? 0 : LFS_I_DIRTY)); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((DESYNC) ? 0 : LFS_I_DIRTY)); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((DESYNC) ? 0 : LFS_I_DIRTY)); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -3000,13 +2886,16 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // close the file @@ -3017,8 +2906,10 @@ code = ''' // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((DESYNC) ? 0 : LFS_I_DIRTY)); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((DESYNC) ? 0 : LFS_I_DIRTY)); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -3089,13 +2980,16 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // remove the file @@ -3103,8 +2997,10 @@ code = ''' // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -3173,13 +3069,16 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // rename one file over another @@ -3187,13 +3086,17 @@ code = ''' // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -3267,13 +3170,16 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // rename one file over another @@ -3281,8 +3187,10 @@ code = ''' // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -3347,6 +3255,7 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); @@ -3363,23 +3272,31 @@ code = ''' // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -3451,13 +3368,16 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse a data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // create enough files for mroot to split @@ -3473,21 +3393,28 @@ code = ''' // traverse another data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -3564,18 +3491,23 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // and another data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // create enough files for mroot to split @@ -3591,11 +3523,14 @@ code = ''' // traverse another data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -3665,6 +3600,7 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); @@ -3679,18 +3615,24 @@ code = ''' // traverse mroot lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -3755,13 +3697,16 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse a data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // rewrite enough files for mroot to extend @@ -3775,11 +3720,14 @@ code = ''' // traverse another data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -3853,6 +3801,7 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); @@ -3872,18 +3821,24 @@ code = ''' // // traverse mroot lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -3957,17 +3912,22 @@ code = ''' // traverse mroots struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse a data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // rewrite enough files for mroot to relocate @@ -3982,11 +3942,14 @@ code = ''' // traverse another data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -4089,6 +4052,7 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); @@ -4106,43 +4070,59 @@ code = ''' // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -4255,31 +4235,41 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse mtree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // create enough files for mdir to split again @@ -4296,26 +4286,35 @@ code = ''' // traverse another data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -4428,36 +4427,48 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse mtree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // create enough files for mdir to split again @@ -4473,19 +4484,25 @@ code = ''' } // traverse another data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; + assert(tinfo.flags == LFS_I_DIRTY); lfsr_traversal_close(&lfs, &t) => 0; // check the file contents @@ -4601,6 +4618,7 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); @@ -4615,38 +4633,52 @@ code = ''' // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -4765,31 +4797,41 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse mtree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // rewrite enough files for mroot to extend @@ -4803,21 +4845,28 @@ code = ''' // traverse another data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -4941,6 +4990,7 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); @@ -4956,38 +5006,52 @@ code = ''' // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -5111,35 +5175,47 @@ code = ''' // traverse mroots struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse mtree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse one data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_DATA); // rewrite enough files for mroot to relocate @@ -5154,21 +5230,28 @@ code = ''' // traverse another data block lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse two data blocks lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_DATA); // we should be at end of traversal now lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -5243,9 +5326,11 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -5274,74 +5359,6 @@ code = ''' lfsr_unmount(&lfs) => 0; ''' -# yes, compactions should return busy if excl -[cases.test_traversal_compact_excl] -defines.CKMETA = [false, true] -defines.CKDATA = [false, true] -defines.LOOKAHEAD = [false, true] -defines.SIZE = 'FILE_BUFFER_SIZE/2' -# set compact thresh to minimum -defines.GC_COMPACT_THRESH = 'BLOCK_SIZE/2' -code = ''' - lfs_t lfs; - lfsr_format(&lfs, CFG) => 0; - lfsr_mount(&lfs, CFG) => 0; - - uint32_t prng = 42; - - // write to our mdir until >gc_compact_thresh full - lfsr_file_t file; - lfsr_file_open(&lfs, &file, "jellyfish", - LFS_O_RDWR | LFS_O_CREAT | LFS_O_EXCL) => 0; - - // hack, don't use the internals like this - uint8_t wbuf[SIZE]; - while ((file.o.o.mdir.rbyd.eoff & 0x7fffffff) <= GC_COMPACT_THRESH) { - lfsr_file_rewind(&lfs, &file) => 0; - for (lfs_size_t j = 0; j < SIZE; j++) { - wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26); - } - lfsr_file_write(&lfs, &file, wbuf, SIZE) => SIZE; - lfsr_file_sync(&lfs, &file) => 0; - } - - // try traversing and compacting - lfsr_traversal_t t; - lfsr_traversal_open(&lfs, &t, - LFS_T_COMPACT - | LFS_T_EXCL - | ((CKMETA) ? LFS_T_CKMETA : 0) - | ((CKDATA) ? LFS_T_CKDATA : 0) - | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0)) => 0; - // traverse mroot - struct lfs_tinfo tinfo; - // compact, return bust - lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_BUSY; - lfsr_traversal_close(&lfs, &t) => 0; - - // mdir should have been compacted - assert((file.o.o.mdir.rbyd.eoff & 0x7fffffff) <= GC_COMPACT_THRESH); - - // check we can still read the file - for (int remount = 0; remount < 2; remount++) { - // remount? - if (remount) { - lfsr_file_close(&lfs, &file) => 0; - lfsr_unmount(&lfs) => 0; - lfsr_mount(&lfs, CFG) => 0; - lfsr_file_open(&lfs, &file, "jellyfish", LFS_O_RDONLY) => 0; - } - - lfsr_file_rewind(&lfs, &file) => 0; - uint8_t rbuf[SIZE]; - lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE; - assert(memcmp(rbuf, wbuf, SIZE) == 0); - } - - lfsr_file_close(&lfs, &file) => 0; - lfsr_unmount(&lfs) => 0; -''' - [cases.test_traversal_compact_mrootchain] defines.CKMETA = [false, true] defines.CKDATA = [false, true] @@ -5403,15 +5420,19 @@ code = ''' // traverse mrootanchor struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse mroot lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; lfsr_traversal_close(&lfs, &t) => 0; @@ -5489,8 +5510,10 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; lfsr_traversal_close(&lfs, &t) => 0; @@ -5586,23 +5609,30 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // should have split, traverse mtree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; lfsr_traversal_close(&lfs, &t) => 0; @@ -5755,28 +5785,37 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse mtree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((COMPACTSET & 0x1) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((COMPACTSET & 0x1) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((COMPACTSET & 0x3) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((COMPACTSET & 0x3) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((COMPACTSET & 0x7) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == ((COMPACTSET & 0x7) ? LFS_I_DIRTY : 0)); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; lfsr_traversal_close(&lfs, &t) => 0; @@ -5932,33 +5971,44 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse mtree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // should have split, traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; lfsr_traversal_close(&lfs, &t) => 0; @@ -6114,23 +6164,30 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); // traverse mdir lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_MDIR); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; lfsr_traversal_close(&lfs, &t) => 0; @@ -6218,13 +6275,16 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; lfsr_traversal_close(&lfs, &t) => 0; @@ -6298,13 +6358,16 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; lfsr_traversal_close(&lfs, &t) => 0; @@ -6375,13 +6438,16 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; lfsr_traversal_close(&lfs, &t) => 0; @@ -6477,19 +6543,24 @@ code = ''' // traverse mroot struct lfs_tinfo tinfo; lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == 0); assert(tinfo.btype == LFS_BTYPE_MDIR); assert(tinfo.block == 0 || tinfo.block == 1); // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); // traverse btree lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; lfsr_traversal_close(&lfs, &t) => 0; @@ -6599,6 +6670,7 @@ code = ''' for (lfs_size_t i = 0; i < 5; i++) { // traverse bshrub lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); } lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -6716,6 +6788,7 @@ code = ''' for (lfs_size_t i = 0; i < 5; i++) { // traverse bshrub lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); } lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -6832,6 +6905,7 @@ code = ''' for (lfs_size_t i = 0; i < 5; i++) { // traverse bshrub lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); } lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -6969,6 +7043,7 @@ code = ''' for (lfs_size_t i = 0; i < 3*5; i++) { // traverse bshrub lfsr_traversal_read(&lfs, &t, &tinfo) => 0; + assert(tinfo.flags == LFS_I_DIRTY); assert(tinfo.btype == LFS_BTYPE_BTREE); } lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; @@ -7028,7 +7103,6 @@ code = ''' [cases.test_traversal_spam_dir_many] # traverse steps between each op defines.STEPS = [1, 2, 4, 8, 16, 32, 64, 128] -defines.EXCL = [false, true] defines.CKMETA = [true] defines.CKDATA = [true] defines.LOOKAHEAD = [false, true] @@ -7045,8 +7119,7 @@ code = ''' // open a traversal lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0) | ((COMPACT) ? LFS_T_COMPACT : 0)) => 0; @@ -7062,9 +7135,9 @@ code = ''' for (lfs_size_t s = 0; s < STEPS; s++) { struct lfs_tinfo tinfo; err = lfsr_traversal_read(&lfs, &t, &tinfo); - assert(!err || err == LFS_ERR_NOENT || err == LFS_ERR_BUSY); + assert(!err || err == LFS_ERR_NOENT); // restart traversal - if (err == LFS_ERR_NOENT || err == LFS_ERR_BUSY) { + if (err == LFS_ERR_NOENT) { lfsr_traversal_rewind(&lfs, &t) => 0; } } @@ -7138,7 +7211,6 @@ code = ''' [cases.test_traversal_spam_dir_fuzz] # traverse steps between each op defines.STEPS = [1, 2, 4, 8, 16, 32, 64, 128] -defines.EXCL = [false, true] defines.CKMETA = [true] defines.CKDATA = [true] defines.LOOKAHEAD = [false, true] @@ -7162,8 +7234,7 @@ code = ''' // open a traversal lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0) | ((COMPACT) ? LFS_T_COMPACT : 0)) => 0; @@ -7255,9 +7326,9 @@ code = ''' for (lfs_size_t s = 0; s < STEPS; s++) { struct lfs_tinfo tinfo; int err = lfsr_traversal_read(&lfs, &t, &tinfo); - assert(!err || err == LFS_ERR_NOENT || err == LFS_ERR_BUSY); + assert(!err || err == LFS_ERR_NOENT); // restart traversal - if (err == LFS_ERR_NOENT || err == LFS_ERR_BUSY) { + if (err == LFS_ERR_NOENT) { lfsr_traversal_rewind(&lfs, &t) => 0; } } @@ -7319,7 +7390,6 @@ code = ''' [cases.test_traversal_spam_file_many] # traverse steps between each op defines.STEPS = [1, 2, 4, 8, 16, 32, 64, 128] -defines.EXCL = [false, true] defines.CKMETA = [true] defines.CKDATA = [true] defines.LOOKAHEAD = [false, true] @@ -7346,8 +7416,7 @@ code = ''' // open a traversal lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0) | ((COMPACT) ? LFS_T_COMPACT : 0)) => 0; @@ -7373,9 +7442,9 @@ code = ''' for (lfs_size_t s = 0; s < STEPS; s++) { struct lfs_tinfo tinfo; int err = lfsr_traversal_read(&lfs, &t, &tinfo); - assert(!err || err == LFS_ERR_NOENT || err == LFS_ERR_BUSY); + assert(!err || err == LFS_ERR_NOENT); // restart traversal - if (err == LFS_ERR_NOENT || err == LFS_ERR_BUSY) { + if (err == LFS_ERR_NOENT) { lfsr_traversal_rewind(&lfs, &t) => 0; } } @@ -7423,7 +7492,6 @@ code = ''' [cases.test_traversal_spam_file_fuzz] # traverse steps between each op defines.STEPS = [1, 2, 4, 8, 16, 32, 64, 128] -defines.EXCL = [false, true] defines.CKMETA = [true] defines.CKDATA = [true] defines.LOOKAHEAD = [false, true] @@ -7458,8 +7526,7 @@ code = ''' // open a traversal lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0) | ((COMPACT) ? LFS_T_COMPACT : 0)) => 0; @@ -7587,9 +7654,9 @@ code = ''' for (lfs_size_t s = 0; s < STEPS; s++) { struct lfs_tinfo tinfo; int err = lfsr_traversal_read(&lfs, &t, &tinfo); - assert(!err || err == LFS_ERR_NOENT || err == LFS_ERR_BUSY); + assert(!err || err == LFS_ERR_NOENT); // restart traversal - if (err == LFS_ERR_NOENT || err == LFS_ERR_BUSY) { + if (err == LFS_ERR_NOENT) { lfsr_traversal_rewind(&lfs, &t) => 0; } } @@ -7666,7 +7733,6 @@ code = ''' [cases.test_traversal_spam_fwrite_fuzz] # traverse steps between each op defines.STEPS = [1, 2, 4, 8, 16, 32, 64, 128] -defines.EXCL = [false, true] defines.CKMETA = [true] defines.CKDATA = [true] defines.LOOKAHEAD = [false, true] @@ -7733,8 +7799,7 @@ code = ''' // open a traversal lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0) | ((COMPACT) ? LFS_T_COMPACT : 0)) => 0; @@ -7766,9 +7831,9 @@ code = ''' for (lfs_size_t s = 0; s < STEPS; s++) { struct lfs_tinfo tinfo; int err = lfsr_traversal_read(&lfs, &t, &tinfo); - assert(!err || err == LFS_ERR_NOENT || err == LFS_ERR_BUSY); + assert(!err || err == LFS_ERR_NOENT); // restart traversal - if (err == LFS_ERR_NOENT || err == LFS_ERR_BUSY) { + if (err == LFS_ERR_NOENT) { lfsr_traversal_rewind(&lfs, &t) => 0; } } @@ -7829,7 +7894,6 @@ code = ''' [cases.test_traversal_spam_orphanzombie_fuzz] # traverse steps between each op defines.STEPS = [1, 2, 4, 8, 16, 32, 64, 128] -defines.EXCL = [false, true] defines.CKMETA = [true] defines.CKDATA = [true] defines.LOOKAHEAD = [false, true] @@ -7874,8 +7938,7 @@ code = ''' // open a traversal lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0) | ((COMPACT) ? LFS_T_COMPACT : 0)) => 0; @@ -8111,9 +8174,9 @@ code = ''' for (lfs_size_t s = 0; s < STEPS; s++) { struct lfs_tinfo tinfo; int err = lfsr_traversal_read(&lfs, &t, &tinfo); - assert(!err || err == LFS_ERR_NOENT || err == LFS_ERR_BUSY); + assert(!err || err == LFS_ERR_NOENT); // restart traversal - if (err == LFS_ERR_NOENT || err == LFS_ERR_BUSY) { + if (err == LFS_ERR_NOENT) { lfsr_traversal_rewind(&lfs, &t) => 0; } } @@ -8200,7 +8263,6 @@ code = ''' [cases.test_traversal_spam_orphanzombiedir_fuzz] # traverse steps between each op defines.STEPS = [1, 2, 4, 8, 16, 32, 64, 128] -defines.EXCL = [false, true] defines.CKMETA = [true] defines.CKDATA = [true] defines.LOOKAHEAD = [false, true] @@ -8246,8 +8308,7 @@ code = ''' // open a traversal lfsr_traversal_t t; lfsr_traversal_open(&lfs, &t, - ((EXCL) ? LFS_T_EXCL : 0) - | ((CKMETA) ? LFS_T_CKMETA : 0) + ((CKMETA) ? LFS_T_CKMETA : 0) | ((CKDATA) ? LFS_T_CKDATA : 0) | ((LOOKAHEAD) ? LFS_T_LOOKAHEAD : 0) | ((COMPACT) ? LFS_T_COMPACT : 0)) => 0; @@ -8544,9 +8605,9 @@ code = ''' for (lfs_size_t s = 0; s < STEPS; s++) { struct lfs_tinfo tinfo; int err = lfsr_traversal_read(&lfs, &t, &tinfo); - assert(!err || err == LFS_ERR_NOENT || err == LFS_ERR_BUSY); + assert(!err || err == LFS_ERR_NOENT); // restart traversal - if (err == LFS_ERR_NOENT || err == LFS_ERR_BUSY) { + if (err == LFS_ERR_NOENT) { lfsr_traversal_rewind(&lfs, &t) => 0; } }