Reworked stickynote API, exposed LFS_TYPE_STICKYNOTE to users
This adds the LFS_TYPE_STICKYNOTE type, allowing users to interact with
stickynotes as long as they aren't orphaned.
This hopefully solves the long-standing mess that was the LFS_O_EXCL
API.
---
As for what I mean by orphaned vs non-orphaned stickynotes:
Non-orphaned stickynotes represent files that have been "created" (via
LFS_O_CREAT), but not "committed" (via sync/close). You can still close
and convert the stickynote to a reg file, so these aren't orphans. These
are also called "uncreated" files in some parts of the codebase:
- open+O_CREAT -> non-orphaned stickynote (uncreated file)
Orphaned stickynotes are possible by either removing an open file, or
desyncing a file before sync/close. These are still invisible to the
user and will be eventually cleaned up after the last file handle is
closed:
- open+remove -> orphaned stickynote (zombied file)
- open+O_CREAT+desync+close -> orphaned stickynote (orphaned file)
Desynced files are a bit special. Even though they technically aren't
orphaned, they also behave like orphaned file handles:
- open+O_CREAT+close -> orphaned stickynote (desynced file)
The idea is this mimics the state of files post-close, and allows for
some tricks like using a desync file as a temporary file with no
observable effects on the filesystem.
---
The motivation for this comes from staring at the LFS_O_EXCL API for too
long and realizing the problem is that littlefs's API contradicts itself
when it comes to whether or not uncreated files exist.
This solution is to consistently treat uncreated files as though they
exist (the alternative would make LFS_O_EXCL pretty much useless), but I
really didn't want to do this as having what appears to be normal files
disappear after powerloss risks confusion.
The compromise here is to give these files a special type, repurposing
the internal LFS_TAG_STICKYNOTE, which hopefully hints to the user these
won't behave like normal files.
If the user is more interested in POSIX compatibility, they can always
map these to either LFS_TYPE_REG or LFS_ERR_NOENT, whichever they think
is the least confusing.
As a quirk of littlefs's API, stickynotes should never actually contain
any data, and will always have size 0.
However they can have custom attributes assigned now (which is I guess
ok? also TODO should probably test this).
---
The implementation right now is a bit naive, I mostly just wanted to get
the tests working again in this new model. It may be possible to claw
back some of this code cost:
code stack ctx
before: 35740 2440 640
after: 35952 (+0.6%) 2440 (+0.0%) 640 (+0.0%)
This commit is contained in:
+967
-423
File diff suppressed because it is too large
Load Diff
+380
-190
@@ -3548,11 +3548,12 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -3639,27 +3640,25 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = false;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
lfs_size_t j = sim_file_count;
|
||||
sim_files[j] = malloc(sizeof(sim_file_t));
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
|
||||
// open the actual file
|
||||
char name[256];
|
||||
@@ -3668,24 +3667,58 @@ code = '''
|
||||
LFS_O_RDWR | LFS_O_CREAT);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
free(sim_files[j]);
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
sim_file_count++;
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfs_ssize_t d = lfsr_file_write(&lfs, &sim_files[j]->file,
|
||||
wbuf, SIZE);
|
||||
assert(d == SIZE || d == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
if (d == LFS_ERR_NOSPC) {
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
} else if (op == 1) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -3697,44 +3730,12 @@ code = '''
|
||||
// choose a random seed
|
||||
uint32_t wprng = TEST_PRNG(&prng);
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
sim_files[k]->prng = wprng;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfs_ssize_t d = lfsr_file_write(&lfs, &sim_files[j]->file,
|
||||
wbuf, SIZE);
|
||||
@@ -3751,6 +3752,31 @@ code = '''
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close a file?
|
||||
} else if (op == 2) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -3758,6 +3784,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
bool sticky = sim_files[j]->sticky;
|
||||
bool zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -3765,12 +3794,41 @@ code = '''
|
||||
// close the file without affected disk
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
// clobber closed files to try to catch lingering references
|
||||
memset(&sim_files[j]->file, 0xcc, sizeof(lfsr_file_t));
|
||||
|
||||
// remove from list
|
||||
free(sim_files[j]);
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -3780,20 +3838,6 @@ code = '''
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
||||
lfs_size_t x = sim[j];
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
sim_size -= 1;
|
||||
|
||||
// mark any related sim files as zombied
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x) {
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
@@ -3803,6 +3847,22 @@ code = '''
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
|
||||
// mark any related sim files as zombied
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x) {
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// rename a file?
|
||||
} else if (op == 4) {
|
||||
if (sim_size == 0) {
|
||||
@@ -3814,6 +3874,18 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
int err = lfsr_rename(&lfs, old_name, new_name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
|
||||
// update our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
@@ -3825,12 +3897,15 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -3838,6 +3913,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
@@ -3846,8 +3923,11 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3864,17 +3944,6 @@ code = '''
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
int err = lfsr_rename(&lfs, old_name, new_name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3885,8 +3954,13 @@ code = '''
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, name, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
lfsr_dir_t dir;
|
||||
@@ -3905,8 +3979,13 @@ code = '''
|
||||
sprintf(name, "batman%03x", sim[j]);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
@@ -3924,14 +4003,19 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfs_ssize_t d = lfsr_file_read(&lfs, &file, rbuf, SIZE);
|
||||
assert(d == SIZE
|
||||
|| (d == LFS_ERR_CORRUPT && (METHOD == 2 || METHOD == 3)));
|
||||
if (d == LFS_ERR_CORRUPT) {
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
goto corrupt_mounted;
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfs_ssize_t d = lfsr_file_read(&lfs, &file, rbuf, SIZE);
|
||||
assert(d == SIZE
|
||||
|| (d == LFS_ERR_CORRUPT
|
||||
&& (METHOD == 2 || METHOD == 3)));
|
||||
if (d == LFS_ERR_CORRUPT) {
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
|
||||
@@ -3947,7 +4031,8 @@ code = '''
|
||||
uint8_t rbuf[SIZE];
|
||||
lfs_ssize_t d = lfsr_file_read(&lfs, &sim_files[j]->file, rbuf, SIZE);
|
||||
assert(d == SIZE
|
||||
|| (d == LFS_ERR_CORRUPT && (METHOD == 2 || METHOD == 3)));
|
||||
|| (d == LFS_ERR_CORRUPT
|
||||
&& (METHOD == 2 || METHOD == 3)));
|
||||
if (d == LFS_ERR_CORRUPT) {
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
@@ -3958,6 +4043,7 @@ corrupt_mounted:;
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
@@ -4054,12 +4140,13 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
bool *sim_isdirs = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -4146,30 +4233,28 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = true;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
if (sim_isdirs[j]) {
|
||||
goto nonsense;
|
||||
}
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
lfs_size_t j = sim_file_count;
|
||||
sim_files[j] = malloc(sizeof(sim_file_t));
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
|
||||
// open the actual file
|
||||
char name[256];
|
||||
@@ -4178,24 +4263,61 @@ code = '''
|
||||
LFS_O_RDWR | LFS_O_CREAT);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
free(sim_files[j]);
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
sim_file_count++;
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfs_ssize_t d = lfsr_file_write(&lfs, &sim_files[j]->file,
|
||||
wbuf, SIZE);
|
||||
assert(d == SIZE || d == LFS_ERR_NOSPC);
|
||||
if (d == LFS_ERR_NOSPC) {
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
} else if (op == 1) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -4207,47 +4329,12 @@ code = '''
|
||||
// choose a random seed
|
||||
uint32_t wprng = TEST_PRNG(&prng);
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
sim_files[k]->prng = wprng;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfs_ssize_t d = lfsr_file_write(&lfs, &sim_files[j]->file,
|
||||
wbuf, SIZE);
|
||||
@@ -4264,6 +4351,31 @@ code = '''
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close a file?
|
||||
} else if (op == 2) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -4271,6 +4383,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
lfs_size_t sticky = sim_files[j]->sticky;
|
||||
lfs_size_t zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -4278,12 +4393,43 @@ code = '''
|
||||
// close the file without affected disk
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
// clobber closed files to try to catch lingering references
|
||||
memset(&sim_files[j]->file, 0xcc, sizeof(lfsr_file_t));
|
||||
|
||||
// remove from list
|
||||
free(sim_files[j]);
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[k], &sim_isdirs[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -4293,11 +4439,22 @@ code = '''
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
||||
lfs_size_t x = sim[j];
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
int err = lfsr_remove(&lfs, name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
@@ -4309,15 +4466,6 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
int err = lfsr_remove(&lfs, name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
|
||||
// rename a file?
|
||||
} else if (op == 4) {
|
||||
if (sim_size == 0) {
|
||||
@@ -4329,31 +4477,55 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool isdir = sim_isdirs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
bool dir = sim_isdirs[j];
|
||||
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= y) {
|
||||
// renaming and replacing
|
||||
if (k < sim_size && sim[k] == y && x != y) {
|
||||
// type mismatch?
|
||||
if (sim_isdirs[k] != dir) {
|
||||
goto nonsense;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
int err = lfsr_rename(&lfs, old_name, new_name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
|
||||
// update our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= y) {
|
||||
// renaming and replacing
|
||||
if (k < sim_size && sim[k] == y && x != y) {
|
||||
// type mismatch?
|
||||
if (sim_isdirs[k] != isdir) {
|
||||
goto nonsense;
|
||||
}
|
||||
|
||||
// delete the original entry
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky/dir
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -4361,6 +4533,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
@@ -4371,11 +4545,14 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = isdir;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -4393,52 +4570,21 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
int err = lfsr_rename(&lfs, old_name, new_name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
|
||||
// toss a directory into the mix
|
||||
} else if (op == 5) {
|
||||
// choose a pseudo-random number
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// insert into our sim, use negative numbers for dirs
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
goto nonsense;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = 0;
|
||||
sim_isdirs[k] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// mark any related sim files as zombied
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x) {
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// make the directory
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
@@ -4447,6 +4593,33 @@ code = '''
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = 0;
|
||||
sim_isdirs[k] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// mark any related sim files as zombied
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x) {
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4459,6 +4632,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -4483,6 +4660,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -4512,14 +4693,19 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfs_ssize_t d = lfsr_file_read(&lfs, &file, rbuf, SIZE);
|
||||
assert(d == SIZE
|
||||
|| (d == LFS_ERR_CORRUPT && (METHOD == 2 || METHOD == 3)));
|
||||
if (d == LFS_ERR_CORRUPT) {
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
goto corrupt_mounted;
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfs_ssize_t d = lfsr_file_read(&lfs, &file, rbuf, SIZE);
|
||||
assert(d == SIZE
|
||||
|| (d == LFS_ERR_CORRUPT
|
||||
&& (METHOD == 2 || METHOD == 3)));
|
||||
if (d == LFS_ERR_CORRUPT) {
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
}
|
||||
@@ -4536,7 +4722,8 @@ code = '''
|
||||
uint8_t rbuf[SIZE];
|
||||
lfs_ssize_t d = lfsr_file_read(&lfs, &sim_files[j]->file, rbuf, SIZE);
|
||||
assert(d == SIZE
|
||||
|| (d == LFS_ERR_CORRUPT && (METHOD == 2 || METHOD == 3)));
|
||||
|| (d == LFS_ERR_CORRUPT
|
||||
&& (METHOD == 2 || METHOD == 3)));
|
||||
if (d == LFS_ERR_CORRUPT) {
|
||||
goto corrupt_mounted;
|
||||
}
|
||||
@@ -4547,6 +4734,8 @@ corrupt_mounted:;
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
free(sim_isdirs);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
@@ -4554,6 +4743,7 @@ corrupt_mounted:;
|
||||
}
|
||||
free(sim_files);
|
||||
lfsr_unmount(&lfs) => 0;
|
||||
|
||||
// how many errors did we survive?
|
||||
printf("survived %d block errors!\n", (int)(i/PERIOD));
|
||||
'''
|
||||
|
||||
+365
-180
@@ -754,11 +754,12 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -781,27 +782,25 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = false;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
lfs_size_t j = sim_file_count;
|
||||
sim_files[j] = malloc(sizeof(sim_file_t));
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
|
||||
// open the actual file
|
||||
char name[256];
|
||||
@@ -810,24 +809,58 @@ code = '''
|
||||
LFS_O_RDWR | LFS_O_CREAT);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
free(sim_files[j]);
|
||||
goto dead;
|
||||
}
|
||||
sim_file_count++;
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfs_ssize_t d = lfsr_file_write(&lfs, &sim_files[j]->file,
|
||||
wbuf, SIZE);
|
||||
assert(d == SIZE || d == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
if (d == LFS_ERR_NOSPC) {
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
goto dead;
|
||||
}
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
} else if (op == 1) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -839,44 +872,12 @@ code = '''
|
||||
// choose a random seed
|
||||
uint32_t wprng = TEST_PRNG(&prng);
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
sim_files[k]->prng = wprng;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfs_ssize_t d = lfsr_file_write(&lfs, &sim_files[j]->file,
|
||||
wbuf, SIZE);
|
||||
@@ -891,6 +892,31 @@ code = '''
|
||||
goto dead;
|
||||
}
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close a file?
|
||||
} else if (op == 2) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -898,6 +924,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
bool sticky = sim_files[j]->sticky;
|
||||
bool zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -905,12 +934,41 @@ code = '''
|
||||
// close the file without affected disk
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
// clobber closed files to try to catch lingering references
|
||||
memset(&sim_files[j]->file, 0xcc, sizeof(lfsr_file_t));
|
||||
|
||||
// remove from list
|
||||
free(sim_files[j]);
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -920,20 +978,6 @@ code = '''
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
||||
lfs_size_t x = sim[j];
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
sim_size -= 1;
|
||||
|
||||
// mark any related sim files as zombied
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x) {
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
@@ -943,6 +987,22 @@ code = '''
|
||||
goto dead;
|
||||
}
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
|
||||
// mark any related sim files as zombied
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x) {
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// rename a file?
|
||||
} else if (op == 4) {
|
||||
if (sim_size == 0) {
|
||||
@@ -954,6 +1014,18 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
int err = lfsr_rename(&lfs, old_name, new_name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto dead;
|
||||
}
|
||||
|
||||
// update our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
@@ -965,12 +1037,15 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -978,6 +1053,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
@@ -986,8 +1063,11 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1004,17 +1084,6 @@ code = '''
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
int err = lfsr_rename(&lfs, old_name, new_name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto dead;
|
||||
}
|
||||
}
|
||||
|
||||
// check our simulation every power-of-2 ops
|
||||
@@ -1026,8 +1095,13 @@ code = '''
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, name, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
lfsr_dir_t dir;
|
||||
@@ -1046,8 +1120,13 @@ code = '''
|
||||
sprintf(name, "batman%03x", sim[j]);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
@@ -1065,8 +1144,12 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
|
||||
@@ -1080,8 +1163,8 @@ code = '''
|
||||
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t rbuf[SIZE];
|
||||
lfsr_file_read(&lfs, &sim_files[j]->file,
|
||||
rbuf, SIZE) => SIZE;
|
||||
lfsr_file_read(&lfs, &sim_files[j]->file, rbuf, SIZE)
|
||||
=> SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
}
|
||||
@@ -1091,6 +1174,7 @@ code = '''
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
@@ -1176,12 +1260,13 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
bool *sim_isdirs = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -1204,30 +1289,28 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = true;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
if (sim_isdirs[j]) {
|
||||
goto nonsense;
|
||||
}
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
lfs_size_t j = sim_file_count;
|
||||
sim_files[j] = malloc(sizeof(sim_file_t));
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
|
||||
// open the actual file
|
||||
char name[256];
|
||||
@@ -1236,24 +1319,61 @@ code = '''
|
||||
LFS_O_RDWR | LFS_O_CREAT);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
free(sim_files[j]);
|
||||
goto dead;
|
||||
}
|
||||
sim_file_count++;
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfs_ssize_t d = lfsr_file_write(&lfs, &sim_files[j]->file,
|
||||
wbuf, SIZE);
|
||||
assert(d == SIZE || d == LFS_ERR_NOSPC);
|
||||
if (d == LFS_ERR_NOSPC) {
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
goto dead;
|
||||
}
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
} else if (op == 1) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -1265,47 +1385,12 @@ code = '''
|
||||
// choose a random seed
|
||||
uint32_t wprng = TEST_PRNG(&prng);
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
sim_files[k]->prng = wprng;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfs_ssize_t d = lfsr_file_write(&lfs, &sim_files[j]->file,
|
||||
wbuf, SIZE);
|
||||
@@ -1320,6 +1405,31 @@ code = '''
|
||||
goto dead;
|
||||
}
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close a file?
|
||||
} else if (op == 2) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -1327,6 +1437,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
lfs_size_t sticky = sim_files[j]->sticky;
|
||||
lfs_size_t zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -1334,12 +1447,43 @@ code = '''
|
||||
// close the file without affected disk
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
// clobber closed files to try to catch lingering references
|
||||
memset(&sim_files[j]->file, 0xcc, sizeof(lfsr_file_t));
|
||||
|
||||
// remove from list
|
||||
free(sim_files[j]);
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[k], &sim_isdirs[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -1349,11 +1493,22 @@ code = '''
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
||||
lfs_size_t x = sim[j];
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
int err = lfsr_remove(&lfs, name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto dead;
|
||||
}
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
@@ -1365,15 +1520,6 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
int err = lfsr_remove(&lfs, name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto dead;
|
||||
}
|
||||
|
||||
// rename a file?
|
||||
} else if (op == 4) {
|
||||
if (sim_size == 0) {
|
||||
@@ -1385,31 +1531,55 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool isdir = sim_isdirs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
bool dir = sim_isdirs[j];
|
||||
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= y) {
|
||||
// renaming and replacing
|
||||
if (k < sim_size && sim[k] == y && x != y) {
|
||||
// type mismatch?
|
||||
if (sim_isdirs[k] != dir) {
|
||||
goto nonsense;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
int err = lfsr_rename(&lfs, old_name, new_name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto dead;
|
||||
}
|
||||
|
||||
// update our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= y) {
|
||||
// renaming and replacing
|
||||
if (k < sim_size && sim[k] == y && x != y) {
|
||||
// type mismatch?
|
||||
if (sim_isdirs[k] != isdir) {
|
||||
goto nonsense;
|
||||
}
|
||||
|
||||
// delete the original entry
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky/dir
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -1417,6 +1587,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
@@ -1427,11 +1599,14 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = isdir;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1449,52 +1624,21 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
int err = lfsr_rename(&lfs, old_name, new_name);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto dead;
|
||||
}
|
||||
|
||||
// toss a directory into the mix
|
||||
} else if (op == 5) {
|
||||
// choose a pseudo-random number
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// insert into our sim, use negative numbers for dirs
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
goto nonsense;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = 0;
|
||||
sim_isdirs[k] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// mark any related sim files as zombied
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x) {
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// make the directory
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
@@ -1503,6 +1647,33 @@ code = '''
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
goto dead;
|
||||
}
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = 0;
|
||||
sim_isdirs[k] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// mark any related sim files as zombied
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x) {
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check our simulation every power-of-2 ops
|
||||
@@ -1516,6 +1687,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -1540,6 +1715,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -1569,8 +1748,12 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
}
|
||||
@@ -1596,6 +1779,8 @@ code = '''
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
free(sim_isdirs);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
|
||||
+3194
-359
File diff suppressed because it is too large
Load Diff
+320
-142
@@ -2838,11 +2838,12 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -2865,28 +2866,25 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = false;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
lfs_size_t j = sim_file_count;
|
||||
sim_files[j] = malloc(sizeof(sim_file_t));
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// open the actual file
|
||||
char name[256];
|
||||
@@ -2895,12 +2893,45 @@ code = '''
|
||||
LFS_O_RDWR | LFS_O_CREAT) => 0;
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE)
|
||||
=> SIZE;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
@@ -2914,26 +2945,27 @@ code = '''
|
||||
// choose a random seed
|
||||
uint32_t wprng = TEST_PRNG(&prng);
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
}
|
||||
if (sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2941,22 +2973,14 @@ code = '''
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// close a file?
|
||||
} else if (op == 2) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -2964,6 +2988,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
bool sticky = sim_files[j]->sticky;
|
||||
bool zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -2979,6 +3006,33 @@ code = '''
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -2988,11 +3042,18 @@ code = '''
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
||||
lfs_size_t x = sim[j];
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
|
||||
// mark any related sim files as zombied
|
||||
@@ -3002,11 +3063,6 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// rename a file?
|
||||
} else if (op == 4) {
|
||||
if (sim_size == 0) {
|
||||
@@ -3018,6 +3074,14 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
|
||||
// update our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
@@ -3029,12 +3093,15 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -3042,6 +3109,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
@@ -3050,8 +3119,11 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3068,13 +3140,6 @@ code = '''
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
}
|
||||
|
||||
// gc!
|
||||
@@ -3093,8 +3158,13 @@ code = '''
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, name, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
lfsr_dir_t dir;
|
||||
@@ -3113,8 +3183,13 @@ code = '''
|
||||
sprintf(name, "batman%03x", sim[j]);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
@@ -3132,8 +3207,12 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
|
||||
@@ -3154,6 +3233,7 @@ code = '''
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
@@ -3203,12 +3283,13 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
bool *sim_isdirs = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -3231,31 +3312,28 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = true;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
if (sim_isdirs[j]) {
|
||||
goto nonsense;
|
||||
}
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
lfs_size_t j = sim_file_count;
|
||||
sim_files[j] = malloc(sizeof(sim_file_t));
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// open the actual file
|
||||
char name[256];
|
||||
@@ -3264,12 +3342,48 @@ code = '''
|
||||
LFS_O_RDWR | LFS_O_CREAT) => 0;
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE)
|
||||
=> SIZE;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
@@ -3283,29 +3397,27 @@ code = '''
|
||||
// choose a random seed
|
||||
uint32_t wprng = TEST_PRNG(&prng);
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3313,22 +3425,14 @@ code = '''
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// close a file?
|
||||
} else if (op == 2) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -3336,6 +3440,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
lfs_size_t sticky = sim_files[j]->sticky;
|
||||
lfs_size_t zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -3351,6 +3458,35 @@ code = '''
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[k], &sim_isdirs[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -3360,11 +3496,18 @@ code = '''
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
||||
lfs_size_t x = sim[j];
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
@@ -3376,11 +3519,6 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// rename a file?
|
||||
} else if (op == 4) {
|
||||
if (sim_size == 0) {
|
||||
@@ -3392,31 +3530,51 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool isdir = sim_isdirs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
bool dir = sim_isdirs[j];
|
||||
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= y) {
|
||||
// renaming and replacing
|
||||
if (k < sim_size && sim[k] == y && x != y) {
|
||||
// type mismatch?
|
||||
if (sim_isdirs[k] != dir) {
|
||||
goto nonsense;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
|
||||
// update our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= y) {
|
||||
// renaming and replacing
|
||||
if (k < sim_size && sim[k] == y && x != y) {
|
||||
// type mismatch?
|
||||
if (sim_isdirs[k] != isdir) {
|
||||
goto nonsense;
|
||||
}
|
||||
|
||||
// delete the original entry
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky/dir
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -3424,6 +3582,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
@@ -3434,11 +3594,14 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = isdir;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3456,52 +3619,52 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
|
||||
// toss a directory into the mix
|
||||
} else if (op == 5) {
|
||||
// choose a pseudo-random number
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// insert into our sim, use negative numbers for dirs
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
goto nonsense;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = 0;
|
||||
sim_isdirs[k] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// make the directory
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_mkdir(&lfs, name) => 0;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = 0;
|
||||
sim_isdirs[k] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// mark any related sim files as zombied
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x) {
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// make the directory
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_mkdir(&lfs, name) => 0;
|
||||
}
|
||||
|
||||
// gc!
|
||||
@@ -3522,6 +3685,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -3546,6 +3713,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -3559,7 +3730,8 @@ code = '''
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", sim[j]);
|
||||
lfsr_file_t file;
|
||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => LFS_ERR_ISDIR;
|
||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY)
|
||||
=> LFS_ERR_ISDIR;
|
||||
|
||||
} else {
|
||||
char name[256];
|
||||
@@ -3574,8 +3746,12 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
}
|
||||
@@ -3597,6 +3773,8 @@ code = '''
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
free(sim_isdirs);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
|
||||
+225
-66
@@ -1273,11 +1273,12 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -1302,18 +1303,21 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng_) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = false;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng_);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
lfs_size_t j = sim_file_count;
|
||||
@@ -1331,7 +1335,7 @@ code = '''
|
||||
}
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
@@ -1349,11 +1353,35 @@ code = '''
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
} else if (op == 1) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -1388,23 +1416,13 @@ code = '''
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
}
|
||||
if (sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1412,8 +1430,10 @@ code = '''
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1425,6 +1445,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng_) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
bool sticky = sim_files[j]->sticky;
|
||||
bool zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -1432,12 +1455,41 @@ code = '''
|
||||
// close the file without affected disk
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
// clobber closed files to try to catch lingering references
|
||||
memset(&sim_files[j]->file, 0xcc, sizeof(lfsr_file_t));
|
||||
|
||||
// remove from list
|
||||
free(sim_files[j]);
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -1461,6 +1513,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
|
||||
// mark any related sim files as zombied
|
||||
@@ -1481,6 +1535,7 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng_) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
@@ -1503,12 +1558,15 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -1516,6 +1574,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
@@ -1524,8 +1584,11 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1591,8 +1654,13 @@ code = '''
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, name, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
lfsr_dir_t dir;
|
||||
@@ -1611,8 +1679,13 @@ code = '''
|
||||
sprintf(name, "batman%03x", sim[j]);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
@@ -1630,8 +1703,12 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
|
||||
@@ -1652,8 +1729,8 @@ code = '''
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
}
|
||||
@@ -1697,12 +1774,13 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
bool *sim_isdirs = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -1727,21 +1805,24 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng_) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = true;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
if (sim_isdirs[j]) {
|
||||
goto nonsense;
|
||||
}
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
wprng = TEST_PRNG(&prng_);
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
lfs_size_t j = sim_file_count;
|
||||
@@ -1759,7 +1840,7 @@ code = '''
|
||||
}
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
@@ -1777,11 +1858,38 @@ code = '''
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
} else if (op == 1) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -1816,26 +1924,13 @@ code = '''
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1843,8 +1938,10 @@ code = '''
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1856,6 +1953,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng_) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
lfs_size_t sticky = sim_files[j]->sticky;
|
||||
lfs_size_t zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -1863,12 +1963,43 @@ code = '''
|
||||
// close the file without affected disk
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
// clobber closed files to try to catch lingering references
|
||||
memset(&sim_files[j]->file, 0xcc, sizeof(lfsr_file_t));
|
||||
|
||||
// remove from list
|
||||
free(sim_files[j]);
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[k], &sim_isdirs[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -1892,6 +2023,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
@@ -1914,14 +2047,15 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng_) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool isdir = sim_isdirs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
bool dir = sim_isdirs[j];
|
||||
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= y) {
|
||||
// renaming and replacing
|
||||
if (k < sim_size && sim[k] == y && x != y) {
|
||||
// type mismatch?
|
||||
if (sim_isdirs[k] != isdir) {
|
||||
if (sim_isdirs[k] != dir) {
|
||||
goto nonsense;
|
||||
}
|
||||
}
|
||||
@@ -1950,14 +2084,18 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky/dir
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -1965,6 +2103,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
@@ -1975,11 +2115,14 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = isdir;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2021,7 +2164,7 @@ code = '''
|
||||
goto grow;
|
||||
}
|
||||
|
||||
// insert into our sim, use negative numbers for dirs
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// insert
|
||||
@@ -2029,6 +2172,8 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
@@ -2096,6 +2241,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -2120,6 +2269,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -2133,7 +2286,8 @@ code = '''
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", sim[j]);
|
||||
lfsr_file_t file;
|
||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => LFS_ERR_ISDIR;
|
||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY)
|
||||
=> LFS_ERR_ISDIR;
|
||||
|
||||
} else {
|
||||
char name[256];
|
||||
@@ -2148,8 +2302,12 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
}
|
||||
@@ -2171,8 +2329,9 @@ code = '''
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
free(sim_isdirs);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
}
|
||||
|
||||
+324
-142
@@ -552,11 +552,12 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -579,28 +580,25 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = false;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
lfs_size_t j = sim_file_count;
|
||||
sim_files[j] = malloc(sizeof(sim_file_t));
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// open the actual file
|
||||
char name[256];
|
||||
@@ -609,12 +607,45 @@ code = '''
|
||||
LFS_O_RDWR | LFS_O_CREAT) => 0;
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE)
|
||||
=> SIZE;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
@@ -628,26 +659,27 @@ code = '''
|
||||
// choose a random seed
|
||||
uint32_t wprng = TEST_PRNG(&prng);
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
}
|
||||
if (sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -655,22 +687,14 @@ code = '''
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// close a file?
|
||||
} else if (op == 2) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -678,6 +702,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
bool sticky = sim_files[j]->sticky;
|
||||
bool zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -685,12 +712,41 @@ code = '''
|
||||
// close the file without affected disk
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
// clobber closed files to try to catch lingering references
|
||||
memset(&sim_files[j]->file, 0xcc, sizeof(lfsr_file_t));
|
||||
|
||||
// remove from list
|
||||
free(sim_files[j]);
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -700,11 +756,18 @@ code = '''
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
||||
lfs_size_t x = sim[j];
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
|
||||
// mark any related sim files as zombied
|
||||
@@ -714,11 +777,6 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// rename a file?
|
||||
} else if (op == 4) {
|
||||
if (sim_size == 0) {
|
||||
@@ -730,6 +788,14 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
|
||||
// update our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
@@ -741,12 +807,15 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -754,6 +823,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
@@ -762,8 +833,11 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -780,13 +854,6 @@ code = '''
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -797,8 +864,13 @@ code = '''
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, name, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
lfsr_dir_t dir;
|
||||
@@ -817,8 +889,13 @@ code = '''
|
||||
sprintf(name, "batman%03x", sim[j]);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
@@ -836,8 +913,12 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
|
||||
@@ -858,6 +939,7 @@ code = '''
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
@@ -892,12 +974,13 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
bool *sim_isdirs = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -920,31 +1003,28 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = true;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
if (sim_isdirs[j]) {
|
||||
goto nonsense;
|
||||
}
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
lfs_size_t j = sim_file_count;
|
||||
sim_files[j] = malloc(sizeof(sim_file_t));
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// open the actual file
|
||||
char name[256];
|
||||
@@ -953,12 +1033,48 @@ code = '''
|
||||
LFS_O_RDWR | LFS_O_CREAT) => 0;
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE)
|
||||
=> SIZE;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
@@ -972,29 +1088,27 @@ code = '''
|
||||
// choose a random seed
|
||||
uint32_t wprng = TEST_PRNG(&prng);
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1002,22 +1116,14 @@ code = '''
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// close a file?
|
||||
} else if (op == 2) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -1025,6 +1131,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
lfs_size_t sticky = sim_files[j]->sticky;
|
||||
lfs_size_t zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -1032,12 +1141,43 @@ code = '''
|
||||
// close the file without affected disk
|
||||
lfsr_file_desync(&lfs, &sim_files[j]->file) => 0;
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
// clobber closed files to try to catch lingering references
|
||||
memset(&sim_files[j]->file, 0xcc, sizeof(lfsr_file_t));
|
||||
|
||||
// remove from list
|
||||
free(sim_files[j]);
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[k], &sim_isdirs[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -1047,11 +1187,18 @@ code = '''
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
||||
lfs_size_t x = sim[j];
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
@@ -1063,11 +1210,6 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// rename a file?
|
||||
} else if (op == 4) {
|
||||
if (sim_size == 0) {
|
||||
@@ -1079,31 +1221,51 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool isdir = sim_isdirs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
bool dir = sim_isdirs[j];
|
||||
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= y) {
|
||||
// renaming and replacing
|
||||
if (k < sim_size && sim[k] == y && x != y) {
|
||||
// type mismatch?
|
||||
if (sim_isdirs[k] != dir) {
|
||||
goto nonsense;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
|
||||
// update our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= y) {
|
||||
// renaming and replacing
|
||||
if (k < sim_size && sim[k] == y && x != y) {
|
||||
// type mismatch?
|
||||
if (sim_isdirs[k] != isdir) {
|
||||
goto nonsense;
|
||||
}
|
||||
|
||||
// delete the original entry
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky/dir
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -1111,6 +1273,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
@@ -1121,11 +1285,14 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = isdir;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1143,52 +1310,52 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
|
||||
// toss a directory into the mix
|
||||
} else if (op == 5) {
|
||||
// choose a pseudo-random number
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// insert into our sim, use negative numbers for dirs
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
goto nonsense;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = 0;
|
||||
sim_isdirs[k] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// make the directory
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_mkdir(&lfs, name) => 0;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = 0;
|
||||
sim_isdirs[k] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// mark any related sim files as zombied
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x) {
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// make the directory
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_mkdir(&lfs, name) => 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1201,6 +1368,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -1225,6 +1396,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -1238,7 +1413,8 @@ code = '''
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", sim[j]);
|
||||
lfsr_file_t file;
|
||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => LFS_ERR_ISDIR;
|
||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY)
|
||||
=> LFS_ERR_ISDIR;
|
||||
|
||||
} else {
|
||||
char name[256];
|
||||
@@ -1253,8 +1429,12 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
}
|
||||
@@ -1276,6 +1456,8 @@ code = '''
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
free(sim_isdirs);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
|
||||
+320
-142
@@ -8505,11 +8505,12 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -8541,28 +8542,25 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = false;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
lfs_size_t j = sim_file_count;
|
||||
sim_files[j] = malloc(sizeof(sim_file_t));
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// open the actual file
|
||||
char name[256];
|
||||
@@ -8571,12 +8569,45 @@ code = '''
|
||||
LFS_O_RDWR | LFS_O_CREAT) => 0;
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE)
|
||||
=> SIZE;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
@@ -8590,26 +8621,27 @@ code = '''
|
||||
// choose a random seed
|
||||
uint32_t wprng = TEST_PRNG(&prng);
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
}
|
||||
if (sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -8617,22 +8649,14 @@ code = '''
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// close a file?
|
||||
} else if (op == 2) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -8640,6 +8664,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
bool sticky = sim_files[j]->sticky;
|
||||
bool zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -8655,6 +8682,33 @@ code = '''
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -8664,11 +8718,18 @@ code = '''
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
||||
lfs_size_t x = sim[j];
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
|
||||
// mark any related sim files as zombied
|
||||
@@ -8678,11 +8739,6 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// rename a file?
|
||||
} else if (op == 4) {
|
||||
if (sim_size == 0) {
|
||||
@@ -8694,6 +8750,14 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
|
||||
// update our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
@@ -8705,12 +8769,15 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -8718,6 +8785,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
@@ -8726,8 +8795,11 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -8744,13 +8816,6 @@ code = '''
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
}
|
||||
|
||||
// step the traversal
|
||||
@@ -8774,8 +8839,13 @@ code = '''
|
||||
struct lfs_info info;
|
||||
lfsr_stat(&lfs, name, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
lfsr_dir_t dir;
|
||||
@@ -8794,8 +8864,13 @@ code = '''
|
||||
sprintf(name, "batman%03x", sim[j]);
|
||||
lfsr_dir_read(&lfs, &dir, &info) => 0;
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
}
|
||||
}
|
||||
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT;
|
||||
lfsr_dir_close(&lfs, &dir) => 0;
|
||||
@@ -8813,8 +8888,12 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
|
||||
@@ -8835,6 +8914,7 @@ code = '''
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
@@ -8876,12 +8956,13 @@ code = '''
|
||||
// set up a simulation to compare against
|
||||
lfs_size_t *sim = malloc(N*sizeof(lfs_size_t));
|
||||
uint32_t *sim_prngs = malloc(N*sizeof(uint32_t));
|
||||
bool *sim_isstickys = malloc(N*sizeof(bool));
|
||||
bool *sim_isdirs = malloc(N*sizeof(bool));
|
||||
lfs_size_t sim_size = 0;
|
||||
|
||||
typedef struct sim_file {
|
||||
lfs_size_t x;
|
||||
bool uncreat;
|
||||
bool sticky;
|
||||
bool zombie;
|
||||
uint32_t prng;
|
||||
lfsr_file_t file;
|
||||
@@ -8913,31 +8994,28 @@ code = '''
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// already exists?
|
||||
bool uncreat = true;
|
||||
bool exist = true;
|
||||
uint32_t wprng = 0;
|
||||
bool sticky = true;
|
||||
for (lfs_size_t j = 0; j < sim_size; j++) {
|
||||
if (sim[j] == x) {
|
||||
if (sim_isdirs[j]) {
|
||||
goto nonsense;
|
||||
}
|
||||
uncreat = false;
|
||||
exist = true;
|
||||
wprng = sim_prngs[j];
|
||||
sticky = sim_isstickys[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// choose a random seed if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist) {
|
||||
wprng = TEST_PRNG(&prng);
|
||||
sticky = true;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
lfs_size_t j = sim_file_count;
|
||||
sim_files[j] = malloc(sizeof(sim_file_t));
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->uncreat = uncreat;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// open the actual file
|
||||
char name[256];
|
||||
@@ -8946,12 +9024,48 @@ code = '''
|
||||
LFS_O_RDWR | LFS_O_CREAT) => 0;
|
||||
|
||||
// write some initial data if we don't exist
|
||||
if (uncreat) {
|
||||
if (!exist || sticky) {
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE)
|
||||
=> SIZE;
|
||||
}
|
||||
|
||||
// open in our sim
|
||||
sim_files[j]->x = x;
|
||||
sim_files[j]->sticky = sticky;
|
||||
sim_files[j]->zombie = false;
|
||||
sim_files[j]->prng = wprng;
|
||||
sim_file_count++;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
}
|
||||
|
||||
// write/rewrite a file?
|
||||
@@ -8965,29 +9079,27 @@ code = '''
|
||||
// choose a random seed
|
||||
uint32_t wprng = TEST_PRNG(&prng);
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
uint32_t wprng_ = wprng;
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng_) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// update sim
|
||||
sim_files[j]->prng = wprng;
|
||||
if (!sim_files[j]->zombie) {
|
||||
// insert into our sim
|
||||
// update in our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = false;
|
||||
}
|
||||
// new prng
|
||||
sim_prngs[k] = wprng;
|
||||
// no longer sticky
|
||||
sim_isstickys[k] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -8995,22 +9107,14 @@ code = '''
|
||||
// update related sim files
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
sim_files[k]->uncreat = false;
|
||||
// new prng
|
||||
sim_files[k]->prng = wprng;
|
||||
// no longer sticky
|
||||
sim_files[k]->sticky = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write to the file
|
||||
lfsr_file_rewind(&lfs, &sim_files[j]->file) => 0;
|
||||
uint8_t wbuf[SIZE];
|
||||
for (lfs_size_t k = 0; k < SIZE; k++) {
|
||||
wbuf[k] = 'a' + (TEST_PRNG(&wprng) % 26);
|
||||
}
|
||||
lfsr_file_write(&lfs, &sim_files[j]->file, wbuf, SIZE) => SIZE;
|
||||
lfsr_file_sync(&lfs, &sim_files[j]->file)
|
||||
=> (!sim_files[j]->zombie) ? 0 : LFS_ERR_NOENT;
|
||||
|
||||
// close a file?
|
||||
} else if (op == 2) {
|
||||
if (sim_file_count == 0) {
|
||||
@@ -9018,6 +9122,9 @@ code = '''
|
||||
}
|
||||
// choose a random file handle
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_file_count;
|
||||
lfs_size_t x = sim_files[j]->x;
|
||||
lfs_size_t sticky = sim_files[j]->sticky;
|
||||
lfs_size_t zombie = sim_files[j]->zombie;
|
||||
|
||||
// this doesn't really test anything, but if we don't close
|
||||
// files eventually everything will end up zombies
|
||||
@@ -9033,6 +9140,35 @@ code = '''
|
||||
sim_files[j] = sim_files[sim_file_count-1];
|
||||
sim_file_count -= 1;
|
||||
|
||||
// update our sim
|
||||
if (sticky && !zombie) {
|
||||
// orphaned?
|
||||
bool orphan = true;
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x && !sim_files[k]->zombie) {
|
||||
orphan = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we were never synced, delete from sim
|
||||
if (orphan) {
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (sim[k] == x) {
|
||||
memmove(&sim[k], &sim[k+1],
|
||||
(sim_size-(k+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k], &sim_prngs[k+1],
|
||||
(sim_size-(k+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k], &sim_isstickys[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[k], &sim_isdirs[k+1],
|
||||
(sim_size-(k+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove a file?
|
||||
} else if (op == 3) {
|
||||
if (sim_size == 0) {
|
||||
@@ -9042,11 +9178,18 @@ code = '''
|
||||
lfs_size_t j = TEST_PRNG(&prng) % sim_size;
|
||||
lfs_size_t x = sim[j];
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// delete from our sim
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
@@ -9058,11 +9201,6 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// delete this file
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_remove(&lfs, name) => 0;
|
||||
|
||||
// rename a file?
|
||||
} else if (op == 4) {
|
||||
if (sim_size == 0) {
|
||||
@@ -9074,31 +9212,51 @@ code = '''
|
||||
lfs_size_t x = sim[j];
|
||||
lfs_size_t y = TEST_PRNG(&prng) % N;
|
||||
uint32_t wprng = sim_prngs[j];
|
||||
bool isdir = sim_isdirs[j];
|
||||
bool sticky = sim_isstickys[j];
|
||||
bool dir = sim_isdirs[j];
|
||||
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= y) {
|
||||
// renaming and replacing
|
||||
if (k < sim_size && sim[k] == y && x != y) {
|
||||
// type mismatch?
|
||||
if (sim_isdirs[k] != dir) {
|
||||
goto nonsense;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
|
||||
// update our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= y) {
|
||||
// renaming and replacing
|
||||
if (k < sim_size && sim[k] == y && x != y) {
|
||||
// type mismatch?
|
||||
if (sim_isdirs[k] != isdir) {
|
||||
goto nonsense;
|
||||
}
|
||||
|
||||
// delete the original entry
|
||||
memmove(&sim[j], &sim[j+1],
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
sim_size -= 1;
|
||||
if (k > j) {
|
||||
k -= 1;
|
||||
}
|
||||
// update the prng
|
||||
// update the prng/sticky/dir
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
// just renaming
|
||||
} else {
|
||||
// first delete
|
||||
@@ -9106,6 +9264,8 @@ code = '''
|
||||
(sim_size-(j+1))*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[j], &sim_prngs[j+1],
|
||||
(sim_size-(j+1))*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[j], &sim_isstickys[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
memmove(&sim_isdirs[j], &sim_isdirs[j+1],
|
||||
(sim_size-(j+1))*sizeof(bool));
|
||||
if (k > j) {
|
||||
@@ -9116,11 +9276,14 @@ code = '''
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim[k] = y;
|
||||
sim_prngs[k] = wprng;
|
||||
sim_isdirs[k] = isdir;
|
||||
sim_isstickys[k] = sticky;
|
||||
sim_isdirs[k] = dir;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -9138,52 +9301,52 @@ code = '''
|
||||
}
|
||||
}
|
||||
|
||||
// rename this file
|
||||
char old_name[256];
|
||||
sprintf(old_name, "batman%03x", x);
|
||||
char new_name[256];
|
||||
sprintf(new_name, "batman%03x", y);
|
||||
lfsr_rename(&lfs, old_name, new_name) => 0;
|
||||
|
||||
// toss a directory into the mix
|
||||
} else if (op == 5) {
|
||||
// choose a pseudo-random number
|
||||
lfs_size_t x = TEST_PRNG(&prng) % N;
|
||||
|
||||
// insert into our sim, use negative numbers for dirs
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// already seen?
|
||||
if (k < sim_size && sim[k] == x) {
|
||||
goto nonsense;
|
||||
} else {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = 0;
|
||||
sim_isdirs[k] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// make the directory
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_mkdir(&lfs, name) => 0;
|
||||
|
||||
// insert into our sim
|
||||
for (lfs_size_t k = 0;; k++) {
|
||||
if (k >= sim_size || sim[k] >= x) {
|
||||
// insert
|
||||
memmove(&sim[k+1], &sim[k],
|
||||
(sim_size-k)*sizeof(lfs_size_t));
|
||||
memmove(&sim_prngs[k+1], &sim_prngs[k],
|
||||
(sim_size-k)*sizeof(uint32_t));
|
||||
memmove(&sim_isstickys[k+1], &sim_isstickys[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
memmove(&sim_isdirs[k+1], &sim_isdirs[k],
|
||||
(sim_size-k)*sizeof(bool));
|
||||
sim_size += 1;
|
||||
sim[k] = x;
|
||||
sim_prngs[k] = 0;
|
||||
sim_isdirs[k] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// mark any related sim files as zombied
|
||||
for (lfs_size_t k = 0; k < sim_file_count; k++) {
|
||||
if (sim_files[k]->x == x) {
|
||||
sim_files[k]->zombie = true;
|
||||
}
|
||||
}
|
||||
|
||||
// make the directory
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", x);
|
||||
lfsr_mkdir(&lfs, name) => 0;
|
||||
}
|
||||
|
||||
// step the traversal
|
||||
@@ -9209,6 +9372,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -9233,6 +9400,10 @@ code = '''
|
||||
assert(strcmp(info.name, name) == 0);
|
||||
if (sim_isdirs[j]) {
|
||||
assert(info.type == LFS_TYPE_DIR);
|
||||
assert(info.size == 0);
|
||||
} else if (sim_isstickys[j]) {
|
||||
assert(info.type == LFS_TYPE_STICKYNOTE);
|
||||
assert(info.size == 0);
|
||||
} else {
|
||||
assert(info.type == LFS_TYPE_REG);
|
||||
assert(info.size == SIZE);
|
||||
@@ -9246,7 +9417,8 @@ code = '''
|
||||
char name[256];
|
||||
sprintf(name, "batman%03x", sim[j]);
|
||||
lfsr_file_t file;
|
||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => LFS_ERR_ISDIR;
|
||||
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY)
|
||||
=> LFS_ERR_ISDIR;
|
||||
|
||||
} else {
|
||||
char name[256];
|
||||
@@ -9261,8 +9433,12 @@ code = '''
|
||||
}
|
||||
|
||||
uint8_t rbuf[SIZE];
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
if (sim_isstickys[j]) {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => 0;
|
||||
} else {
|
||||
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE;
|
||||
assert(memcmp(rbuf, wbuf, SIZE) == 0);
|
||||
}
|
||||
lfsr_file_close(&lfs, &file) => 0;
|
||||
}
|
||||
}
|
||||
@@ -9284,6 +9460,8 @@ code = '''
|
||||
// clean up sim/lfs
|
||||
free(sim);
|
||||
free(sim_prngs);
|
||||
free(sim_isstickys);
|
||||
free(sim_isdirs);
|
||||
for (lfs_size_t j = 0; j < sim_file_count; j++) {
|
||||
lfsr_file_close(&lfs, &sim_files[j]->file) => 0;
|
||||
free(sim_files[j]);
|
||||
|
||||
Reference in New Issue
Block a user