Added LFS_O_CKMETA/CKDATA flags
These flags just call lfsr_file_ckmeta/ckdata under the hood, but make
it very easy to check metadata/data when opening a file. As an extra
plus they implicitly close the file on failure, so might make cleanup
easier.
Of course, everything has a cost:
code stack
before: 36368 2664
after: 36424 (+0.2%) 2664 (+0.0%)
These also ruin my previous "you don't pay for what you don't call"
assertion, since runtime flags unfortunately always pull in code.
We should add a compile-time switch for these evntually.
This commit is contained in:
@@ -5926,6 +5926,14 @@ static inline bool lfsr_o_isdesync(uint32_t flags) {
|
|||||||
return flags & LFS_O_DESYNC;
|
return flags & LFS_O_DESYNC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool lfsr_o_isckmeta(uint32_t flags) {
|
||||||
|
return flags & LFS_O_CKMETA;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool lfsr_o_isckdata(uint32_t flags) {
|
||||||
|
return flags & LFS_O_CKDATA;
|
||||||
|
}
|
||||||
|
|
||||||
// internal open flags
|
// internal open flags
|
||||||
static inline uint8_t lfsr_f_type(uint32_t flags) {
|
static inline uint8_t lfsr_f_type(uint32_t flags) {
|
||||||
return flags >> 24;
|
return flags >> 24;
|
||||||
@@ -9888,6 +9896,8 @@ static inline lfs_off_t lfsr_file_size_(const lfsr_file_t *file) {
|
|||||||
// needed in lfsr_file_opencfg
|
// needed in lfsr_file_opencfg
|
||||||
static lfs_ssize_t lfsr_file_read_(lfs_t *lfs, const lfsr_file_t *file,
|
static lfs_ssize_t lfsr_file_read_(lfs_t *lfs, const lfsr_file_t *file,
|
||||||
lfs_off_t pos, uint8_t *buffer, lfs_size_t size);
|
lfs_off_t pos, uint8_t *buffer, lfs_size_t size);
|
||||||
|
static int lfsr_file_ck(lfs_t *lfs, const lfsr_file_t *file,
|
||||||
|
uint32_t flags);
|
||||||
|
|
||||||
int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
|
int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
|
||||||
const char *path, uint32_t flags,
|
const char *path, uint32_t flags,
|
||||||
@@ -10067,6 +10077,14 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
|
|||||||
file->o.bshrub = LFSR_BSHRUB_BNULL();
|
file->o.bshrub = LFSR_BSHRUB_BNULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check metadata/data for errors?
|
||||||
|
if (lfsr_o_isckmeta(flags) || lfsr_o_isckdata(flags)) {
|
||||||
|
err = lfsr_file_ck(lfs, file, flags);
|
||||||
|
if (err) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add to tracked mdirs
|
// add to tracked mdirs
|
||||||
lfsr_omdir_open(lfs, &file->o.o);
|
lfsr_omdir_open(lfs, &file->o.o);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -11745,7 +11763,8 @@ failed:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// file check functions
|
// file check functions
|
||||||
static int lfsr_file_ck(lfs_t *lfs, lfsr_file_t *file, uint32_t flags) {
|
static int lfsr_file_ck(lfs_t *lfs, const lfsr_file_t *file,
|
||||||
|
uint32_t flags) {
|
||||||
// traverse the file's btree
|
// traverse the file's btree
|
||||||
lfsr_btraversal_t bt = LFSR_BTRAVERSAL();
|
lfsr_btraversal_t bt = LFSR_BTRAVERSAL();
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|||||||
@@ -136,6 +136,8 @@ enum lfs_type {
|
|||||||
#define LFS_O_FLUSH 0x00000040 // Flush data on every write
|
#define LFS_O_FLUSH 0x00000040 // Flush data on every write
|
||||||
#define LFS_O_SYNC 0x00000080 // Sync metadata on every write
|
#define LFS_O_SYNC 0x00000080 // Sync metadata on every write
|
||||||
#define LFS_O_DESYNC 0x00000100 // Do not sync or recieve file updates
|
#define LFS_O_DESYNC 0x00000100 // Do not sync or recieve file updates
|
||||||
|
#define LFS_O_CKMETA 0x00001000 // Check metadata checksums
|
||||||
|
#define LFS_O_CKDATA 0x00002000 // Check metadata + data checksums
|
||||||
|
|
||||||
// internally used flags
|
// internally used flags
|
||||||
#define LFS_F_TYPE 0xff000000 // The file's type
|
#define LFS_F_TYPE 0xff000000 // The file's type
|
||||||
|
|||||||
+19
-2
@@ -269,6 +269,7 @@ done:;
|
|||||||
[cases.test_ck_file_ckmeta_easy]
|
[cases.test_ck_file_ckmeta_easy]
|
||||||
# METHOD=0 => lfsr_file_ckmeta
|
# METHOD=0 => lfsr_file_ckmeta
|
||||||
# METHOD=1 => lfsr_file_close+open+ckmeta
|
# METHOD=1 => lfsr_file_close+open+ckmeta
|
||||||
|
# METHOD=2 => lfsr_file_close+open
|
||||||
defines.METHOD = [0, 1]
|
defines.METHOD = [0, 1]
|
||||||
defines.N = [1, 2, 4, 8, 16, 32, 64]
|
defines.N = [1, 2, 4, 8, 16, 32, 64]
|
||||||
defines.SIZE = [
|
defines.SIZE = [
|
||||||
@@ -345,11 +346,18 @@ code = '''
|
|||||||
lfsr_file_open(&lfs, &file, "octopus", LFS_O_RDONLY) => 0;
|
lfsr_file_open(&lfs, &file, "octopus", LFS_O_RDONLY) => 0;
|
||||||
lfsr_file_ckmeta(&lfs, &file) => LFS_ERR_CORRUPT;
|
lfsr_file_ckmeta(&lfs, &file) => LFS_ERR_CORRUPT;
|
||||||
|
|
||||||
|
// find clobbered blocks with lfsr_file_close+open
|
||||||
|
} else if (METHOD == 2) {
|
||||||
|
lfsr_file_open(&lfs, &file, "octopus",
|
||||||
|
LFS_O_RDONLY | LFS_O_CKMETA) => LFS_ERR_CORRUPT;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
if (METHOD != 2) {
|
||||||
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
}
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfsr_unmount(&lfs) => 0;
|
||||||
}
|
}
|
||||||
done:;
|
done:;
|
||||||
@@ -359,6 +367,7 @@ done:;
|
|||||||
[cases.test_ck_file_ckdata_easy]
|
[cases.test_ck_file_ckdata_easy]
|
||||||
# METHOD=0 => lfsr_file_ckdata
|
# METHOD=0 => lfsr_file_ckdata
|
||||||
# METHOD=1 => lfsr_file_close+open+ckdata
|
# METHOD=1 => lfsr_file_close+open+ckdata
|
||||||
|
# METHOD=2 => lfsr_file_close+open
|
||||||
defines.METHOD = [0, 1]
|
defines.METHOD = [0, 1]
|
||||||
defines.N = [1, 2, 4, 8, 16, 32, 64]
|
defines.N = [1, 2, 4, 8, 16, 32, 64]
|
||||||
defines.SIZE = [
|
defines.SIZE = [
|
||||||
@@ -436,11 +445,19 @@ code = '''
|
|||||||
lfsr_file_open(&lfs, &file, "octopus", LFS_O_RDONLY) => 0;
|
lfsr_file_open(&lfs, &file, "octopus", LFS_O_RDONLY) => 0;
|
||||||
lfsr_file_ckdata(&lfs, &file) => LFS_ERR_CORRUPT;
|
lfsr_file_ckdata(&lfs, &file) => LFS_ERR_CORRUPT;
|
||||||
|
|
||||||
|
// find clobbered blocks with lfsr_file_close+open
|
||||||
|
} else if (METHOD == 2) {
|
||||||
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
lfsr_file_open(&lfs, &file, "octopus",
|
||||||
|
LFS_O_RDONLY | LFS_O_CKDATA) => LFS_ERR_CORRUPT;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_file_close(&lfs, &file) => 0;
|
if (METHOD != 2) {
|
||||||
|
lfsr_file_close(&lfs, &file) => 0;
|
||||||
|
}
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfsr_unmount(&lfs) => 0;
|
||||||
}
|
}
|
||||||
done:;
|
done:;
|
||||||
|
|||||||
Reference in New Issue
Block a user