diff --git a/lfs.c b/lfs.c index 48522e1d..6bba30c0 100644 --- a/lfs.c +++ b/lfs.c @@ -11331,6 +11331,13 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file, LFS_ASSERT(!lfsr_o_isrdonly(flags) || !lfsr_o_iscreat(flags)); LFS_ASSERT(!lfsr_o_isrdonly(flags) || !lfsr_o_isexcl(flags)); LFS_ASSERT(!lfsr_o_isrdonly(flags) || !lfsr_o_istrunc(flags)); + // these flags are incompatible + LFS_ASSERT(lfsr_o_isrdonly(flags) + || !lfsr_o_issync(flags) + || !lfsr_o_isdesync(flags)); + LFS_ASSERT(lfsr_o_isrdonly(flags) + || !lfsr_o_issync(lfs->flags) + || !lfsr_o_isdesync(flags)); for (lfs_size_t i = 0; i < cfg->attr_count; i++) { // these flags require a writable attr LFS_ASSERT(!lfsr_o_isrdonly(cfg->attrs[i].flags) @@ -11461,9 +11468,8 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file, lfsr_omdir_open(lfs, &file->b.o); // sync if requested - if (!lfsr_o_isrdonly(file->b.o.flags) - && lfsr_o_issync(file->b.o.flags) - && lfsr_o_isunsync(file->b.o.flags)) { + if (lfsr_o_issync(file->b.o.flags) + && !lfsr_o_isrdonly(file->b.o.flags)) { err = lfsr_file_sync(lfs, file); if (err) { lfsr_omdir_close(lfs, &file->b.o); @@ -12946,6 +12952,8 @@ failed:; int lfsr_file_desync(lfs_t *lfs, lfsr_file_t *file) { (void)lfs; LFS_ASSERT(lfsr_omdir_isopen(lfs, &file->b.o)); + // desyncing LFS_O_SYNC files is not allowed + LFS_ASSERT(!lfsr_o_issync(file->b.o.flags)); // mark as desynced file->b.o.flags |= LFS_O_DESYNC; diff --git a/tests/test_fsync.toml b/tests/test_fsync.toml index 7669afd5..1bd6fd67 100644 --- a/tests/test_fsync.toml +++ b/tests/test_fsync.toml @@ -2480,7 +2480,7 @@ code = ''' # SYNC=1 => sync via lfsr_file_sync # SYNC=2 => sync via LFS_O_SYNC # SYNC=3 => sync via LFS_M_SYNC -defines.SYNC = [2, 3] +defines.SYNC = [2] # FLUSH=0 => no flush # FLUSH=1 => flush via lfsr_file_flush # FLUSH=2 => flush via LFS_O_FLUSH @@ -2496,7 +2496,7 @@ code = ''' CFG) => 0; // a - desynced writer - // b - writer + // b - synced writer // c - reader kept open, recvs updates from a // d - reader kept closed, checks disk state lfsr_file_t a; @@ -2504,44 +2504,40 @@ code = ''' lfsr_file_t c; lfsr_file_t d; uint8_t rbuf[256]; - // LFS_O_SYNC/LFS_M_SYNC should immediately create the file lfsr_file_open(&lfs, &a, "jello", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL | ((FLUSH == 2) ? LFS_O_FLUSH : 0) - | ((SYNC == 2) ? LFS_O_SYNC : 0) | LFS_O_DESYNC) => 0; - struct lfs_info info; - lfsr_stat(&lfs, "jello", &info) => 0; - assert(strcmp(info.name, "jello") == 0); - assert(info.type == LFS_TYPE_REG); - assert(info.size == 0); - // create the other files lfsr_file_open(&lfs, &b, "jello", LFS_O_WRONLY + | LFS_O_CREAT + | LFS_O_EXCL | ((FLUSH == 2) ? LFS_O_FLUSH : 0) | ((SYNC == 2) ? LFS_O_SYNC : 0)) => 0; lfsr_file_open(&lfs, &c, "jello", LFS_O_RDONLY) => 0; - // write to b - lfsr_file_write(&lfs, &b, "hello!", strlen("hello!")) + // write to a + lfsr_file_write(&lfs, &a, "hello!", strlen("hello!")) => strlen("hello!"); + // write to b + lfsr_file_write(&lfs, &b, "bonjour!", strlen("bonjour!")) + => strlen("bonjour!"); // our write should show up in c - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("hello!"); - assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); + lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("bonjour!"); + assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); // and on disk lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("hello!"); - assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); + lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("bonjour!"); + assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); lfsr_file_close(&lfs, &d) => 0; // sync a lfsr_file_sync(&lfs, &a) => 0; - // c should still have b, this may be surprising, but the implicit - // sync in open+O_CREAT clears the desync flag + // c should revert to a's contents lfsr_file_rewind(&lfs, &c) => 0; lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("hello!"); assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); @@ -2551,17 +2547,44 @@ code = ''' assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); lfsr_file_close(&lfs, &d) => 0; - // reopen with LFS_O_TRUNC + // reopen a with LFS_O_TRUNC lfsr_file_close(&lfs, &a) => 0; lfsr_file_open(&lfs, &a, "jello", LFS_O_WRONLY | LFS_O_TRUNC | ((FLUSH == 2) ? LFS_O_FLUSH : 0) - | ((SYNC == 2) ? LFS_O_SYNC : 0) | LFS_O_DESYNC) => 0; + // c should still have a's contents + lfsr_file_rewind(&lfs, &c) => 0; + lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("hello!"); + assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); + // and on disk + lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; + lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("hello!"); + assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); + lfsr_file_close(&lfs, &d) => 0; + + // rewrite b + lfsr_file_rewind(&lfs, &b) => 0; + lfsr_file_write(&lfs, &b, "ohayo!", strlen("ohayo!")) + => strlen("ohayo!"); + // should immediately show up in c lfsr_file_rewind(&lfs, &c) => 0; + lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("ohayo!"); + assert(memcmp(rbuf, "ohayo!", strlen("ohayo!")) == 0); + // and on disk + lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; + lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("ohayo!"); + assert(memcmp(rbuf, "ohayo!", strlen("ohayo!")) == 0); + lfsr_file_close(&lfs, &d) => 0; + + // sync a + lfsr_file_sync(&lfs, &a) => 0; + + // c should revert to a's contents + lfsr_file_rewind(&lfs, &c) => 0; lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => 0; // and on disk lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; @@ -2573,86 +2596,18 @@ code = ''' lfsr_file_open(&lfs, &a, "jello", LFS_O_WRONLY | ((FLUSH == 2) ? LFS_O_FLUSH : 0) - | ((SYNC == 2) ? LFS_O_SYNC : 0) | LFS_O_DESYNC) => 0; - lfsr_file_write(&lfs, &a, "bonjour!", strlen("bonjour!")) - => strlen("bonjour!"); - - // should immediately show up in c - lfsr_file_rewind(&lfs, &c) => 0; - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("bonjour!"); - assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); - // and on disk - lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("bonjour!"); - assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); - lfsr_file_close(&lfs, &d) => 0; - - // sync b - lfsr_file_sync(&lfs, &b) => 0; - - // should still have a - lfsr_file_rewind(&lfs, &c) => 0; - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("bonjour!"); - assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); - // and on disk - lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("bonjour!"); - assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); - lfsr_file_close(&lfs, &d) => 0; - - // reopen a - lfsr_file_close(&lfs, &a) => 0; - lfsr_file_open(&lfs, &a, "jello", - LFS_O_WRONLY - | ((FLUSH == 2) ? LFS_O_FLUSH : 0) - | ((SYNC == 2) ? LFS_O_SYNC : 0) - | LFS_O_DESYNC) => 0; - // rewrite b - lfsr_file_rewind(&lfs, &b) => 0; - lfsr_file_write(&lfs, &b, "ohayo!", strlen("ohayo!")) - => strlen("ohayo!"); - - // should immediately show up in c - lfsr_file_rewind(&lfs, &c) => 0; - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("ohayo!r!"); - assert(memcmp(rbuf, "ohayo!r!", strlen("ohayo!r!")) == 0); - // and on disk - lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("ohayo!r!"); - assert(memcmp(rbuf, "ohayo!r!", strlen("ohayo!r!")) == 0); - lfsr_file_close(&lfs, &d) => 0; - - // sync a - lfsr_file_sync(&lfs, &a) => 0; - - // c should revert to a's contents - lfsr_file_rewind(&lfs, &c) => 0; - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("bonjour!"); - assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); - // and on disk - lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("bonjour!"); - assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); - lfsr_file_close(&lfs, &d) => 0; - - // rewrite a - lfsr_file_rewind(&lfs, &a) => 0; lfsr_file_write(&lfs, &a, "zdrasti!", strlen("zdrasti!")) => strlen("zdrasti!"); - // should immediately show up in c + // c should still have a's contents lfsr_file_rewind(&lfs, &c) => 0; - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("zdrasti!"); - assert(memcmp(rbuf, "zdrasti!", strlen("zdrasti!")) == 0); + lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => 0; // and on disk lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("zdrasti!"); - assert(memcmp(rbuf, "zdrasti!", strlen("zdrasti!")) == 0); + lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => 0; lfsr_file_close(&lfs, &d) => 0; - // desync a - lfsr_file_desync(&lfs, &a) => 0; // rewrite b lfsr_file_rewind(&lfs, &b) => 0; lfsr_file_write(&lfs, &b, "annyeong!", strlen("annyeong!")) @@ -2681,9 +2636,12 @@ code = ''' assert(memcmp(rbuf, "zdrasti!", strlen("zdrasti!")) == 0); lfsr_file_close(&lfs, &d) => 0; - // lets rewrite a one last time + // lets rewrite a and b one last time lfsr_file_rewind(&lfs, &a) => 0; - lfsr_file_write(&lfs, &a, "czesc!", strlen("czesc!")) + lfsr_file_write(&lfs, &a, "moshimoshi!", strlen("moshimoshi!")) + => strlen("moshimoshi!"); + lfsr_file_rewind(&lfs, &b) => 0; + lfsr_file_write(&lfs, &b, "czesc!", strlen("czesc!")) => strlen("czesc!"); // should immediately show up in c @@ -2700,7 +2658,7 @@ code = ''' lfsr_file_close(&lfs, &a) => 0; lfsr_file_close(&lfs, &b) => 0; - // should still have a + // should still have b lfsr_file_rewind(&lfs, &c) => 0; lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("czesc!i!"); assert(memcmp(rbuf, "czesc!i!", strlen("czesc!i!")) == 0); @@ -3063,7 +3021,7 @@ defines.R = 4 # SYNC=0 => no sync, readers not updated # SYNC=1 => sync via lfsr_file_sync # SYNC=2 => sync via LFS_O_SYNC -defines.SYNC = [0, 1, 2] +defines.SYNC = [0, 1] # FLUSH=0 => no flush # FLUSH=1 => flush via lfsr_file_flush # FLUSH=2 => flush via LFS_O_FLUSH @@ -3156,7 +3114,7 @@ defines.R = 4 # SYNC=0 => no sync, readers not updated # SYNC=1 => sync via lfsr_file_sync # SYNC=2 => sync via LFS_O_SYNC -defines.SYNC = [0, 1, 2] +defines.SYNC = [0, 1] # FLUSH=0 => no flush # FLUSH=1 => flush via lfsr_file_flush # FLUSH=2 => flush via LFS_O_FLUSH @@ -3451,7 +3409,7 @@ defines.RW = 4 # SYNC=0 => no sync, readers not updated # SYNC=1 => sync via lfsr_file_sync # SYNC=2 => sync via LFS_O_SYNC -defines.SYNC = [0, 1, 2] +defines.SYNC = [0, 1] # FLUSH=0 => no flush # FLUSH=1 => flush via lfsr_file_flush # FLUSH=2 => flush via LFS_O_FLUSH @@ -3559,7 +3517,7 @@ defines.RW = 4 # SYNC=0 => no sync, readers not updated # SYNC=1 => sync via lfsr_file_sync # SYNC=2 => sync via LFS_O_SYNC -defines.SYNC = [0, 1, 2] +defines.SYNC = [0, 1] # FLUSH=0 => no flush # FLUSH=1 => flush via lfsr_file_flush # FLUSH=2 => flush via LFS_O_FLUSH @@ -4344,7 +4302,7 @@ code = ''' # SYNC=1 => sync via lfsr_file_sync # SYNC=2 => sync via LFS_O_SYNC # SYNC=3 => sync via LFS_M_SYNC -defines.SYNC = [2, 3] +defines.SYNC = [2] # FLUSH=0 => no flush # FLUSH=1 => flush via lfsr_file_flush # FLUSH=2 => flush via LFS_O_FLUSH @@ -4360,7 +4318,7 @@ code = ''' CFG) => 0; // a - desynced writer - // b - writer + // b - synced writer // c - reader kept open, recvs updates from a // d - reader kept closed, checks disk state lfsr_file_t a; @@ -4368,66 +4326,42 @@ code = ''' lfsr_file_t c; lfsr_file_t d; uint8_t rbuf[256]; - // LFS_O_SYNC/LFS_M_SYNC should immediately create the file lfsr_file_open(&lfs, &a, "jello", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL | ((FLUSH == 2) ? LFS_O_FLUSH : 0) - | ((SYNC == 2) ? LFS_O_SYNC : 0) | LFS_O_DESYNC) => 0; - struct lfs_info info; - lfsr_stat(&lfs, "jello", &info) => 0; - assert(strcmp(info.name, "jello") == 0); - assert(info.type == LFS_TYPE_REG); - assert(info.size == 0); - // create the other files lfsr_file_open(&lfs, &b, "jello", LFS_O_WRONLY + | LFS_O_CREAT + | LFS_O_EXCL | ((FLUSH == 2) ? LFS_O_FLUSH : 0) | ((SYNC == 2) ? LFS_O_SYNC : 0)) => 0; lfsr_file_open(&lfs, &c, "jello", LFS_O_RDONLY) => 0; - // write to b - lfsr_file_write(&lfs, &b, "hello!", strlen("hello!")) + // write to a + lfsr_file_write(&lfs, &a, "hello!", strlen("hello!")) => strlen("hello!"); - - // our write should show up in c - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("hello!"); - assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); - // and on disk - lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("hello!"); - assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); - lfsr_file_close(&lfs, &d) => 0; - - // sync a - lfsr_file_sync(&lfs, &a) => 0; - - // c should still have b, this may be surprising, but the implicit - // sync in open+O_CREAT clears the desync flag - lfsr_file_rewind(&lfs, &c) => 0; - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("hello!"); - assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); - // and on disk - lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("hello!"); - assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); - lfsr_file_close(&lfs, &d) => 0; - - // reopen a - lfsr_file_close(&lfs, &a) => 0; - lfsr_file_open(&lfs, &a, "jello", - LFS_O_WRONLY - | ((FLUSH == 2) ? LFS_O_FLUSH : 0) - | ((SYNC == 2) ? LFS_O_SYNC : 0) - | LFS_O_DESYNC) => 0; - // rewrite b - lfsr_file_rewind(&lfs, &b) => 0; + // write to b lfsr_file_write(&lfs, &b, "bonjour!", strlen("bonjour!")) => strlen("bonjour!"); - // should immediately show up in c + // our write should show up in c + lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("bonjour!"); + assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); + // and on disk + lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; + lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("bonjour!"); + assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); + lfsr_file_close(&lfs, &d) => 0; + + // resync a + lfsr_file_resync(&lfs, &a) => 0; + // sync a + lfsr_file_sync(&lfs, &a) => 0; + + // c should still have b's contents lfsr_file_rewind(&lfs, &c) => 0; lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("bonjour!"); assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); @@ -4437,26 +4371,24 @@ code = ''' assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); lfsr_file_close(&lfs, &d) => 0; - // sync a - lfsr_file_sync(&lfs, &a) => 0; - - // c should revert to a's contents - lfsr_file_rewind(&lfs, &c) => 0; - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("hello!"); - assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); - // and on disk - lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("hello!"); - assert(memcmp(rbuf, "hello!", strlen("hello!")) == 0); - lfsr_file_close(&lfs, &d) => 0; - - // reopen a + // reopen a with LFS_O_TRUNC lfsr_file_close(&lfs, &a) => 0; lfsr_file_open(&lfs, &a, "jello", LFS_O_WRONLY + | LFS_O_TRUNC | ((FLUSH == 2) ? LFS_O_FLUSH : 0) - | ((SYNC == 2) ? LFS_O_SYNC : 0) | LFS_O_DESYNC) => 0; + + // c should still have b's contents + lfsr_file_rewind(&lfs, &c) => 0; + lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("bonjour!"); + assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); + // and on disk + lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; + lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("bonjour!"); + assert(memcmp(rbuf, "bonjour!", strlen("bonjour!")) == 0); + lfsr_file_close(&lfs, &d) => 0; + // rewrite b lfsr_file_rewind(&lfs, &b) => 0; lfsr_file_write(&lfs, &b, "ohayo!", strlen("ohayo!")) @@ -4464,12 +4396,12 @@ code = ''' // should immediately show up in c lfsr_file_rewind(&lfs, &c) => 0; - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("ohayo!"); - assert(memcmp(rbuf, "ohayo!", strlen("ohayo!")) == 0); + lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("ohayo!r!"); + assert(memcmp(rbuf, "ohayo!r!", strlen("ohayo!r!")) == 0); // and on disk lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("ohayo!"); - assert(memcmp(rbuf, "ohayo!", strlen("ohayo!")) == 0); + lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("ohayo!r!"); + assert(memcmp(rbuf, "ohayo!r!", strlen("ohayo!r!")) == 0); lfsr_file_close(&lfs, &d) => 0; // resync a @@ -4477,49 +4409,38 @@ code = ''' // sync a lfsr_file_sync(&lfs, &a) => 0; - // c should still show b's changes + // c should still have b's contents lfsr_file_rewind(&lfs, &c) => 0; - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("ohayo!"); - assert(memcmp(rbuf, "ohayo!", strlen("ohayo!")) == 0); + lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("ohayo!r!"); + assert(memcmp(rbuf, "ohayo!r!", strlen("ohayo!r!")) == 0); // and on disk lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("ohayo!"); - assert(memcmp(rbuf, "ohayo!", strlen("ohayo!")) == 0); + lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("ohayo!r!"); + assert(memcmp(rbuf, "ohayo!r!", strlen("ohayo!r!")) == 0); lfsr_file_close(&lfs, &d) => 0; - // desync a - lfsr_file_desync(&lfs, &a) => 0; - // rewrite b - lfsr_file_rewind(&lfs, &b) => 0; - lfsr_file_write(&lfs, &b, "zdrasti!", strlen("zdrasti!")) + // reopen LFS_O_WRONLY and rewrite a + lfsr_file_close(&lfs, &a) => 0; + lfsr_file_open(&lfs, &a, "jello", + LFS_O_WRONLY + | ((FLUSH == 2) ? LFS_O_FLUSH : 0) + | LFS_O_DESYNC) => 0; + lfsr_file_write(&lfs, &a, "zdrasti!", strlen("zdrasti!")) => strlen("zdrasti!"); - // should immediately show up in c + // c should still have b's contents lfsr_file_rewind(&lfs, &c) => 0; - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("zdrasti!"); - assert(memcmp(rbuf, "zdrasti!", strlen("zdrasti!")) == 0); + lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("ohayo!r!"); + assert(memcmp(rbuf, "ohayo!r!", strlen("ohayo!r!")) == 0); // and on disk lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("zdrasti!"); - assert(memcmp(rbuf, "zdrasti!", strlen("zdrasti!")) == 0); + lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("ohayo!r!"); + assert(memcmp(rbuf, "ohayo!r!", strlen("ohayo!r!")) == 0); lfsr_file_close(&lfs, &d) => 0; - // sync a - lfsr_file_sync(&lfs, &a) => 0; - - // c should revert to a's contents - lfsr_file_rewind(&lfs, &c) => 0; - lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("ohayo!"); - assert(memcmp(rbuf, "ohayo!", strlen("ohayo!")) == 0); - // and on disk - lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; - lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("ohayo!"); - assert(memcmp(rbuf, "ohayo!", strlen("ohayo!")) == 0); - lfsr_file_close(&lfs, &d) => 0; - - // rewrite a - lfsr_file_rewind(&lfs, &a) => 0; - lfsr_file_write(&lfs, &a, "annyeong!", strlen("annyeong!")) + // rewrite b + lfsr_file_rewind(&lfs, &b) => 0; + lfsr_file_write(&lfs, &b, "annyeong!", strlen("annyeong!")) => strlen("annyeong!"); // should immediately show up in c @@ -4532,14 +4453,32 @@ code = ''' assert(memcmp(rbuf, "annyeong!", strlen("annyeong!")) == 0); lfsr_file_close(&lfs, &d) => 0; - // desync b - lfsr_file_desync(&lfs, &b) => 0; - // resync b - lfsr_file_resync(&lfs, &b) => 0; - // rewrite b + // resync a + lfsr_file_resync(&lfs, &a) => 0; + // sync a + lfsr_file_sync(&lfs, &a) => 0; + + // c should still have b's contents + lfsr_file_rewind(&lfs, &c) => 0; + lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("annyeong!"); + assert(memcmp(rbuf, "annyeong!", strlen("annyeong!")) == 0); + // and on disk + lfsr_file_open(&lfs, &d, "jello", LFS_O_RDONLY) => 0; + lfsr_file_read(&lfs, &d, rbuf, sizeof(rbuf)) => strlen("annyeong!"); + assert(memcmp(rbuf, "annyeong!", strlen("annyeong!")) == 0); + lfsr_file_close(&lfs, &d) => 0; + + // desync a + lfsr_file_desync(&lfs, &a) => 0; + // lets rewrite a and b one last time + lfsr_file_rewind(&lfs, &a) => 0; + lfsr_file_write(&lfs, &a, "moshimoshi!", strlen("moshimoshi!")) + => strlen("moshimoshi!"); lfsr_file_rewind(&lfs, &b) => 0; lfsr_file_write(&lfs, &b, "czesc!", strlen("czesc!")) => strlen("czesc!"); + // resync a + lfsr_file_resync(&lfs, &a) => 0; // should immediately show up in c lfsr_file_rewind(&lfs, &c) => 0; @@ -4551,12 +4490,11 @@ code = ''' assert(memcmp(rbuf, "czesc!ng!", strlen("czesc!ng!")) == 0); lfsr_file_close(&lfs, &d) => 0; - // close b - lfsr_file_close(&lfs, &b) => 0; - // close a + // close a and b lfsr_file_close(&lfs, &a) => 0; + lfsr_file_close(&lfs, &b) => 0; - // c should still show b's changes + // should still have b lfsr_file_rewind(&lfs, &c) => 0; lfsr_file_read(&lfs, &c, rbuf, sizeof(rbuf)) => strlen("czesc!ng!"); assert(memcmp(rbuf, "czesc!ng!", strlen("czesc!ng!")) == 0); @@ -4900,7 +4838,7 @@ defines.R = 4 # SYNC=0 => no sync, readers not updated # SYNC=1 => sync via lfsr_file_sync # SYNC=2 => sync via LFS_O_SYNC -defines.SYNC = [0, 1, 2] +defines.SYNC = [0, 1] # FLUSH=0 => no flush # FLUSH=1 => flush via lfsr_file_flush # FLUSH=2 => flush via LFS_O_FLUSH