t: Replaced LFS_T_EXCL with LFS_I_DIRTY flag in lfsr_tinfo
This just forwards the internal LFS_I_DIRTY flag to the user via the
lfsr_tinfo flags field.
Benefits of this approach:
- Gives the user more flexibility on what to do if the filesystem is
modified, maybe you want to keep traversing depending on some other
logic.
- Can eventually add other flags to tinfo.flags, such as
LFS_I_COMPACTED, LFS_I_REPAIRED, LFS_I_INCONSISTENT, etc.
- Avoids confusion around the very different behaviors of LFS_O_EXCL and
LFS_T_EXCL.
I tried to come up with a better name (maybe LFS_T_WATCH?) but it was
a bit of a struggle... Switching to a flags approach sidesteps the
issue.
- Can drop the LFS_ERR_BUSY error code for now.
Code changes were fairly insignificant:
code stack
before: 35244 2680
after: 35224 (-0.1%) 2680 (+0.0%)
The only concern is that the tests highlighted it's possible for our
flag scheme to miss mutation if it happens after/during the last set of
blocks... Not sure how to handle this yet...
This commit is contained in:
@@ -5968,7 +5968,7 @@ static bool lfsr_omdir_ismidopen(lfs_t *lfs, lfsr_smid_t mid) {
|
||||
static void lfsr_fs_mkdirty(lfs_t *lfs) {
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (o->type == LFS_TYPE_TRAVERSAL) {
|
||||
o->flags |= LFS_F_DIRTY;
|
||||
o->flags |= LFS_I_DIRTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8241,10 +8241,6 @@ static inline bool lfsr_t_ismtreeonly(uint32_t flags) {
|
||||
return flags & LFS_T_MTREEONLY;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_isexcl(uint32_t flags) {
|
||||
return flags & LFS_T_EXCL;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_ismkconsistent(uint32_t flags) {
|
||||
return flags & LFS_T_MKCONSISTENT;
|
||||
}
|
||||
@@ -8265,8 +8261,8 @@ static inline bool lfsr_t_isckdata(uint32_t flags) {
|
||||
return flags & (LFS_T_CKDATA ^ LFS_T_CKMETA);
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isdirty(uint32_t flags) {
|
||||
return flags & LFS_F_DIRTY;
|
||||
static inline bool lfsr_i_isdirty(uint32_t flags) {
|
||||
return flags & LFS_I_DIRTY;
|
||||
}
|
||||
|
||||
|
||||
@@ -8683,7 +8679,7 @@ static int lfsr_mtree_gc(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
}
|
||||
|
||||
// mark as dirty
|
||||
t->o.o.flags |= LFS_F_DIRTY;
|
||||
t->o.o.flags |= LFS_I_DIRTY;
|
||||
}
|
||||
|
||||
// compacting btree nodes?
|
||||
@@ -8761,7 +8757,7 @@ static int lfsr_mtree_gc(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
t->u.bt.rid = t->u.bt.bid;
|
||||
|
||||
// mark as dirty
|
||||
t->o.o.flags |= LFS_F_DIRTY;
|
||||
t->o.o.flags |= LFS_I_DIRTY;
|
||||
}
|
||||
|
||||
if (tag_) {
|
||||
@@ -8914,7 +8910,6 @@ static lfs_sblock_t lfs_alloc(lfs_t *lfs, bool erase) {
|
||||
int err = lfsr_mtree_traverse(lfs, &t,
|
||||
NULL, NULL);
|
||||
if (err) {
|
||||
LFS_ASSERT(err != LFS_ERR_BUSY);
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
break;
|
||||
}
|
||||
@@ -12832,7 +12827,7 @@ int lfsr_traversal_open(lfs_t *lfs, lfsr_traversal_t *t, uint32_t flags) {
|
||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
|
||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
||||
// these flags are internal and shouldn't be provided by the user
|
||||
LFS_ASSERT(!lfsr_f_isdirty(flags));
|
||||
LFS_ASSERT(!lfsr_i_isdirty(flags));
|
||||
|
||||
// some flags mutate the filesystem
|
||||
if (lfsr_t_ismkconsistent(flags)
|
||||
@@ -12871,16 +12866,11 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
struct lfs_tinfo *tinfo) {
|
||||
LFS_ASSERT(lfsr_omdir_isopen(lfs, &t->o.o));
|
||||
|
||||
// traversal dirty and excl? terminate early
|
||||
if (lfsr_t_isexcl(t->o.o.flags)
|
||||
&& lfsr_f_isdirty(t->o.o.flags)) {
|
||||
return LFS_ERR_BUSY;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
// some redund blocks left over?
|
||||
if (t->blocks[0] != -1) {
|
||||
// write our traversal info
|
||||
tinfo->flags = t->o.o.flags & LFS_I_DIRTY;
|
||||
tinfo->btype = lfsr_t_btype(t->o.o.flags);
|
||||
tinfo->block = t->blocks[0];
|
||||
|
||||
@@ -12902,13 +12892,6 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
return err;
|
||||
}
|
||||
|
||||
// traversal may itself set the dirty flag if it required
|
||||
// mutation to make progress
|
||||
if (lfsr_t_isexcl(t->o.o.flags)
|
||||
&& lfsr_f_isdirty(t->o.o.flags)) {
|
||||
return LFS_ERR_BUSY;
|
||||
}
|
||||
|
||||
// figure out type/blocks
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
@@ -12935,7 +12918,7 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
done:;
|
||||
// was a lookahead scan successful?
|
||||
if (lfsr_t_islookahead(t->o.o.flags)
|
||||
&& !lfsr_f_isdirty(t->o.o.flags)) {
|
||||
&& !lfsr_i_isdirty(t->o.o.flags)) {
|
||||
lfs_alloc_markfree(lfs);
|
||||
}
|
||||
|
||||
@@ -12978,7 +12961,7 @@ static void lfsr_traversal_clobber(lfs_t *lfs, lfsr_traversal_t *t) {
|
||||
static int lfsr_traversal_rewind_(lfs_t *lfs, lfsr_traversal_t *t) {
|
||||
(void)lfs;
|
||||
// reset traversal
|
||||
t->o.o.flags &= ~LFS_F_DIRTY;
|
||||
t->o.o.flags &= ~LFS_I_DIRTY;
|
||||
t->o.o.state = LFSR_TSTATE_MROOTANCHOR;
|
||||
t->o.o.mdir.mid = -1;
|
||||
t->o.o.mdir.rbyd.weight = 0;
|
||||
|
||||
@@ -98,7 +98,6 @@ enum lfs_error {
|
||||
LFS_ERR_UNKNOWN = -1, // Unknown error
|
||||
LFS_ERR_INVAL = -22, // Invalid parameter
|
||||
LFS_ERR_NOTSUP = -95, // Operation not supported
|
||||
LFS_ERR_BUSY = -16, // Device or resource busy
|
||||
LFS_ERR_IO = -5, // Error during device operation
|
||||
LFS_ERR_CORRUPT = -84, // Corrupted
|
||||
LFS_ERR_NOENT = -2, // No directory entry
|
||||
@@ -169,8 +168,7 @@ enum lfs_btype {
|
||||
// Traversal flags
|
||||
enum lfs_traversal_flags {
|
||||
// traversal open flags
|
||||
LFS_T_MTREEONLY = 0x0008, // Only traverse the mtree
|
||||
LFS_T_EXCL = 0x0010, // Terminate if filesystem modified
|
||||
LFS_T_MTREEONLY = 0x0010, // Only traverse the mtree
|
||||
LFS_T_MKCONSISTENT = 0x0020, // Make the filesystem consistent
|
||||
LFS_T_LOOKAHEAD = 0x0040, // Populate lookahead buffer
|
||||
LFS_T_COMPACT = 0x0080, // Compact metadata logs
|
||||
@@ -179,9 +177,11 @@ enum lfs_traversal_flags {
|
||||
// TODO
|
||||
// LFS_T_REPAIRMETA = 0x0400, // Repair metadata blocks
|
||||
// LFS_T_REPAIRDATA = 0x0c00, // Repair metadata + data blocks
|
||||
};
|
||||
|
||||
// internally used flags
|
||||
LFS_F_DIRTY = 0x1000, // Filesystem has been modified
|
||||
enum lfs_tinfo_flags {
|
||||
// traversal info flags
|
||||
LFS_I_DIRTY = 0x1000, // Filesystem has been modified
|
||||
};
|
||||
|
||||
|
||||
@@ -385,6 +385,9 @@ struct lfs_fsinfo {
|
||||
|
||||
// Traversal info structure
|
||||
struct lfs_tinfo {
|
||||
// Traversal flags
|
||||
uint16_t flags;
|
||||
|
||||
// Type of the block
|
||||
uint8_t btype;
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ ERRS = [
|
||||
('UNKNOWN', -1, "Unknown error" ),
|
||||
('INVAL', -22, "Invalid parameter" ),
|
||||
('NOTSUP', -95, "Operation not supported" ),
|
||||
('BUSY', -16, "Device or resource busy" ),
|
||||
('IO', -5, "Error during device operation" ),
|
||||
('CORRUPT', -84, "Corrupted" ),
|
||||
('NOENT', -2, "No directory entry" ),
|
||||
|
||||
+376
-315
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user