gc: Made CKMETA/CKDATA progressable, added lfsr_gc_unck
LFS_GC_CKMETA and LFS_GC_CKDATA are a bit unique in that their work is
never really done.
Where LFS_GC_MKCONSISTENT/COMPACT can prove things about the system,
LFS_GC_CKMETA/CKDATA can't, because it's always possible for new
bit-errors to develop. Even _during_ an LFS_GC_CKMETA/CKDATA traversal.
But while this is technically true, it's not a very useful state of
things for our lfsr_gc API...
---
What we really want is some way to know if ckmeta/ckdata has completed
"recently" (for some definition of recently), and to let users indicate
when they need another ckmeta/ckdata scan.
To try to solve this:
1. Added LFS_I_CANCKMETA and LFS_I_CANCKDATA to indicate when lfsr_gc
has not checked metadata/data.
These are set during mount (unless mounting with
LFS_M_CKMETA/CKDATA), and cleared when either lfsr_gc completes or
lfsr_fs_ckmeta/data is called. Once cleared, littlefs will not reset
them on its own.
2. Added lfsr_gc_unck to allow users to explicitly reset LFS_I_CKMETA
and/or LFS_I_CKDATA, which will tell lfsr_gc to check metadata/data
again on the next call.
There is some subtlety around clobbering ongoing traversals, but a
mask and some tests should prevent this from being a problem.
Currently, lfsr_gc_unck also allows clearing of other gc flags, but
I'm not sure there's any real use-case for this...
Note that you can still get the previous behavior if you just call
lfsr_gc_unck after every lfsr_gc call.
This also changes info flag behavior slightly in default mode, with
LFS_I_CANCKMETA/CANCKDATA telling you if metadata/data has been checked
since mount. Which does seem useful? Maybe these flags deserve a better
name?
Code changes:
code stack ctx
default before: 37796 (+0.0%) 2608 (+0.0%) 620 (+0.0%)
default after: 37792 (+0.0%) 2608 (+0.0%) 620 (+0.0%)
gc before: 37896 2608 768
gc after: 37938 (+0.1%) 2608 (+0.0%) 768 (+0.0.%)
This commit is contained in:
@@ -229,6 +229,8 @@ enum lfs_type {
|
||||
0x00002000 // Lookahead buffer is not full
|
||||
#define LFS_I_UNCOMPACTED \
|
||||
0x00008000 // Filesystem may have uncompacted metadata
|
||||
#define LFS_I_CANCKMETA 0x00010000 // Metadata checksums not checked recently
|
||||
#define LFS_I_CANCKDATA 0x00020000 // Data checksums not checked recently
|
||||
|
||||
// internally used flags, don't use these
|
||||
#define LFS_I_UNTIDY 0x00001000 // Filesystem may have orphaned stickynotes
|
||||
@@ -1270,6 +1272,20 @@ int lfsr_traversal_rewind(lfs_t *lfs, lfsr_traversal_t *t);
|
||||
int lfsr_gc(lfs_t *lfs);
|
||||
#endif
|
||||
|
||||
#ifdef LFS_GC
|
||||
// Mark janitorial work as incomplete.
|
||||
//
|
||||
// Any info flags passed to lfsr_gc_unck will be reset internally,
|
||||
// forcing the work to be redone.
|
||||
//
|
||||
// This is most useful for triggering new ckmeta/ckdata scans with
|
||||
// LFS_I_CANCKMETA and LFS_I_CANCKDATA. Otherwise littlefs will perform
|
||||
// only one scan after mount.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfsr_gc_unck(lfs_t *lfs, uint32_t flags);
|
||||
#endif
|
||||
|
||||
|
||||
/// Filesystem-level filesystem operations
|
||||
|
||||
|
||||
Reference in New Issue
Block a user