Increased internal flags 16 bits -> 32 bits
If we add CKMETA/CKDATA and eventually REPAIRMETA/REPAIRDATA to the file
open flags, we'll end up with 17 flags total (13 user-facing,
4 internal), which is a bit (heh) too much for a 16-bit flags field!
There are a few ways to solve this, dropping features for one, instead
I've decided to expand the fields flag to 32-bits. Fortunately this was
already the field size for all user-facing fields.
To avoid a RAM increase, I've also shoved the opened-file types and
traversal tstates into the same field.
We have various flags in quite a few places now, here's how
everything fits together:
8 8 8 8
.----++----++----++----.
.----..---..--..-------.
o_flags: |type|| f ||t || o |
|----||---|:--:'-------'
|----||---|:--:--------.
d_flags: |type|| f |: : |
|----||---|:--:--------'
|----||---|:--'--..----.
t_flags: |type|| f || t ||tstt|
'----''---'|-----|'----'
.----------|-----|-----.
gc_flags: | | t | |
'----------|-----|-----'
.-----.---.|-----|.----.
m_flags: | | m || t || m |
'-----|---|'-----'|----|
.----.|---|-------|----|
i_flags: | i || m | | m |
'----''---'-------'----'
Unfortunately, using the full 32-bit flag space highlights that C99's
enum types are kind of garbage...
In C99 enums are strictly signed ints, which means attempting to use
them for 32-bit bit fields overflows. There is no way around this so
I've switched our flag definitions to #defines.
I've kept types as enums for now but I'm keeping my eye on them...
---
The tradeoff of merging the type/btype/tstate/flags fields is that it
takes more code to extract/encode the various subfields. Since these
fields our heavily used in our codebase, this really adds up:
code stack
before: 35888 2696
after: 36048 (+0.4%) 2696 (+0.0%)
At least in theory the type fields can be optimized to a byte load, but
not btype/tstate. Also accessing bits in higher positions may be adding
cost.
This commit is contained in:
@@ -5161,7 +5161,7 @@ static inline int lfsr_sprout_cmp(
|
||||
}
|
||||
|
||||
// needed in lfsr_sprout_estimate
|
||||
static inline bool lfsr_omdir_isbshrub(const lfsr_omdir_t *o);
|
||||
static inline bool lfsr_f_isbshrub(uint32_t flags);
|
||||
|
||||
// these are used in mdir compaction
|
||||
static lfs_ssize_t lfsr_sprout_estimate(lfs_t *lfs,
|
||||
@@ -5169,7 +5169,7 @@ static lfs_ssize_t lfsr_sprout_estimate(lfs_t *lfs,
|
||||
// only include the last reference
|
||||
const lfsr_sprout_t *last = NULL;
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (lfsr_omdir_isbshrub(o)
|
||||
if (lfsr_f_isbshrub(o->flags)
|
||||
&& lfsr_bshrub_isbsprout(&o->mdir,
|
||||
&((lfsr_obshrub_t*)o)->bshrub)
|
||||
&& lfsr_sprout_cmp(
|
||||
@@ -5200,7 +5200,7 @@ static int lfsr_sprout_compact(lfs_t *lfs, const lfsr_rbyd_t *rbyd_,
|
||||
// stage any opened inlined files with their new location so we
|
||||
// can update these later if our commit is a success
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (lfsr_omdir_isbshrub(o)
|
||||
if (lfsr_f_isbshrub(o->flags)
|
||||
&& lfsr_bshrub_isbsprout(&o->mdir,
|
||||
&((lfsr_obshrub_t*)o)->bshrub)
|
||||
&& lfsr_sprout_cmp(
|
||||
@@ -5317,7 +5317,7 @@ static lfs_ssize_t lfsr_shrub_estimate(lfs_t *lfs,
|
||||
// only include the last reference
|
||||
const lfsr_shrub_t *last = NULL;
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (lfsr_omdir_isbshrub(o)
|
||||
if (lfsr_f_isbshrub(o->flags)
|
||||
&& lfsr_bshrub_isbshrub(&o->mdir,
|
||||
&((lfsr_obshrub_t*)o)->bshrub)
|
||||
&& lfsr_shrub_cmp(
|
||||
@@ -5351,7 +5351,7 @@ static int lfsr_shrub_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
|
||||
//
|
||||
// this should include our current bshrub
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (lfsr_omdir_isbshrub(o)
|
||||
if (lfsr_f_isbshrub(o->flags)
|
||||
&& lfsr_bshrub_isbshrub(&o->mdir,
|
||||
&((lfsr_obshrub_t*)o)->bshrub)
|
||||
&& lfsr_shrub_cmp(
|
||||
@@ -5458,7 +5458,7 @@ static lfs_ssize_t lfsr_bshrub_estimate(lfs_t *lfs,
|
||||
|
||||
// this includes our current shrub
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (lfsr_omdir_isbshrub(o)
|
||||
if (lfsr_f_isbshrub(o->flags)
|
||||
&& o->mdir.mid == mdir->mid) {
|
||||
if (lfsr_bshrub_isbsprout(&o->mdir,
|
||||
&((lfsr_obshrub_t*)o)->bshrub)) {
|
||||
@@ -5648,7 +5648,7 @@ static int lfsr_bshrub_commit_(lfs_t *lfs,
|
||||
// as unerased
|
||||
if (lfsr_bshrub_isbtree(mdir, bshrub)) {
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (lfsr_omdir_isbshrub(o)
|
||||
if (lfsr_f_isbshrub(o->flags)
|
||||
&& &((lfsr_obshrub_t*)o)->bshrub != bshrub
|
||||
&& lfsr_bshrub_isbshruborbtree(
|
||||
&((lfsr_obshrub_t*)o)->bshrub)
|
||||
@@ -5737,7 +5737,7 @@ static int lfsr_bshrub_commit_(lfs_t *lfs,
|
||||
|
||||
// update _all_ shrubs with the new estimate
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (lfsr_omdir_isbshrub(o)
|
||||
if (lfsr_f_isbshrub(o->flags)
|
||||
&& o->mdir.mid == mdir->mid
|
||||
&& lfsr_bshrub_isbshrub(&o->mdir,
|
||||
&((lfsr_obshrub_t*)o)->bshrub)) {
|
||||
@@ -5889,6 +5889,129 @@ static int lfsr_data_readmptr(lfs_t *lfs, lfsr_data_t *data,
|
||||
|
||||
/// various flag things ///
|
||||
|
||||
// open flags
|
||||
static inline bool lfsr_o_isrdonly(uint32_t flags) {
|
||||
return (flags & 3) == LFS_O_RDONLY;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_iswronly(uint32_t flags) {
|
||||
return (flags & 3) == LFS_O_WRONLY;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_iscreat(uint32_t flags) {
|
||||
return flags & LFS_O_CREAT;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_isexcl(uint32_t flags) {
|
||||
return flags & LFS_O_EXCL;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_istrunc(uint32_t flags) {
|
||||
return flags & LFS_O_TRUNC;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_isappend(uint32_t flags) {
|
||||
return flags & LFS_O_APPEND;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_isflush(uint32_t flags) {
|
||||
return flags & LFS_O_FLUSH;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_issync(uint32_t flags) {
|
||||
return flags & LFS_O_SYNC;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_isdesync(uint32_t flags) {
|
||||
return flags & LFS_O_DESYNC;
|
||||
}
|
||||
|
||||
// internal open flags
|
||||
static inline uint8_t lfsr_f_type(uint32_t flags) {
|
||||
return flags >> 24;
|
||||
}
|
||||
|
||||
static inline uint32_t lfsr_f_settype(uint32_t flags, uint8_t type) {
|
||||
return (flags & ~0xff000000) | ((uint32_t)type << 24);
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isbshrub(uint32_t flags) {
|
||||
// it turns out that bshrub types share a bit
|
||||
return flags & 0x01000000;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isunflush(uint32_t flags) {
|
||||
return flags & LFS_F_UNFLUSH;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isunsync(uint32_t flags) {
|
||||
return flags & LFS_F_UNSYNC;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isorphan(uint32_t flags) {
|
||||
return flags & LFS_F_ORPHAN;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_iszombie(uint32_t flags) {
|
||||
return flags & LFS_F_ZOMBIE;
|
||||
}
|
||||
|
||||
// traversal flags
|
||||
static inline bool lfsr_t_ismtreeonly(uint32_t flags) {
|
||||
return flags & LFS_T_MTREEONLY;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_ismkconsistent(uint32_t flags) {
|
||||
return flags & LFS_T_MKCONSISTENT;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_islookahead(uint32_t flags) {
|
||||
return flags & LFS_T_LOOKAHEAD;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_iscompact(uint32_t flags) {
|
||||
return flags & LFS_T_COMPACT;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_isckmeta(uint32_t flags) {
|
||||
return flags & LFS_T_CKMETA;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_isckdata(uint32_t flags) {
|
||||
return flags & LFS_T_CKDATA;
|
||||
}
|
||||
|
||||
// internal traversal flags
|
||||
static inline uint8_t lfsr_f_tstate(uint32_t flags) {
|
||||
return (flags >> 0) & 0xf;
|
||||
}
|
||||
|
||||
static inline uint32_t lfsr_f_settstate(uint32_t flags, uint8_t tstate) {
|
||||
return (flags & ~0x0000000f) | (tstate << 0);
|
||||
}
|
||||
|
||||
static inline uint8_t lfsr_f_btype(uint32_t flags) {
|
||||
return (flags >> 4) & 0xf;
|
||||
}
|
||||
|
||||
static inline uint32_t lfsr_f_setbtype(uint32_t flags, uint8_t btype) {
|
||||
return (flags & ~0x000000f0) | (btype << 4);
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isdirty(uint32_t flags) {
|
||||
return flags & LFS_F_DIRTY;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_ismutated(uint32_t flags) {
|
||||
return flags & LFS_F_MUTATED;
|
||||
}
|
||||
|
||||
static inline uint32_t lfsr_f_swapdirty(uint32_t flags) {
|
||||
uint32_t x = ((flags >> 19) ^ (flags >> 18)) & 0x1;
|
||||
return flags ^ (x << 19) ^ (x << 18);
|
||||
}
|
||||
|
||||
// mount flags
|
||||
static inline bool lfsr_m_isrdonly(uint32_t flags) {
|
||||
return flags & LFS_M_RDONLY;
|
||||
}
|
||||
@@ -5897,14 +6020,15 @@ static inline bool lfsr_m_isckprogs(uint32_t flags) {
|
||||
return flags & LFS_M_CKPROGS;
|
||||
}
|
||||
|
||||
static inline bool lfsr_i_isuncompacted(uint32_t flags) {
|
||||
return flags & LFS_I_UNCOMPACTED;
|
||||
}
|
||||
|
||||
// internal fs flags
|
||||
static inline bool lfsr_f_hasorphans(uint32_t flags) {
|
||||
return flags & LFS_F_ORPHANS;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isuncompacted(uint32_t flags) {
|
||||
return flags & LFS_F_UNCOMPACTED;
|
||||
}
|
||||
|
||||
// on-demand flags
|
||||
|
||||
// needed in lfsr_fs_isinconsistent
|
||||
@@ -5927,12 +6051,6 @@ static bool lfsr_fs_canlookahead(const lfs_t *lfs) {
|
||||
// we maintain a linked-list of all opened mdirs, in order to keep
|
||||
// metadata state in-sync, these may be casted to specific file types
|
||||
|
||||
static inline bool lfsr_omdir_isbshrub(const lfsr_omdir_t *o) {
|
||||
// it turns out that bshrub types share a bit
|
||||
return o->type & 0x1;
|
||||
}
|
||||
|
||||
|
||||
static bool lfsr_omdir_isopen(lfs_t *lfs, const lfsr_omdir_t *o) {
|
||||
for (lfsr_omdir_t *o_ = lfs->omdirs; o_; o_ = o_->next) {
|
||||
if (o_ == o) {
|
||||
@@ -5973,7 +6091,8 @@ static bool lfsr_omdir_ismidopen(lfs_t *lfs, lfsr_smid_t mid) {
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
// we really only care about regular open files here, all
|
||||
// others are either transient (dirs) or fake (orphans)
|
||||
if (o->type == LFS_TYPE_REG && o->mdir.mid == mid) {
|
||||
if (lfsr_f_type(o->flags) == LFS_TYPE_REG
|
||||
&& o->mdir.mid == mid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -5990,7 +6109,7 @@ static void lfsr_traversal_clobber(lfs_t *lfs, lfsr_traversal_t *t);
|
||||
static void lfsr_omdir_clobber(lfs_t *lfs, const lfsr_omdir_t *o,
|
||||
bool dirty) {
|
||||
for (lfsr_omdir_t *o_ = lfs->omdirs; o_; o_ = o_->next) {
|
||||
if (o_->type == LFS_TYPE_TRAVERSAL) {
|
||||
if (lfsr_f_type(o_->flags) == LFS_TYPE_TRAVERSAL) {
|
||||
o_->flags |= (dirty) ? LFS_F_DIRTY : 0;
|
||||
|
||||
if (o && ((lfsr_traversal_t*)o_)->ot == o) {
|
||||
@@ -6785,7 +6904,7 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
// unsynced files
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
// belongs to our mid?
|
||||
if (!(lfsr_omdir_isbshrub(o)
|
||||
if (!(lfsr_f_isbshrub(o->flags)
|
||||
&& o->mdir.mid == mdir__->mid)) {
|
||||
continue;
|
||||
}
|
||||
@@ -6973,7 +7092,7 @@ static lfs_ssize_t lfsr_mdir_estimate__(lfs_t *lfs, const lfsr_mdir_t *mdir,
|
||||
// opened files by mid
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
// belongs to our mdir + rid?
|
||||
if (!(lfsr_omdir_isbshrub(o)
|
||||
if (!(lfsr_f_isbshrub(o->flags)
|
||||
&& lfsr_mdir_cmp(&o->mdir, mdir) == 0
|
||||
&& lfsr_mid_rid(lfs, o->mdir.mid) == a_rid)) {
|
||||
continue;
|
||||
@@ -7121,7 +7240,7 @@ static int lfsr_mdir_compact__(lfs_t *lfs, lfsr_mdir_t *mdir_,
|
||||
// we're not quite done! we also need to bring over any unsynced files
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
// belongs to our mdir?
|
||||
if (!(lfsr_omdir_isbshrub(o)
|
||||
if (!(lfsr_f_isbshrub(o->flags)
|
||||
&& lfsr_mdir_cmp(&o->mdir, mdir) == 0
|
||||
&& lfsr_mid_rid(lfs, o->mdir.mid) >= start_rid
|
||||
&& (lfsr_rid_t)lfsr_mid_rid(lfs, o->mdir.mid)
|
||||
@@ -7377,7 +7496,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
}
|
||||
|
||||
// stage any bsprouts/bshrubs
|
||||
if (lfsr_omdir_isbshrub(o)) {
|
||||
if (lfsr_f_isbshrub(o->flags)) {
|
||||
((lfsr_obshrub_t*)o)->bshrub_ = ((lfsr_obshrub_t*)o)->bshrub;
|
||||
}
|
||||
}
|
||||
@@ -7844,7 +7963,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
|
||||
// we may have touched any number of mdirs, so assume uncompacted
|
||||
// until lfsr_fs_gc can prove otherwise
|
||||
lfs->flags |= LFS_I_UNCOMPACTED;
|
||||
lfs->flags |= LFS_F_UNCOMPACTED;
|
||||
|
||||
// update any gstate changes
|
||||
lfsr_fs_commitgdelta(lfs);
|
||||
@@ -7860,7 +7979,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
// removed?
|
||||
if (o->mdir.mid < mid_ - attrs[i].weight) {
|
||||
// we should not be removing opened regular files
|
||||
LFS_ASSERT(o->type != LFS_TYPE_REG);
|
||||
LFS_ASSERT(lfsr_f_type(o->flags) != LFS_TYPE_REG);
|
||||
o->flags |= LFS_F_ZOMBIE;
|
||||
o->mdir.mid = mid_;
|
||||
} else {
|
||||
@@ -7875,7 +7994,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
|
||||
// update any staged bsprouts/bshrubs
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (lfsr_omdir_isbshrub(o)) {
|
||||
if (lfsr_f_isbshrub(o->flags)) {
|
||||
((lfsr_obshrub_t*)o)->bshrub = ((lfsr_obshrub_t*)o)->bshrub_;
|
||||
}
|
||||
}
|
||||
@@ -7887,7 +8006,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
if (lfsr_mdir_cmp(&mroot_, &lfs->mroot) != 0
|
||||
|| lfsr_mtree_cmp(&mtree_, &lfs->mtree) != 0) {
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (o->type == LFS_TYPE_TRAVERSAL
|
||||
if (lfsr_f_type(o->flags) == LFS_TYPE_TRAVERSAL
|
||||
&& o->mdir.mid == -1
|
||||
// don't clobber the current mdir, assume upper layers
|
||||
// know what they're doing
|
||||
@@ -8244,9 +8363,10 @@ enum {
|
||||
|
||||
#define LFSR_TRAVERSAL(_flags) \
|
||||
((lfsr_traversal_t){ \
|
||||
.o.o.type=LFS_TYPE_TRAVERSAL, \
|
||||
.o.o.state=LFSR_TSTATE_MROOTANCHOR, \
|
||||
.o.o.flags=_flags, \
|
||||
.o.o.flags \
|
||||
= (LFS_TYPE_TRAVERSAL << 24) \
|
||||
| (LFSR_TSTATE_MROOTANCHOR << 4) \
|
||||
| (_flags), \
|
||||
.o.o.mdir.mid=-1, \
|
||||
.o.o.mdir.rbyd.blocks={-1,-1}, \
|
||||
.o.bshrub.u.bshrub.blocks={-1}, \
|
||||
@@ -8255,58 +8375,11 @@ enum {
|
||||
.u.mtortoise.step=0, \
|
||||
.u.mtortoise.power=0})
|
||||
|
||||
static inline uint8_t lfsr_t_btype(uint32_t flags) {
|
||||
// store btype in flags to avoid needing an extra field
|
||||
return flags & 0x7;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_ismtreeonly(uint32_t flags) {
|
||||
return flags & LFS_T_MTREEONLY;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_ismkconsistent(uint32_t flags) {
|
||||
return flags & LFS_T_MKCONSISTENT;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_islookahead(uint32_t flags) {
|
||||
return flags & LFS_T_LOOKAHEAD;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_iscompact(uint32_t flags) {
|
||||
return flags & LFS_T_COMPACT;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_isckmeta(uint32_t flags) {
|
||||
return flags & LFS_T_CKMETA;
|
||||
}
|
||||
|
||||
static inline bool lfsr_t_isckdata(uint32_t flags) {
|
||||
return flags & LFS_T_CKDATA;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isdirty(uint32_t flags) {
|
||||
return flags & LFS_F_DIRTY;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_ismutated(uint32_t flags) {
|
||||
return flags & LFS_F_MUTATED;
|
||||
}
|
||||
|
||||
static inline uint32_t lfsr_f_swapdirty(uint32_t flags) {
|
||||
uint32_t x = ((flags >> 14) ^ (flags >> 12)) & 0x1;
|
||||
return flags ^ (x << 14) ^ (x << 12);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// needed in lfsr_mtree_traverse_
|
||||
static inline bool lfsr_f_isunsync(uint32_t flags);
|
||||
|
||||
// low-level traversal _only_ finds blocks
|
||||
static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
lfsr_tag_t *tag_, lfsr_bptr_t *bptr_) {
|
||||
while (true) {
|
||||
switch (t->o.o.state) {
|
||||
switch (lfsr_f_tstate(t->o.o.flags)) {
|
||||
// start with the mrootanchor 0x{0,1}
|
||||
//
|
||||
// note we make sure to include all mroots in our mroot chain!
|
||||
@@ -8320,7 +8393,8 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
}
|
||||
|
||||
// transition to traversing the mroot chain
|
||||
t->o.o.state = LFSR_TSTATE_MROOTCHAIN;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_MROOTCHAIN);
|
||||
|
||||
if (tag_) {
|
||||
*tag_ = LFSR_TAG_MDIR;
|
||||
@@ -8342,7 +8416,8 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
// traverse any files in our mroot next
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
t->o.o.mdir.mid = 0;
|
||||
t->o.o.state = LFSR_TSTATE_MDIR;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_MDIR);
|
||||
continue;
|
||||
}
|
||||
return err;
|
||||
@@ -8405,7 +8480,8 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
}
|
||||
|
||||
// transition to traversing the mdir
|
||||
t->o.o.state = LFSR_TSTATE_MDIR;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_MDIR);
|
||||
|
||||
if (tag_) {
|
||||
*tag_ = LFSR_TAG_MDIR;
|
||||
@@ -8425,7 +8501,8 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
|
||||
// transition to traversing the mtree
|
||||
t->u.bt = LFSR_BTRAVERSAL();
|
||||
t->o.o.state = LFSR_TSTATE_MTREE;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_MTREE);
|
||||
continue;
|
||||
|
||||
} else {
|
||||
@@ -8441,14 +8518,16 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
if (err) {
|
||||
// end of mtree? guess we're done
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
t->o.o.state = LFSR_TSTATE_DONE;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_DONE);
|
||||
continue;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// transition to traversing the mdir
|
||||
t->o.o.state = LFSR_TSTATE_MDIR;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_MDIR);
|
||||
|
||||
if (tag_) {
|
||||
*tag_ = LFSR_TAG_MDIR;
|
||||
@@ -8466,7 +8545,8 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
|| lfsr_mid_rid(lfs, t->o.o.mdir.mid)
|
||||
>= (lfsr_srid_t)t->o.o.mdir.rbyd.weight) {
|
||||
t->o.o.mdir.mid = lfsr_mid_bid(lfs, t->o.o.mdir.mid) + 1;
|
||||
t->o.o.state = LFSR_TSTATE_MDIRS;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_MDIRS);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -8503,13 +8583,15 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
// no? next we need to check any opened files
|
||||
} else {
|
||||
t->ot = lfs->omdirs;
|
||||
t->o.o.state = LFSR_TSTATE_OMDIRS;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_OMDIRS);
|
||||
continue;
|
||||
}
|
||||
|
||||
// start traversing
|
||||
t->u.bt = LFSR_BTRAVERSAL();
|
||||
t->o.o.state = LFSR_TSTATE_BTREE;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_BTREE);
|
||||
continue;
|
||||
|
||||
// scan for blocks/btrees in our opened file list
|
||||
@@ -8517,7 +8599,8 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
// reached end of opened files? return to mdir traversal
|
||||
if (!t->ot) {
|
||||
t->o.o.mdir.mid += 1;
|
||||
t->o.o.state = LFSR_TSTATE_MDIR;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_MDIR);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -8530,7 +8613,7 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
// this list anyways
|
||||
//
|
||||
if (t->ot->mdir.mid != t->o.o.mdir.mid
|
||||
|| t->ot->type != LFS_TYPE_REG
|
||||
|| lfsr_f_type(t->ot->flags) != LFS_TYPE_REG
|
||||
|| !lfsr_f_isunsync(t->ot->flags)) {
|
||||
t->ot = t->ot->next;
|
||||
continue;
|
||||
@@ -8540,7 +8623,8 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
const lfsr_file_t *file = (const lfsr_file_t*)t->ot;
|
||||
t->o.bshrub = file->o.bshrub;
|
||||
t->u.bt = LFSR_BTRAVERSAL();
|
||||
t->o.o.state = LFSR_TSTATE_OBTREE;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_OBTREE);
|
||||
continue;
|
||||
|
||||
// traverse any btrees we see, this includes the mtree and any file
|
||||
@@ -8555,19 +8639,25 @@ static int lfsr_mtree_traverse_(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
if (err) {
|
||||
if (err == LFS_ERR_NOENT) {
|
||||
// end of mtree? start iterating over mdirs
|
||||
if (t->o.o.state == LFSR_TSTATE_MTREE) {
|
||||
if (lfsr_f_tstate(t->o.o.flags)
|
||||
== LFSR_TSTATE_MTREE) {
|
||||
t->o.o.mdir.mid = 0;
|
||||
t->o.o.state = LFSR_TSTATE_MDIRS;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_MDIRS);
|
||||
continue;
|
||||
// end of mdir btree? start iterating over opened files
|
||||
} else if (t->o.o.state == LFSR_TSTATE_BTREE) {
|
||||
} else if (lfsr_f_tstate(t->o.o.flags)
|
||||
== LFSR_TSTATE_BTREE) {
|
||||
t->ot = lfs->omdirs;
|
||||
t->o.o.state = LFSR_TSTATE_OMDIRS;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_OMDIRS);
|
||||
continue;
|
||||
// end of opened btree? go to next opened file
|
||||
} else if (t->o.o.state == LFSR_TSTATE_OBTREE) {
|
||||
} else if (lfsr_f_tstate(t->o.o.flags)
|
||||
== LFSR_TSTATE_OBTREE) {
|
||||
t->ot = t->ot->next;
|
||||
t->o.o.state = LFSR_TSTATE_OMDIRS;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags,
|
||||
LFSR_TSTATE_OMDIRS);
|
||||
continue;
|
||||
} else {
|
||||
LFS_UNREACHABLE();
|
||||
@@ -8698,7 +8788,7 @@ dropped:;
|
||||
// swap back dirty/mutated flags
|
||||
t->o.o.flags = lfsr_f_swapdirty(t->o.o.flags);
|
||||
// continue traversal
|
||||
t->o.o.state = LFSR_TSTATE_MDIRS;
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags, LFSR_TSTATE_MDIRS);
|
||||
goto dropped;
|
||||
}
|
||||
}
|
||||
@@ -8767,7 +8857,7 @@ eot:;
|
||||
if (lfsr_t_iscompact(t->o.o.flags)
|
||||
&& !lfsr_f_isdirty(t->o.o.flags)
|
||||
&& !lfsr_f_ismutated(t->o.o.flags)) {
|
||||
lfs->flags &= ~LFS_I_UNCOMPACTED;
|
||||
lfs->flags &= ~LFS_F_UNCOMPACTED;
|
||||
}
|
||||
|
||||
return LFS_ERR_NOENT;
|
||||
@@ -9112,7 +9202,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
// mark any clobbered orphans as zombied
|
||||
if (exists
|
||||
&& o->type == LFS_TYPE_REG
|
||||
&& lfsr_f_type(o->flags) == LFS_TYPE_REG
|
||||
&& o->mdir.mid == mdir.mid) {
|
||||
o->flags = (o->flags & ~LFS_F_ORPHAN)
|
||||
| LFS_F_ZOMBIE
|
||||
@@ -9121,7 +9211,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
|
||||
|
||||
// update dir positions
|
||||
} else if (!exists
|
||||
&& o->type == LFS_TYPE_DIR
|
||||
&& lfsr_f_type(o->flags) == LFS_TYPE_DIR
|
||||
&& ((lfsr_dir_t*)o)->did == did
|
||||
&& o->mdir.mid >= mdir.mid) {
|
||||
((lfsr_dir_t*)o)->pos += 1;
|
||||
@@ -9182,7 +9272,6 @@ empty:;
|
||||
}
|
||||
|
||||
// needed in lfsr_remove
|
||||
static inline bool lfsr_f_iszombie(uint32_t flags);
|
||||
static int lfsr_fs_fixgrm(lfs_t *lfs);
|
||||
|
||||
int lfsr_remove(lfs_t *lfs, const char *path) {
|
||||
@@ -9257,7 +9346,7 @@ int lfsr_remove(lfs_t *lfs, const char *path) {
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
// mark any clobbered orphans as zombied orphans
|
||||
if (zombie
|
||||
&& o->type == LFS_TYPE_REG
|
||||
&& lfsr_f_type(o->flags) == LFS_TYPE_REG
|
||||
&& o->mdir.mid == mdir.mid) {
|
||||
o->flags |= LFS_F_ORPHAN
|
||||
| LFS_F_ZOMBIE
|
||||
@@ -9266,12 +9355,12 @@ int lfsr_remove(lfs_t *lfs, const char *path) {
|
||||
|
||||
// mark any removed dirs as zombied
|
||||
} else if (did_
|
||||
&& o->type == LFS_TYPE_DIR
|
||||
&& lfsr_f_type(o->flags) == LFS_TYPE_DIR
|
||||
&& ((lfsr_dir_t*)o)->did == did_) {
|
||||
o->flags |= LFS_F_ZOMBIE;
|
||||
|
||||
// update dir positions
|
||||
} else if (o->type == LFS_TYPE_DIR
|
||||
} else if (lfsr_f_type(o->flags) == LFS_TYPE_DIR
|
||||
&& ((lfsr_dir_t*)o)->did == did
|
||||
&& o->mdir.mid >= mdir.mid) {
|
||||
if (lfsr_f_iszombie(o->flags)) {
|
||||
@@ -9281,7 +9370,7 @@ int lfsr_remove(lfs_t *lfs, const char *path) {
|
||||
}
|
||||
|
||||
// clobber entangled traversals
|
||||
} else if (o->type == LFS_TYPE_TRAVERSAL) {
|
||||
} else if (lfsr_f_type(o->flags) == LFS_TYPE_TRAVERSAL) {
|
||||
if (lfsr_f_iszombie(o->flags)) {
|
||||
o->flags &= ~LFS_F_ZOMBIE;
|
||||
o->mdir.mid -= 1;
|
||||
@@ -9407,7 +9496,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
// mark any clobbered orphans as zombied
|
||||
if (exists
|
||||
&& o->type == LFS_TYPE_REG
|
||||
&& lfsr_f_type(o->flags) == LFS_TYPE_REG
|
||||
&& o->mdir.mid == new_mdir.mid) {
|
||||
o->flags = (o->flags & ~LFS_F_ORPHAN)
|
||||
| LFS_F_ZOMBIE
|
||||
@@ -9415,18 +9504,18 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
|
||||
| LFS_O_DESYNC;
|
||||
|
||||
// update moved files with the new mdir
|
||||
} else if (o->type == LFS_TYPE_REG
|
||||
} else if (lfsr_f_type(o->flags) == LFS_TYPE_REG
|
||||
&& o->mdir.mid == lfs->grm.mids[0]) {
|
||||
o->mdir = new_mdir;
|
||||
|
||||
// mark any removed dirs as zombied
|
||||
} else if (new_did_
|
||||
&& o->type == LFS_TYPE_DIR
|
||||
&& lfsr_f_type(o->flags) == LFS_TYPE_DIR
|
||||
&& ((lfsr_dir_t*)o)->did == new_did_) {
|
||||
o->flags |= LFS_F_ZOMBIE;
|
||||
|
||||
// update dir positions
|
||||
} else if (o->type == LFS_TYPE_DIR) {
|
||||
} else if (lfsr_f_type(o->flags) == LFS_TYPE_DIR) {
|
||||
if (!exists
|
||||
&& ((lfsr_dir_t*)o)->did == new_did
|
||||
&& o->mdir.mid >= new_mdir.mid) {
|
||||
@@ -9443,7 +9532,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
|
||||
}
|
||||
|
||||
// clobber entangled traversals
|
||||
} else if (o->type == LFS_TYPE_TRAVERSAL
|
||||
} else if (lfsr_f_type(o->flags) == LFS_TYPE_TRAVERSAL
|
||||
&& ((exists && o->mdir.mid == new_mdir.mid)
|
||||
|| o->mdir.mid == lfs->grm.mids[0])) {
|
||||
lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o);
|
||||
@@ -9550,8 +9639,7 @@ int lfsr_dir_open(lfs_t *lfs, lfsr_dir_t *dir, const char *path) {
|
||||
LFS_ASSERT(!lfsr_omdir_isopen(lfs, &dir->o));
|
||||
|
||||
// setup dir state
|
||||
dir->o.type = LFS_TYPE_DIR;
|
||||
dir->o.flags = 0;
|
||||
dir->o.flags = lfsr_f_settype(0, LFS_TYPE_DIR);
|
||||
|
||||
// lookup our directory
|
||||
lfsr_mdir_t mdir;
|
||||
@@ -9772,60 +9860,7 @@ int lfsr_dir_rewind(lfs_t *lfs, lfsr_dir_t *dir) {
|
||||
|
||||
/// File operations ///
|
||||
|
||||
// flag things
|
||||
static inline bool lfsr_o_isrdonly(uint32_t flags) {
|
||||
return (flags & 3) == LFS_O_RDONLY;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_iswronly(uint32_t flags) {
|
||||
return (flags & 3) == LFS_O_WRONLY;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_iscreat(uint32_t flags) {
|
||||
return flags & LFS_O_CREAT;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_isexcl(uint32_t flags) {
|
||||
return flags & LFS_O_EXCL;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_istrunc(uint32_t flags) {
|
||||
return flags & LFS_O_TRUNC;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_isappend(uint32_t flags) {
|
||||
return flags & LFS_O_APPEND;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_isflush(uint32_t flags) {
|
||||
return flags & LFS_O_FLUSH;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_issync(uint32_t flags) {
|
||||
return flags & LFS_O_SYNC;
|
||||
}
|
||||
|
||||
static inline bool lfsr_o_isdesync(uint32_t flags) {
|
||||
return flags & LFS_O_DESYNC;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isunflush(uint32_t flags) {
|
||||
return flags & LFS_F_UNFLUSH;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isunsync(uint32_t flags) {
|
||||
return flags & LFS_F_UNSYNC;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_isorphan(uint32_t flags) {
|
||||
return flags & LFS_F_ORPHAN;
|
||||
}
|
||||
|
||||
static inline bool lfsr_f_iszombie(uint32_t flags) {
|
||||
return flags & LFS_F_ZOMBIE;
|
||||
}
|
||||
|
||||
// other file helpers
|
||||
// file helpers
|
||||
static inline lfs_size_t lfsr_file_buffersize(lfs_t *lfs,
|
||||
const lfsr_file_t *file) {
|
||||
return (file->cfg->buffer_size)
|
||||
@@ -9888,8 +9923,7 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
|
||||
}
|
||||
|
||||
// setup file state
|
||||
file->o.o.type = LFS_TYPE_REG;
|
||||
file->o.o.flags = flags;
|
||||
file->o.o.flags = lfsr_f_settype(flags, LFS_TYPE_REG);
|
||||
file->cfg = cfg;
|
||||
file->pos = 0;
|
||||
file->eblock = 0;
|
||||
@@ -9936,7 +9970,7 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
|
||||
|
||||
// update dir positions
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (o->type == LFS_TYPE_DIR
|
||||
if (lfsr_f_type(o->flags) == LFS_TYPE_DIR
|
||||
&& ((lfsr_dir_t*)o)->did == did
|
||||
&& o->mdir.mid >= file->o.o.mdir.mid) {
|
||||
((lfsr_dir_t*)o)->pos += 1;
|
||||
@@ -11364,7 +11398,7 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
|
||||
|
||||
// update in-device state
|
||||
for (lfsr_omdir_t *o = lfs->omdirs; o; o = o->next) {
|
||||
if (o->type == LFS_TYPE_REG
|
||||
if (lfsr_f_type(o->flags) == LFS_TYPE_REG
|
||||
&& o->mdir.mid == file->o.o.mdir.mid
|
||||
// don't double update
|
||||
&& o != &file->o.o) {
|
||||
@@ -11395,7 +11429,7 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
|
||||
}
|
||||
|
||||
// clobber entangled traversals
|
||||
} else if (o->type == LFS_TYPE_TRAVERSAL
|
||||
} else if (lfsr_f_type(o->flags) == LFS_TYPE_TRAVERSAL
|
||||
&& o->mdir.mid == file->o.o.mdir.mid) {
|
||||
lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o);
|
||||
}
|
||||
@@ -12504,7 +12538,7 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
||||
|
||||
// default to assuming we need a compaction somewhere, worst case this
|
||||
// just makes lfsr_fs_gc read more than is strictly needed
|
||||
lfs->flags |= LFS_I_UNCOMPACTED;
|
||||
lfs->flags |= LFS_F_UNCOMPACTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -12962,7 +12996,7 @@ int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags) {
|
||||
uint32_t pending = flags & (
|
||||
((lfsr_f_hasorphans(lfs->flags)) ? LFS_GC_MKCONSISTENT : 0)
|
||||
| ((lfsr_fs_canlookahead(lfs)) ? LFS_GC_LOOKAHEAD : 0)
|
||||
| ((lfsr_i_isuncompacted(lfs->flags)) ? LFS_GC_COMPACT : 0)
|
||||
| ((lfsr_f_isuncompacted(lfs->flags)) ? LFS_GC_COMPACT : 0)
|
||||
| LFS_GC_CKMETA
|
||||
| LFS_GC_CKDATA);
|
||||
|
||||
@@ -13030,7 +13064,7 @@ int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags) {
|
||||
| ((!lfsr_fs_canlookahead(lfs))
|
||||
? LFS_GC_LOOKAHEAD
|
||||
: 0)
|
||||
| ((!lfsr_i_isuncompacted(lfs->flags))
|
||||
| ((!lfsr_f_isuncompacted(lfs->flags))
|
||||
? LFS_GC_COMPACT
|
||||
: 0)
|
||||
// only consider our filesystem checked if we
|
||||
@@ -13128,8 +13162,7 @@ int lfsr_traversal_open(lfs_t *lfs, lfsr_traversal_t *t, uint32_t flags) {
|
||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
||||
|
||||
// setup traversal state
|
||||
t->o.o.type = LFS_TYPE_TRAVERSAL;
|
||||
t->o.o.flags = flags;
|
||||
t->o.o.flags = lfsr_f_settype(flags, LFS_TYPE_TRAVERSAL);
|
||||
|
||||
// let rewind initialize/reset things
|
||||
int err = lfsr_traversal_rewind_(lfs, t);
|
||||
@@ -13189,7 +13222,7 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
// some redund blocks left over?
|
||||
if (t->blocks[0] != -1) {
|
||||
// write our traversal info
|
||||
tinfo->btype = lfsr_t_btype(t->o.o.flags);
|
||||
tinfo->btype = lfsr_f_btype(t->o.o.flags);
|
||||
tinfo->block = t->blocks[0];
|
||||
|
||||
t->blocks[0] = t->blocks[1];
|
||||
@@ -13209,18 +13242,18 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
// figure out type/blocks
|
||||
if (tag == LFSR_TAG_MDIR) {
|
||||
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer;
|
||||
t->o.o.flags = (t->o.o.flags & ~0x7) | LFS_BTYPE_MDIR;
|
||||
t->o.o.flags = lfsr_f_setbtype(t->o.o.flags, LFS_BTYPE_MDIR);
|
||||
t->blocks[0] = mdir->rbyd.blocks[0];
|
||||
t->blocks[1] = mdir->rbyd.blocks[1];
|
||||
|
||||
} else if (tag == LFSR_TAG_BRANCH) {
|
||||
t->o.o.flags = (t->o.o.flags & ~0x7) | LFS_BTYPE_BTREE;
|
||||
t->o.o.flags = lfsr_f_setbtype(t->o.o.flags, LFS_BTYPE_BTREE);
|
||||
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer;
|
||||
t->blocks[0] = rbyd->blocks[0];
|
||||
t->blocks[1] = -1;
|
||||
|
||||
} else if (tag == LFSR_TAG_BLOCK) {
|
||||
t->o.o.flags = (t->o.o.flags & ~0x7) | LFS_BTYPE_DATA;
|
||||
t->o.o.flags = lfsr_f_setbtype(t->o.o.flags, LFS_BTYPE_DATA);
|
||||
t->blocks[0] = bptr.data.u.disk.block;
|
||||
t->blocks[1] = -1;
|
||||
|
||||
@@ -13233,23 +13266,23 @@ int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *t,
|
||||
static void lfsr_traversal_clobber(lfs_t *lfs, lfsr_traversal_t *t) {
|
||||
(void)lfs;
|
||||
// mroot/mtree? transition to mdir iteration
|
||||
if (t->o.o.state < LFSR_TSTATE_MDIRS) {
|
||||
t->o.o.state = LFSR_TSTATE_MDIRS;
|
||||
if (lfsr_f_tstate(t->o.o.flags) < LFSR_TSTATE_MDIRS) {
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags, LFSR_TSTATE_MDIRS);
|
||||
t->o.o.mdir.mid = 0;
|
||||
t->o.bshrub.u.bshrub.weight = 0;
|
||||
t->o.bshrub.u.bshrub.blocks[0] = -1;
|
||||
t->ot = NULL;
|
||||
// in-mtree mdir? increment the mid (to make progress) and reset to
|
||||
// mdir iteration
|
||||
} else if (t->o.o.state < LFSR_TSTATE_OMDIRS) {
|
||||
t->o.o.state = LFSR_TSTATE_MDIR;
|
||||
} else if (lfsr_f_tstate(t->o.o.flags) < LFSR_TSTATE_OMDIRS) {
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags, LFSR_TSTATE_MDIR);
|
||||
t->o.o.mdir.mid += 1;
|
||||
t->o.bshrub.u.bshrub.weight = 0;
|
||||
t->o.bshrub.u.bshrub.blocks[0] = -1;
|
||||
t->ot = NULL;
|
||||
// opened mdir? skip to next omdir
|
||||
} else if (t->o.o.state < LFSR_TSTATE_DONE) {
|
||||
t->o.o.state = LFSR_TSTATE_OMDIRS;
|
||||
} else if (lfsr_f_tstate(t->o.o.flags) < LFSR_TSTATE_DONE) {
|
||||
t->o.o.flags = lfsr_f_settstate(t->o.o.flags, LFSR_TSTATE_OMDIRS);
|
||||
t->o.bshrub.u.bshrub.weight = 0;
|
||||
t->o.bshrub.u.bshrub.blocks[0] = -1;
|
||||
t->ot = (t->ot) ? t->ot->next : NULL;
|
||||
@@ -13266,8 +13299,9 @@ 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 | LFS_F_MUTATED);
|
||||
t->o.o.state = LFSR_TSTATE_MROOTANCHOR;
|
||||
t->o.o.flags = lfsr_f_settstate(
|
||||
t->o.o.flags & ~(LFS_F_DIRTY | LFS_F_MUTATED),
|
||||
LFSR_TSTATE_MROOTANCHOR);
|
||||
t->o.o.mdir.mid = -1;
|
||||
t->o.o.mdir.rbyd.weight = 0;
|
||||
t->o.o.mdir.rbyd.blocks[0] = -1;
|
||||
|
||||
Reference in New Issue
Block a user