Added filesystem-level info flags to lfsr_fs_stat
Thinking again of use cases, lfsr_fs_gc provides the perfect API to call
in the background to perform any pending filesystem work. But what if
there's no work to be done? Sure we could just spin forever, but that's
a waste. Especially on devices that can turn on sleep modes to save
power.
To help with this, this commit adds a set of flags to struct lfs_fsinfo
that signals when lfsr_fs_gc can accomplish work:
LFS_I_INCONSISTENT = 0x01, // Filesystem needs mkconsistent to write
LFS_I_NEEDSUPGRADE* = 0x02, // Filesystem needs an upgrade to write
LFS_I_CANLOOKAHEAD = 0x04, // Lookahead buffer is not full
LFS_I_CANPREERASE+ = 0x08, // Pre-erase buffer is not full
LFS_I_UNCOMPACTED = 0x10, // Filesystem may have uncompacted metadata
LFS_I_NEEDSREPAIRMETA+ = 0x20, // Filesystem contains damaged metadata
LFS_I_NEEDSREPAIRDATA+ = 0x40, // Filesystem contains damaged data
*Hypothetical
+Planned
This flags field also provides a useful place internally to store other
filesystem-related flags, currently LFS_F_ORPHANS, though this may be
expanded in the future.
These flags allow users to know exactly what work can/needs to be done
for the filesystem to make progress:
- LFS_I_INCONSISTENT => LFS_GC_MKCONSISTENT or lfsr_fs_mkconsistent
- LFS_I_CANLOOKAHEAD => LFS_GC_LOOKAHEAD
- LFS_I_UNCOMPACTED => LFS_GC_COMPACT
The one is new!
If we complete a compaction-traversal without any mutation, we know
all mdirs/btree nodes have been compacted and future traversals won't
accomplish anything. Of course, we need to clear this bit on
filesystem mutation.
Right now we just pessimistically assume the filesystem is uncompacted
during mount, but in theory we can also figure this out during our
initial mount traversal.
- LFS_GC_CKMETA/CKDATA?
LFS_GC_CKMETA and LFS_GC_CKDATA are a bit trickier. In theory,
LFS_GC_CKMETA/CKDATA will always accomplish something, since time is
the only ingredient necessary to introduce bit errors.
So there isn't really a reasonable flag here. It's entirely up to the
user to decide when to do an LFS_GC_CKMETA/CKDATA traversal.
Code changes:
code stack
before: 35740 2672
after: 35880 (+0.4%) 2672 (+0.0%)
This commit is contained in:
@@ -125,6 +125,16 @@ enum lfs_type {
|
||||
LFS_TYPE_TRAVERSAL = 9,
|
||||
};
|
||||
|
||||
// Block types
|
||||
enum lfs_btype {
|
||||
LFS_BTYPE_MDIR = 1,
|
||||
LFS_BTYPE_BTREE = 2,
|
||||
LFS_BTYPE_DATA = 3,
|
||||
// TODO
|
||||
// LFS_BTYPE_PARITY = 4,
|
||||
// LFS_BTYPE_BAD = 5,
|
||||
};
|
||||
|
||||
// File open flags
|
||||
enum lfs_open_flags {
|
||||
// open flags
|
||||
@@ -155,14 +165,15 @@ enum lfs_whence_flags {
|
||||
LFS_SEEK_END = 2, // Seek relative to the end of the file
|
||||
};
|
||||
|
||||
// Block types
|
||||
enum lfs_btype {
|
||||
LFS_BTYPE_MDIR = 1,
|
||||
LFS_BTYPE_BTREE = 2,
|
||||
LFS_BTYPE_DATA = 3,
|
||||
// TODO
|
||||
// LFS_BTYPE_PARITY = 4,
|
||||
// LFS_BTYPE_BAD = 5,
|
||||
// Filesystem info flags
|
||||
enum lfs_fsinfo_flags {
|
||||
// state flags
|
||||
LFS_I_INCONSISTENT = 0x01, // Filesystem needs mkconsistent to write
|
||||
LFS_I_CANLOOKAHEAD = 0x04, // Lookahead buffer is not full
|
||||
LFS_I_UNCOMPACTED = 0x10, // Filesystem may have uncompacted metadata
|
||||
|
||||
// internally used flags
|
||||
LFS_F_ORPHANS = 0x80, // Filesystem may have untracked orphans
|
||||
};
|
||||
|
||||
// Traversal flags
|
||||
@@ -391,7 +402,8 @@ struct lfs_info {
|
||||
|
||||
// Filesystem info structure
|
||||
struct lfs_fsinfo {
|
||||
// TODO should we add rcompat/wcompat flags here?
|
||||
// Filesystem flags
|
||||
uint8_t flags;
|
||||
|
||||
// Size of a logical block in bytes.
|
||||
lfs_size_t block_size;
|
||||
@@ -713,10 +725,7 @@ typedef struct lfs {
|
||||
lfs_size_t name_limit;
|
||||
lfs_off_t file_limit;
|
||||
|
||||
// TODO we should put this flag somewhere, should lfs_t have a general
|
||||
// purpose flags field? this has been useful for lfsr_file_t
|
||||
bool hasorphans;
|
||||
|
||||
uint8_t flags;
|
||||
int8_t recycle_bits;
|
||||
uint8_t attr_estimate;
|
||||
uint8_t mdir_bits;
|
||||
|
||||
Reference in New Issue
Block a user