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 {