From 51357bc925a6b1d10dfb6a59b155624c4383c95d Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sat, 8 Jun 2024 16:08:59 -0500 Subject: [PATCH] Readded lfsr_fs_mkconsistent See comments/previous commits. lfsr_fs_mkconsistent allows running internal consistency operations without any other filesystem changes. Implementation-wize, this just calls lfsr_fs_preparemutation which we already need to, uh, prepare for mutation. Though it may do some additional work in the future, such as setting compat flags, version numbers, etc. Added mkconsistent permutations to what seems like the relevant tests: - test_forphans - easy for lfsr_fs_mkconsistent to accidentally delete orphans/zombies. - test_powerloss - heavy fuzz tests over powerloss-related consistency operations, though this does multiply every permutation by ~2x... Code cost minimal. I guess this is what it costs to make an internal function non-static: code stack before: 33634 2592 after: 33642 (+0.0%) 2592 (+0.0%) --- lfs.c | 4 + lfs.h | 12 ++ tests/test_forphans.toml | 284 ++++++++++++++++++++++++++++++++++++-- tests/test_powerloss.toml | 16 +++ 4 files changed, 301 insertions(+), 15 deletions(-) diff --git a/lfs.c b/lfs.c index b295d0b4..bc29078b 100644 --- a/lfs.c +++ b/lfs.c @@ -9094,6 +9094,10 @@ static int lfsr_fs_preparemutation(lfs_t *lfs) { return 0; } +int lfsr_fs_mkconsistent(lfs_t *lfs) { + return lfsr_fs_preparemutation(lfs); +} + /// Directory operations /// diff --git a/lfs.h b/lfs.h index fcc45bcb..2ab5f1d9 100644 --- a/lfs.h +++ b/lfs.h @@ -959,6 +959,18 @@ lfs_ssize_t lfsr_fs_size(lfs_t *lfs); // Returns a negative error code on failure. //int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data); +#ifndef LFS_READONLY +// Attempt to make the filesystem consistent and ready for writing +// +// Calling this function is not required, consistency will be implicitly +// enforced on the first operation that writes to the filesystem, but this +// function allows the work to be performed earlier and without other +// filesystem changes. +// +// Returns a negative error code on failure. +int lfsr_fs_mkconsistent(lfs_t *lfs); +#endif + #ifndef LFS_READONLY #ifdef LFS_MIGRATE // Attempts to migrate a previous version of littlefs diff --git a/tests/test_forphans.toml b/tests/test_forphans.toml index 67291428..daef54d8 100644 --- a/tests/test_forphans.toml +++ b/tests/test_forphans.toml @@ -14,6 +14,7 @@ defines.SIZE = [ ] defines.CHUNK = 'LFS_MIN(64, SIZE)' defines.SYNC = [false, true] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -24,6 +25,11 @@ code = ''' lfsr_file_open(&lfs, &file, "batman", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // check that the file doesn't _really_ exist lfs_t lfs_; lfsr_mount(&lfs_, CFG) => 0; @@ -57,6 +63,11 @@ code = ''' } lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // check that the file still doesn't _really_ exist lfsr_mount(&lfs_, CFG) => 0; // via stat @@ -378,6 +389,7 @@ defines.SIZE = [ ] defines.CHUNK = 'LFS_MIN(64, SIZE)' defines.SYNC = [false, true] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -388,6 +400,11 @@ code = ''' lfsr_file_open(&lfs, &file, "batman", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -421,6 +438,11 @@ code = ''' } lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat lfsr_stat(&lfs, "batman", &info) => LFS_ERR_NOENT; @@ -448,6 +470,11 @@ code = ''' lfsr_file_open(&lfs, &file__, "batman", LFS_O_RDWR | LFS_O_CREAT | LFS_O_EXCL) => 0; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + if (SYNC) { // sync the file lfsr_file_sync(&lfs, &file) => 0; @@ -568,6 +595,7 @@ defines.SIZE = [ ] defines.CHUNK = 'LFS_MIN(64, SIZE)' defines.SYNC = [false, true] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -582,6 +610,11 @@ code = ''' lfsr_file_open(&lfs, &file__, "batman", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -615,6 +648,11 @@ code = ''' } lfsr_file_write(&lfs, &file__, wbuf, CHUNK) => CHUNK; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat lfsr_stat(&lfs, "batman", &info) => LFS_ERR_NOENT; @@ -757,6 +795,7 @@ defines.SIZE = [ ] defines.CHUNK = 'LFS_MIN(64, SIZE)' defines.SYNC = [false, true] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -775,6 +814,11 @@ code = ''' lfsr_file_open(&lfs, &file___, "batman", LFS_O_RDWR | LFS_O_CREAT | LFS_O_EXCL) => 0; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // write to the first file uint32_t prng = 42; for (lfs_off_t i = 0; i < SIZE; i += CHUNK) { @@ -784,6 +828,11 @@ code = ''' } lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -818,6 +867,11 @@ code = ''' } lfsr_file_write(&lfs, &file__, wbuf, CHUNK) => CHUNK; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -1074,6 +1128,7 @@ defines.SIZE = [ '4*BLOCK_SIZE', ] defines.CHUNK = 'LFS_MIN(64, SIZE)' +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -1084,6 +1139,11 @@ code = ''' lfsr_file_open(&lfs, &file, "batman", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL | LFS_O_DESYNC) => 0; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // write to the file uint32_t prng = 42; for (lfs_off_t i = 0; i < SIZE; i += CHUNK) { @@ -1093,6 +1153,11 @@ code = ''' } lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -1121,6 +1186,11 @@ code = ''' // close lfsr_file_close(&lfs, &file) => 0; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // because the file was desynced, it should still not exist // via stat struct lfs_info info; @@ -1186,6 +1256,7 @@ defines.CHUNK = 'LFS_MIN(64, SIZE)' # SYNC=0x1 => sync before orphaning # SYNC=0x2 => sync after orphaning defines.SYNC = [0, 1, 2, 3] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -1204,6 +1275,11 @@ code = ''' lfsr_file_open(&lfs, &file___, "batman", LFS_O_RDWR | LFS_O_CREAT | LFS_O_EXCL) => 0; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // write to the first file uint32_t prng = 42; for (lfs_off_t i = 0; i < SIZE; i += CHUNK) { @@ -1213,6 +1289,11 @@ code = ''' } lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -1247,6 +1328,11 @@ code = ''' } lfsr_file_write(&lfs, &file__, wbuf, CHUNK) => CHUNK; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -1462,6 +1548,7 @@ defines.SIZE = [ '4*BLOCK_SIZE', ] defines.CHUNK = 'LFS_MIN(64, SIZE)' +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -1497,6 +1584,11 @@ code = ''' lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK; } + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, none of the orphans exist // via stat struct lfs_info info; @@ -1669,6 +1761,7 @@ defines.ORPHANS = [1, 2, 3, 100] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -1707,6 +1800,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // create a new file over the orphan lfsr_file_open(&lfs, &file, "batman", @@ -1719,6 +1815,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make sure the new file is readable // via stat @@ -1761,6 +1860,7 @@ defines.ORPHANS = [1, 2, 3, 100] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -1799,6 +1899,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // create a new dir over the orphan lfsr_mkdir(&lfs, "batman") => 0; @@ -1807,6 +1910,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make sure the new dir is readable // via stat @@ -1842,6 +1948,7 @@ defines.ORPHANS = [1, 2, 3, 100] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -1880,6 +1987,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // orphans aren't real, so remove should fail lfsr_remove(&lfs, "batman") => LFS_ERR_NOENT; @@ -1888,6 +1998,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // just make sure things look ok // via stat @@ -1919,6 +2032,7 @@ defines.ORPHANS = [1, 2, 3, 100] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -1985,6 +2099,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // rename onto orphan lfsr_rename(&lfs, @@ -1995,6 +2112,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make sure the new file is readable // via stat @@ -2065,6 +2185,7 @@ defines.ORPHANS = [1, 2, 3, 100] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -2103,6 +2224,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // orphans aren't real, so rename should fail lfsr_rename(&lfs, "batman", "catman") => LFS_ERR_NOENT; @@ -2111,6 +2235,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // just make sure things look ok // via stat @@ -2144,6 +2271,7 @@ defines.SIZE = [ '4*BLOCK_SIZE', ] defines.CHUNK = 'LFS_MIN(64, SIZE)' +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -2170,6 +2298,11 @@ code = ''' // remove the file lfsr_remove(&lfs, "batman") => 0; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -2271,6 +2404,7 @@ defines.SIZE = [ '4*BLOCK_SIZE', ] defines.CHUNK = 'LFS_MIN(64, SIZE)' +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -2297,6 +2431,11 @@ code = ''' lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK; } + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -2398,7 +2537,7 @@ defines.SIZE = [ '4*BLOCK_SIZE', ] defines.CHUNK = 'LFS_MIN(64, SIZE)' -defines.SYNC = [false, true] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -2440,6 +2579,11 @@ code = ''' lfsr_file_write(&lfs, &file__, wbuf, CHUNK) => CHUNK; } + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -2624,7 +2768,7 @@ defines.SIZE = [ '4*BLOCK_SIZE', ] defines.CHUNK = 'LFS_MIN(64, SIZE)' -defines.SYNC = [false, true] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -2666,6 +2810,11 @@ code = ''' lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK; } + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -2850,7 +2999,7 @@ defines.SIZE = [ '4*BLOCK_SIZE', ] defines.CHUNK = 'LFS_MIN(64, SIZE)' -defines.SYNC = [false, true] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -2913,6 +3062,11 @@ code = ''' lfsr_file_write(&lfs, &file___, wbuf, CHUNK) => CHUNK; } + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -3111,7 +3265,7 @@ defines.SIZE = [ '4*BLOCK_SIZE', ] defines.CHUNK = 'LFS_MIN(64, SIZE)' -defines.SYNC = [false, true] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -3174,6 +3328,11 @@ code = ''' lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK; } + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // as far as the filesystem is concerned, the file does not exist yet // via stat struct lfs_info info; @@ -3363,6 +3522,7 @@ code = ''' ''' [cases.test_forphans_zombie_open] +defines.POSTHUMOUS = [false, true] # CLOSE=0 => don't close (before end of test) # CLOSE=1 => close after op # CLOSE=2 => close before op @@ -3371,7 +3531,7 @@ defines.CLOSE = [0, 1, 2] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] -defines.POSTHUMOUS = [false, true] +defines.MKCONSISTENT = [false, true] if = 'REMOUNT <= CLOSE' code = ''' lfs_t lfs; @@ -3397,6 +3557,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // create a new file over the zombie lfsr_file_t file; @@ -3428,6 +3591,9 @@ code = ''' lfsr_mount(&lfs, CFG) => 0; } } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make sure the new file is readable // via stat @@ -3468,6 +3634,7 @@ code = ''' ''' [cases.test_forphans_zombie_mkdir] +defines.POSTHUMOUS = [false, true] # CLOSE=0 => don't close (before end of test) # CLOSE=1 => close after op # CLOSE=2 => close before op @@ -3476,7 +3643,7 @@ defines.CLOSE = [0, 1, 2] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] -defines.POSTHUMOUS = [false, true] +defines.MKCONSISTENT = [false, true] if = 'REMOUNT <= CLOSE' code = ''' lfs_t lfs; @@ -3502,6 +3669,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // create a new dir over the zombie lfsr_mkdir(&lfs, "batman") => 0; @@ -3528,6 +3698,9 @@ code = ''' lfsr_mount(&lfs, CFG) => 0; } } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make sure the new dir is readable // via stat @@ -3561,6 +3734,7 @@ code = ''' ''' [cases.test_forphans_zombie_rm] +defines.POSTHUMOUS = [false, true] # CLOSE=0 => don't close (before end of test) # CLOSE=1 => close after op # CLOSE=2 => close before op @@ -3569,7 +3743,7 @@ defines.CLOSE = [0, 1, 2] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] -defines.POSTHUMOUS = [false, true] +defines.MKCONSISTENT = [false, true] if = 'REMOUNT <= CLOSE' code = ''' lfs_t lfs; @@ -3595,6 +3769,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // zombies aren't real, so remove should fail lfsr_remove(&lfs, "batman") => LFS_ERR_NOENT; @@ -3621,6 +3798,9 @@ code = ''' lfsr_mount(&lfs, CFG) => 0; } } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // just make sure things look ok // via stat @@ -3650,6 +3830,7 @@ code = ''' defines.DIR = [false, true] defines.INTERDIR = [false, true] defines.DISTANCE = [0, 1, 100] +defines.POSTHUMOUS = [false, true] # CLOSE=0 => don't close (before end of test) # CLOSE=1 => close after op # CLOSE=2 => close before op @@ -3658,7 +3839,7 @@ defines.CLOSE = [0, 1, 2] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] -defines.POSTHUMOUS = [false, true] +defines.MKCONSISTENT = [false, true] if = 'REMOUNT <= CLOSE' code = ''' lfs_t lfs; @@ -3711,6 +3892,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // rename onto zombie lfsr_rename(&lfs, @@ -3739,6 +3923,9 @@ code = ''' lfsr_mount(&lfs, CFG) => 0; } } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make sure the new file is readable // via stat @@ -3807,6 +3994,7 @@ code = ''' ''' [cases.test_forphans_zombie_mv_src] +defines.POSTHUMOUS = [false, true] # CLOSE=0 => don't close (before end of test) # CLOSE=1 => close after op # CLOSE=2 => close before op @@ -3815,7 +4003,7 @@ defines.CLOSE = [0, 1, 2] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] -defines.POSTHUMOUS = [false, true] +defines.MKCONSISTENT = [false, true] if = 'REMOUNT <= CLOSE' code = ''' lfs_t lfs; @@ -3841,6 +4029,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // zombies aren't real, so rename should fail lfsr_rename(&lfs, "batman", "catman") => LFS_ERR_NOENT; @@ -3867,6 +4058,9 @@ code = ''' lfsr_mount(&lfs, CFG) => 0; } } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // just make sure things look ok // via stat @@ -3894,9 +4088,10 @@ code = ''' ''' [cases.test_forphans_zombify_mkdir] +defines.POSTHUMOUS = [false, true] defines.CLOSE = [false, true] defines.REMOUNT = [false, true] -defines.POSTHUMOUS = [false, true] +defines.MKCONSISTENT = [false, true] if = 'REMOUNT <= CLOSE' code = ''' lfs_t lfs; @@ -3938,6 +4133,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make sure the new dir is readable // via stat @@ -3975,9 +4173,10 @@ defines.ORPHAN = [false, true] defines.DIR = [false, true] defines.INTERDIR = [false, true] defines.DISTANCE = [0, 1, 100] +defines.POSTHUMOUS = [false, true] defines.CLOSE = [false, true] defines.REMOUNT = [false, true] -defines.POSTHUMOUS = [false, true] +defines.MKCONSISTENT = [false, true] if = [ 'REMOUNT <= CLOSE', '!DIR || ORPHAN', @@ -4054,6 +4253,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make sure the new file is readable // via stat @@ -4123,6 +4325,7 @@ code = ''' [cases.test_forphans_file_on_zombie_rm] defines.DIR = [false, true] +defines.POSTHUMOUS = [false, true] # CLOSE=0 => don't close (before end of test) # CLOSE=1 => close after op # CLOSE=2 => close before op @@ -4131,7 +4334,7 @@ defines.CLOSE = [0, 1, 2] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] -defines.POSTHUMOUS = [false, true] +defines.MKCONSISTENT = [false, true] if = 'REMOUNT <= CLOSE' code = ''' lfs_t lfs; @@ -4169,6 +4372,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // remove the file lfsr_remove(&lfs, "batman") => 0; @@ -4195,6 +4401,9 @@ code = ''' lfsr_mount(&lfs, CFG) => 0; } } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // just make sure things look ok // via stat @@ -4224,6 +4433,7 @@ code = ''' defines.DIR = [false, true] defines.INTERDIR = [false, true] defines.DISTANCE = [0, 1, 100] +defines.POSTHUMOUS = [false, true] # CLOSE=0 => don't close (before end of test) # CLOSE=1 => close after op # CLOSE=2 => close before op @@ -4232,7 +4442,7 @@ defines.CLOSE = [0, 1, 2] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] -defines.POSTHUMOUS = [false, true] +defines.MKCONSISTENT = [false, true] if = 'REMOUNT <= CLOSE' code = ''' lfs_t lfs; @@ -4297,6 +4507,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // rename onto the file lfsr_rename(&lfs, @@ -4325,6 +4538,9 @@ code = ''' lfsr_mount(&lfs, CFG) => 0; } } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make sure the new file is readable // via stat @@ -4407,6 +4623,7 @@ defines.CHUNK = 'LFS_MIN(64, SIZE)' defines.EXISTS = [false, true] defines.INTERDIR = [false, true] defines.DISTANCE = [0, 1, 100] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -4460,6 +4677,11 @@ code = ''' (INTERDIR) ? "c/datman" : "datman", (INTERDIR) ? "a/batman" : "batman") => 0; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // the file should have been renamed // via stat struct lfs_info info; @@ -4644,6 +4866,7 @@ defines.EXISTS = [false, true] defines.INTERDIR = [false, true] defines.DISTANCE = [0, 1, 100] defines.SYNC = [false, true] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -4697,6 +4920,11 @@ code = ''' lfsr_file_write(&lfs, &file, wbuf, CHUNK) => CHUNK; } + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // the file should have been renamed, but zero sized // via stat struct lfs_info info; @@ -4940,6 +5168,7 @@ defines.EXISTS = [false, true] defines.INTERDIR = [false, true] defines.DISTANCE = [0, 1, 100] defines.SYNC = [false, true] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -5008,6 +5237,11 @@ code = ''' (INTERDIR) ? "c/datman" : "datman", (INTERDIR) ? "a/batman" : "batman") => 0; + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // the file should have been renamed // via stat struct lfs_info info; @@ -5285,6 +5519,7 @@ defines.EXISTS = [false, true] defines.INTERDIR = [false, true] defines.DISTANCE = [0, 1, 100] defines.SYNC = [false, true] +defines.MKCONSISTENT = [false, true] code = ''' lfs_t lfs; lfsr_format(&lfs, CFG) => 0; @@ -5353,6 +5588,11 @@ code = ''' lfsr_file_write(&lfs, &file__, wbuf, CHUNK) => CHUNK; } + // mkconsistent should have no effect + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } + // the file should have been renamed, but zero sized // via stat struct lfs_info info; @@ -5612,6 +5852,7 @@ code = ''' defines.EXISTS = [false, true] defines.INTERDIR = [false, true] defines.DISTANCE = [0, 1, 100] +defines.POSTMV = [false, true] defines.SYNC = [false, true] # CLOSE=0 => don't close (before end of test) # CLOSE=1 => close after op @@ -5621,7 +5862,7 @@ defines.CLOSE = [0, 1, 2] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] -defines.POSTMV = [false, true] +defines.MKCONSISTENT = [false, true] if = 'REMOUNT <= CLOSE' code = ''' lfs_t lfs; @@ -5674,6 +5915,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // rename while open lfsr_rename(&lfs, @@ -5705,6 +5949,9 @@ code = ''' lfsr_mount(&lfs, CFG) => 0; } } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make sure the new file is readable // via stat @@ -5773,6 +6020,7 @@ defines.DIR = [false, true] defines.EXISTS = [false, true] defines.INTERDIR = [false, true] defines.DISTANCE = [0, 1, 100] +defines.POSTHUMOUS = [false, true] # CLOSE=0 => don't close (before end of test) # CLOSE=1 => close after op # CLOSE=2 => close before op @@ -5781,7 +6029,7 @@ defines.CLOSE = [0, 1, 2] # REMOUNT=1 => remount after op # REMOUNT=2 => remount before op defines.REMOUNT = [0, 1, 2] -defines.POSTHUMOUS = [false, true] +defines.MKCONSISTENT = [false, true] if = 'REMOUNT <= CLOSE' code = ''' lfs_t lfs; @@ -5848,6 +6096,9 @@ code = ''' lfsr_unmount(&lfs) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // rename while open lfsr_rename(&lfs, @@ -5876,6 +6127,9 @@ code = ''' lfsr_mount(&lfs, CFG) => 0; } } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make sure the new file is readable // via stat diff --git a/tests/test_powerloss.toml b/tests/test_powerloss.toml index b73090a4..a98e4ea3 100644 --- a/tests/test_powerloss.toml +++ b/tests/test_powerloss.toml @@ -23,6 +23,7 @@ defines.POWERLOSS_BEHAVIOR = [ 'LFS_EMUBD_POWERLOSS_MOSTBITS', 'LFS_EMUBD_POWERLOSS_OOO', ] +defines.MKCONSISTENT = [false, true] defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512] reentrant = true code = ''' @@ -33,6 +34,9 @@ code = ''' lfsr_format(&lfs, CFG) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // make this many directories for (lfs_size_t i = 0; i < N; i++) { @@ -117,6 +121,7 @@ defines.POWERLOSS_BEHAVIOR = [ 'LFS_EMUBD_POWERLOSS_MOSTBITS', 'LFS_EMUBD_POWERLOSS_OOO', ] +defines.MKCONSISTENT = [false, true] # inlining has a tendency to hide sync issues, so try without defines.INLINE_SIZE = ['BLOCK_SIZE/4', '0'] defines.N = [1, 2, 4, 8, 16, 32, 64] @@ -139,6 +144,9 @@ code = ''' lfsr_format(&lfs, CFG) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // create this many files uint32_t prng = 42; @@ -213,6 +221,7 @@ defines.POWERLOSS_BEHAVIOR = [ 'LFS_EMUBD_POWERLOSS_MOSTBITS', 'LFS_EMUBD_POWERLOSS_OOO', ] +defines.MKCONSISTENT = [false, true] # inlining has a tendency to hide sync issues, so try without defines.INLINE_SIZE = ['BLOCK_SIZE/4', '0'] defines.N = [1, 2, 4, 8, 16, 32, 64] @@ -238,6 +247,9 @@ code = ''' lfsr_format(&lfs, CFG) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // keep some test state on disk to survive powerloss typedef struct fuzz_state { @@ -439,6 +451,7 @@ defines.POWERLOSS_BEHAVIOR = [ 'LFS_EMUBD_POWERLOSS_MOSTBITS', 'LFS_EMUBD_POWERLOSS_OOO', ] +defines.MKCONSISTENT = [false, true] # inlining has a tendency to hide sync issues, so try without defines.INLINE_SIZE = ['BLOCK_SIZE/4', '0'] # note dirs x files grows O(n^2) @@ -466,6 +479,9 @@ code = ''' lfsr_format(&lfs, CFG) => 0; lfsr_mount(&lfs, CFG) => 0; } + if (MKCONSISTENT) { + lfsr_fs_mkconsistent(&lfs) => 0; + } // keep some test state on disk to survive powerloss typedef struct fuzz_state {