Cleaned up post-mdir-commit state updates a bit
This code is a bit tricky since we need to reference the current mdir to
know how to update other opened mdirs, but then also update the current
mdir, which could also be in the list of opened mdirs. I think a hear a
functional language user laughing in the distance...
code stack
before: 33764 2832
after: 33716 (-0.1%) 2832 (+0.0%)
This commit is contained in:
@@ -6192,10 +6192,9 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
|
||||
// reset gdelta for new commit
|
||||
lfsr_fs_flushgdelta(lfs);
|
||||
|
||||
// parse out any pending gstate, these will get automatically
|
||||
// xored with on-disk gdeltas in lower-level functions
|
||||
for (lfs_size_t i = 0; i < attr_count; i++) {
|
||||
// parse out any pending gstate, these will get automatically
|
||||
// xored with on-disk gdeltas in lower-level functions
|
||||
if (attrs[i].tag == LFSR_TAG_GRM) {
|
||||
// encode to disk
|
||||
lfsr_grm_t *grm = lfsr_attr_grm(&attrs[i]);
|
||||
@@ -6397,7 +6396,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
uint8_t mdir_buf[LFSR_MPTR_DSIZE];
|
||||
uint8_t msibling_buf[LFSR_MPTR_DSIZE];
|
||||
err = lfsr_btree_commit(lfs, &mtree_.u.btree,
|
||||
lfsr_mid_bid(lfs, mdir_.mid), LFSR_ATTRS(
|
||||
lfsr_mid_bid(lfs, mdir->mid), LFSR_ATTRS(
|
||||
LFSR_ATTR(
|
||||
MDIR, 0,
|
||||
FROMMPTR(lfsr_mdir_mptr(&mdir_), mdir_buf)),
|
||||
@@ -6416,8 +6415,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
} else if (err == LFS_ERR_NOENT) {
|
||||
LFS_DEBUG("Dropping mdir %"PRId32" "
|
||||
"0x{%"PRIx32",%"PRIx32"}",
|
||||
mdir_.mid >> lfs->mleaf_bits,
|
||||
mdir_.rbyd.blocks[0], mdir_.rbyd.blocks[1]);
|
||||
mdir->mid >> lfs->mleaf_bits,
|
||||
mdir->rbyd.blocks[0], mdir->rbyd.blocks[1]);
|
||||
|
||||
// consume gstate so we don't lose any info
|
||||
err = lfsr_fs_consumegdelta(lfs, mdir);
|
||||
@@ -6437,7 +6436,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
|
||||
// update our mtree
|
||||
err = lfsr_btree_commit(lfs, &mtree_.u.btree,
|
||||
lfsr_mid_bid(lfs, mdir_.mid), LFSR_ATTRS(
|
||||
lfsr_mid_bid(lfs, mdir->mid), LFSR_ATTRS(
|
||||
LFSR_ATTR(RM, -lfsr_mleafweight(lfs), NULL())));
|
||||
if (err) {
|
||||
return err;
|
||||
@@ -6466,7 +6465,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
// update our mtree
|
||||
uint8_t mdir_buf[LFSR_MPTR_DSIZE];
|
||||
err = lfsr_btree_commit(lfs, &mtree_.u.btree,
|
||||
lfsr_mid_bid(lfs, mdir_.mid), LFSR_ATTRS(
|
||||
lfsr_mid_bid(lfs, mdir->mid), LFSR_ATTRS(
|
||||
LFSR_ATTR(
|
||||
MDIR, 0,
|
||||
FROMMPTR(lfsr_mdir_mptr(&mdir_), mdir_buf))));
|
||||
@@ -6659,56 +6658,24 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
}
|
||||
}
|
||||
|
||||
// success? update in-device state, we must not error at this point
|
||||
|
||||
// update any opened mdirs in our mroot
|
||||
for (lfsr_opened_t *o = lfs->opened; o; o = o->next) {
|
||||
if (lfsr_mdir_cmp(&o->mdir, &lfs->mroot) == 0) {
|
||||
o->mdir.rbyd = mroot_.rbyd;
|
||||
|
||||
// update staged changes
|
||||
if (o->type == LFS_TYPE_REG) {
|
||||
lfsr_file_t *file = (lfsr_file_t*)o;
|
||||
file->bshrub = file->bshrub_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update mroot and mtree
|
||||
lfs->mroot = mroot_;
|
||||
lfs->mtree = mtree_;
|
||||
|
||||
// gstate must have been committed by a lower-level function at this point
|
||||
LFS_ASSERT(lfsr_grm_iszero(lfs->grm_d));
|
||||
|
||||
// TODO merge with attr updates below?
|
||||
// success? update in-device state, we must not error at this point
|
||||
|
||||
// play out any attrs that affect internal state
|
||||
lfsr_smid_t mid = mdir->mid;
|
||||
for (lfs_size_t i = 0; i < attr_count; i++) {
|
||||
// update any gstate
|
||||
// update any gstate changes
|
||||
if (attrs[i].tag == LFSR_TAG_GRM) {
|
||||
lfs->grm = *lfsr_attr_grm(&attrs[i]);
|
||||
|
||||
// keep track of the exact encoding on-disk
|
||||
lfsr_data_fromgrm(&lfs->grm, lfs->grm_g);
|
||||
}
|
||||
}
|
||||
|
||||
for (lfsr_opened_t *o = lfs->opened;
|
||||
o;
|
||||
o = o->next) {
|
||||
// update staged changes
|
||||
if (o->type == LFS_TYPE_REG) {
|
||||
lfsr_file_t *file = (lfsr_file_t*)o;
|
||||
file->bshrub = file->bshrub_;
|
||||
}
|
||||
|
||||
// avoid double updating current mdir
|
||||
if (&o->mdir == mdir) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// first play out any attrs that change our mid
|
||||
lfsr_srid_t mid = mdir->mid;
|
||||
for (lfs_size_t i = 0; i < attr_count; i++) {
|
||||
// adjust any opened mdirs
|
||||
for (lfsr_opened_t *o = lfs->opened; o; o = o->next) {
|
||||
// adjust opened mdirs?
|
||||
if (lfsr_mdir_cmp(&o->mdir, mdir) == 0
|
||||
&& o->mdir.mid >= mid) {
|
||||
@@ -6734,7 +6701,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
((lfsr_dir_t*)(o-1))->pos -= attrs[i].delta;
|
||||
}
|
||||
}
|
||||
} else if (o->mdir.mid > mdir->mid) {
|
||||
} else if (o->mdir.mid > mid) {
|
||||
// adjust dir position?
|
||||
if (o->type == LFS_TYPE_DIR) {
|
||||
((lfsr_dir_t*)o)->pos += attrs[i].delta;
|
||||
@@ -6742,18 +6709,36 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
((lfsr_dir_t*)(o-1))->pos -= attrs[i].delta;
|
||||
}
|
||||
}
|
||||
|
||||
// adjust mid
|
||||
mid += attrs[i].delta;
|
||||
if (lfsr_attr_isinsert(&attrs[i])) {
|
||||
mid -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// update any opened mdirs if we had a split or drop
|
||||
// adjust mid
|
||||
mid += attrs[i].delta;
|
||||
if (lfsr_attr_isinsert(&attrs[i])) {
|
||||
mid -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// update any staged bsprouts/bshrubs
|
||||
for (lfsr_opened_t *o = lfs->opened; o; o = o->next) {
|
||||
if (o->type == LFS_TYPE_REG) {
|
||||
lfsr_file_t *file = (lfsr_file_t*)o;
|
||||
file->bshrub = file->bshrub_;
|
||||
}
|
||||
}
|
||||
|
||||
// update internal mdir state
|
||||
for (lfsr_opened_t *o = lfs->opened; o; o = o->next) {
|
||||
// avoid double updating the current mdir
|
||||
if (&o->mdir == mdir) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// update any splits/drops
|
||||
if (lfsr_mdir_cmp(&o->mdir, mdir) == 0) {
|
||||
LFS_ASSERT(mdir->mid != -1 || mdir == &lfs->mroot);
|
||||
if (mdelta > 0
|
||||
&& lfsr_mid_rid(lfs, o->mdir.mid) >= mdir_.rbyd.weight) {
|
||||
&& lfsr_mid_rid(lfs, o->mdir.mid)
|
||||
>= mdir_.rbyd.weight) {
|
||||
o->mdir.mid += lfsr_mleafweight(lfs) - mdir_.rbyd.weight;
|
||||
o->mdir.rbyd = msibling_.rbyd;
|
||||
} else {
|
||||
@@ -6765,16 +6750,20 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
||||
}
|
||||
|
||||
// update mdir to follow requested rid
|
||||
if (mdir->mid == -1) {
|
||||
mdir->rbyd = lfs->mroot.rbyd;
|
||||
} else if (mdelta > 0
|
||||
&& lfsr_mid_rid(lfs, mdir->mid) >= mdir_.rbyd.weight) {
|
||||
LFS_ASSERT(mdir->mid != -1 || mdir == &lfs->mroot);
|
||||
if (mdelta > 0
|
||||
&& lfsr_mid_rid(lfs, mdir->mid)
|
||||
>= mdir_.rbyd.weight) {
|
||||
mdir->mid += lfsr_mleafweight(lfs) - mdir_.rbyd.weight;
|
||||
mdir->rbyd = msibling_.rbyd;
|
||||
} else {
|
||||
mdir->rbyd = mdir_.rbyd;
|
||||
}
|
||||
|
||||
// update mroot and mtree
|
||||
lfs->mroot = mroot_;
|
||||
lfs->mtree = mtree_;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user