WIP so close

This commit is contained in:
Christopher Haster
2020-02-28 06:03:59 -06:00
parent f7bc22937a
commit 3ee291de59

222
lfs.c
View File

@@ -1186,27 +1186,34 @@ nextname:
} }
// TODO compact npair -> dir->tail? // TODO compact npair -> dir->tail?
lfs_stag_t ttag = 0; if (lfs_pair_isnull(dir->branch)) {
npair[0] = dir->tail[0];
npair[1] = dir->tail[1];
if (!dir->split) {
// npair[0] = dir->branch[0];
// npair[1] = dir->branch[1];
ttag = lfs_dir_get(lfs, dir,
LFS_MKTAG(0x7ff, 0, 0),
LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)),
npair);
if (ttag < 0 && ttag != LFS_ERR_NOENT) {
return ttag;
}
lfs_pair_fromle32(npair);
assert(ttag == LFS_ERR_NOENT || lfs_pair_cmp(npair, dir->branch) == 0);
}
// ttag may be NOENT or may be marked null explicitly
if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) {
return LFS_ERR_NOENT; return LFS_ERR_NOENT;
} }
npair[0] = dir->branch[0];
npair[1] = dir->branch[1];
// lfs_stag_t ttag = 0;
// npair[0] = dir->tail[0];
// npair[1] = dir->tail[1];
// if (!dir->split) {
//// npair[0] = dir->branch[0];
//// npair[1] = dir->branch[1];
// ttag = lfs_dir_get(lfs, dir,
// LFS_MKTAG(0x7ff, 0, 0),
// LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)),
// npair);
// if (ttag < 0 && ttag != LFS_ERR_NOENT) {
// return ttag;
// }
// lfs_pair_fromle32(npair);
// assert(ttag == LFS_ERR_NOENT || lfs_pair_cmp(npair, dir->branch) == 0);
// }
//
// // ttag may be NOENT or may be marked null explicitly
// if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) {
// return LFS_ERR_NOENT;
// }
} }
// to next name // to next name
@@ -1418,29 +1425,29 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) {
return 0; return 0;
} }
static int lfs_dir_drop(lfs_t *lfs, lfs_mdir_t *dir, lfs_mdir_t *tail) { static int lfs_dir_droptail(lfs_t *lfs, lfs_mdir_t *dir, lfs_mdir_t *tail) {
// steal state // steal state
int err = lfs_dir_getgstate(lfs, tail, &lfs->gdelta); int err = lfs_dir_getgstate(lfs, tail, &lfs->gdelta);
if (err) { if (err) {
return err; return err;
} }
// steal tail's branch // // steal tail's branch
lfs_block_t tbpair[2]; // lfs_block_t tbpair[2];
lfs_stag_t tbtag = lfs_dir_get(lfs, tail, // lfs_stag_t tbtag = lfs_dir_get(lfs, tail,
LFS_MKTAG(0x7ff, 0, 0), // LFS_MKTAG(0x7ff, 0, 0),
LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), tbpair); // LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), tbpair);
if (tbtag < 0 && tbtag != LFS_ERR_NOENT) { // if (tbtag < 0 && tbtag != LFS_ERR_NOENT) {
return tbtag; // return tbtag;
} // }
// steal tail's tail // steal tail's tail
lfs_pair_tole32(tail->tail); lfs_pair_tole32(tail->tail);
err = lfs_dir_commit(lfs, dir, LFS_MKATTRS( err = lfs_dir_commit(lfs, dir, LFS_MKATTRS(
{LFS_MKTAG(LFS_TYPE_TAIL + tail->split, 0x3ff, 8), tail->tail}, {LFS_MKTAG(LFS_TYPE_TAIL + tail->split, 0x3ff, 8), tail->tail}));
{LFS_MKTAG_IF_ELSE(tbtag != LFS_ERR_NOENT, // {LFS_MKTAG_IF_ELSE(tbtag != LFS_ERR_NOENT,
LFS_TYPE_BRANCH, 0x3ff, sizeof(tbpair), // LFS_TYPE_BRANCH, 0x3ff, sizeof(tbpair),
LFS_TYPE_BRANCH, 0x3ff, 0x3ff), tbpair})); // LFS_TYPE_BRANCH, 0x3ff, 0x3ff), tbpair}));
lfs_pair_fromle32(tail->tail); lfs_pair_fromle32(tail->tail);
if (err) { if (err) {
return err; return err;
@@ -1459,13 +1466,15 @@ static int lfs_dir_dropbranch(lfs_t *lfs,
} }
// steal branch's branch // steal branch's branch
lfs_block_t bbpair[2]; dir->branch[0] = branch->branch[0];
lfs_stag_t bbtag = lfs_dir_get(lfs, branch, dir->branch[1] = branch->branch[1];
LFS_MKTAG(0x7ff, 0, 0), // lfs_block_t bbpair[2];
LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), bbpair); // lfs_stag_t bbtag = lfs_dir_get(lfs, branch,
if (bbtag < 0 && bbtag != LFS_ERR_NOENT) { // LFS_MKTAG(0x7ff, 0, 0),
return bbtag; // LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), bbpair);
} // if (bbtag < 0 && bbtag != LFS_ERR_NOENT) {
// return bbtag;
// }
// TODO need mlist? // TODO need mlist?
// TODO endianness? // TODO endianness?
@@ -1473,11 +1482,12 @@ static int lfs_dir_dropbranch(lfs_t *lfs,
lfs_fs_preporphans(lfs, +1); lfs_fs_preporphans(lfs, +1);
// delete branch // delete branch
lfs_block_t branch_[2] = {dir->branch[0], dir->branch[1]}; // TODO need this?
err = lfs_dir_commit(lfs, dir, LFS_MKATTRS( err = lfs_dir_commit(lfs, dir, LFS_MKATTRS(
//{LFS_MKTAG(LFS_TYPE_TAIL + branch->split, 0x3ff, 8), branch->tail}, //{LFS_MKTAG(LFS_TYPE_TAIL + branch->split, 0x3ff, 8), branch->tail},
{LFS_MKTAG_IF_ELSE(bbtag != LFS_ERR_NOENT, {LFS_MKTAG_IF_ELSE(!lfs_pair_isnull(branch_), // bbtag != LFS_ERR_NOENT,
LFS_TYPE_BRANCH, 0x3ff, sizeof(bbpair), LFS_TYPE_BRANCH, 0x3ff, sizeof(branch_),
LFS_TYPE_BRANCH, 0x3ff, 0x3ff), bbpair})); LFS_TYPE_BRANCH, 0x3ff, 0x3ff), branch_}));
if (err) { if (err) {
return err; return err;
} }
@@ -1488,8 +1498,9 @@ static int lfs_dir_dropbranch(lfs_t *lfs,
return err; return err;
} }
// TODO move this out?
lfs_fs_preporphans(lfs, -1); lfs_fs_preporphans(lfs, -1);
err = lfs_dir_drop(lfs, dir, branch); err = lfs_dir_droptail(lfs, dir, branch);
if (err) { if (err) {
return err; return err;
} }
@@ -2007,7 +2018,7 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
// TODO should this actually be handled in _lfs_remove_?? // TODO should this actually be handled in _lfs_remove_??
//printf("hmm1 %d %d\n", err, pdir.split); //printf("hmm1 %d %d\n", err, pdir.split);
if (err != LFS_ERR_NOENT && pdir.split) { if (err != LFS_ERR_NOENT && pdir.split) {
err = lfs_dir_drop(lfs, &pdir, dir); // TODO drop needs to handle branches err = lfs_dir_droptail(lfs, &pdir, dir); // TODO drop needs to handle branches
if (err) { if (err) {
*dir = olddir; *dir = olddir;
return err; return err;
@@ -2386,28 +2397,33 @@ int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) {
while (true) { while (true) {
if (dir->id == dir->m.count) { if (dir->id == dir->m.count) {
lfs_stag_t ttag = 0;
lfs_block_t npair[2] = {dir->m.tail[0], dir->m.tail[1]};
// TODO remove mlist from mkdir! // lfs_stag_t ttag = 0;
if (!dir->m.split) { // lfs_block_t npair[2] = {dir->m.tail[0], dir->m.tail[1]};
ttag = lfs_dir_get(lfs, &dir->m, // // TODO remove mlist from mkdir!
LFS_MKTAG(0x7ff, 0, 0), // if (!dir->m.split) {
LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)), // ttag = lfs_dir_get(lfs, &dir->m,
npair); // LFS_MKTAG(0x7ff, 0, 0),
if (ttag < 0 && ttag != LFS_ERR_NOENT) { // LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)),
return ttag; // npair);
} // if (ttag < 0 && ttag != LFS_ERR_NOENT) {
lfs_pair_fromle32(npair); // return ttag;
} // }
// lfs_pair_fromle32(npair);
// }
// ttag may be NOENT or may be marked null explicitly // ttag may be NOENT or may be marked null explicitly
if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) { //if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) { // TODO rm me
if (lfs_pair_isnull(dir->m.branch)) {
LFS_TRACE("lfs_dir_read -> %d", false); LFS_TRACE("lfs_dir_read -> %d", false);
return false; return false;
} }
// fetch next dir // fetch next dir
int err = lfs_dir_fetch(lfs, &dir->m, npair); // TODO copy out branch in lfs_dir_fetch?
lfs_block_t branch[2] = {dir->m.branch[0], dir->m.branch[1]};
int err = lfs_dir_fetch(lfs, &dir->m, branch);
if (err) { if (err) {
LFS_TRACE("lfs_dir_read -> %d", err); LFS_TRACE("lfs_dir_read -> %d", err);
return err; return err;
@@ -2457,26 +2473,28 @@ int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) {
off -= diff; off -= diff;
if (dir->id == dir->m.count) { if (dir->id == dir->m.count) {
lfs_stag_t ttag = 0; // lfs_stag_t ttag = 0;
lfs_block_t npair[2] = {dir->m.tail[0], dir->m.tail[1]}; // TODO reuse dir tail? // lfs_block_t npair[2] = {dir->m.tail[0], dir->m.tail[1]}; // TODO reuse dir tail?
if (!dir->m.split) { // if (!dir->m.split) {
ttag = lfs_dir_get(lfs, &dir->m, // ttag = lfs_dir_get(lfs, &dir->m,
LFS_MKTAG(0x7ff, 0, 0), // LFS_MKTAG(0x7ff, 0, 0),
LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)), // LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)),
npair); // npair);
if (ttag < 0 && ttag != LFS_ERR_NOENT) { // if (ttag < 0 && ttag != LFS_ERR_NOENT) {
return ttag; // return ttag;
} // }
lfs_pair_fromle32(npair); // lfs_pair_fromle32(npair);
} // }
// ttag may be NOENT or may be marked null explicitly // ttag may be NOENT or may be marked null explicitly
if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) { //if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) { // TODO rm me
if (lfs_pair_isnull(dir->m.branch)) {
LFS_TRACE("lfs_dir_seek -> %d", LFS_ERR_INVAL); LFS_TRACE("lfs_dir_seek -> %d", LFS_ERR_INVAL);
return LFS_ERR_INVAL; return LFS_ERR_INVAL;
} }
err = lfs_dir_fetch(lfs, &dir->m, npair); lfs_block_t branch[2] = {dir->m.branch[0], dir->m.branch[1]};
err = lfs_dir_fetch(lfs, &dir->m, branch);
if (err) { if (err) {
LFS_TRACE("lfs_dir_seek -> %d", err); LFS_TRACE("lfs_dir_seek -> %d", err);
return err; return err;
@@ -3542,7 +3560,7 @@ int lfs_remove(lfs_t *lfs, const char *path) {
return err; return err;
} }
err = lfs_dir_drop(lfs, &cwd, &dir.m); err = lfs_dir_droptail(lfs, &cwd, &dir.m);
if (err) { if (err) {
LFS_TRACE("lfs_remove -> %d", err); LFS_TRACE("lfs_remove -> %d", err);
return err; return err;
@@ -3687,7 +3705,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
return err; return err;
} }
err = lfs_dir_drop(lfs, &newcwd, &prevdir.m); err = lfs_dir_droptail(lfs, &newcwd, &prevdir.m);
if (err) { if (err) {
LFS_TRACE("lfs_rename -> %d", err); LFS_TRACE("lfs_rename -> %d", err);
return err; return err;
@@ -4516,7 +4534,7 @@ static int lfs_fs_deorphan(lfs_t *lfs) {
LFS_DEBUG("Fixing orphan %"PRIx32" %"PRIx32, LFS_DEBUG("Fixing orphan %"PRIx32" %"PRIx32,
pdir.tail[0], pdir.tail[1]); pdir.tail[0], pdir.tail[1]);
err = lfs_dir_drop(lfs, &pdir, &dir); err = lfs_dir_droptail(lfs, &pdir, &dir);
if (err) { if (err) {
return err; return err;
} }
@@ -4525,32 +4543,32 @@ static int lfs_fs_deorphan(lfs_t *lfs) {
continue; continue;
} }
lfs_block_t pair[2]; // lfs_block_t pair[2];
lfs_stag_t res = lfs_dir_get(lfs, &parent, // lfs_stag_t res = lfs_dir_get(lfs, &parent,
LFS_MKTAG(0x7ff, 0x3ff, 0), tag, pair); // LFS_MKTAG(0x7ff, 0x3ff, 0), tag, pair);
if (res < 0) { // if (res < 0) {
return res; // return res;
} // }
lfs_pair_fromle32(pair); // lfs_pair_fromle32(pair);
//
if (!lfs_pair_sync(pair, pdir.tail)) { // if (!lfs_pair_sync(pair, pdir.tail)) {
assert(false); // assert(false);
// we have desynced // // we have desynced
LFS_DEBUG("Fixing half-orphan " // LFS_DEBUG("Fixing half-orphan "
"%"PRIx32" %"PRIx32" -> %"PRIx32" %"PRIx32, // "%"PRIx32" %"PRIx32" -> %"PRIx32" %"PRIx32,
pdir.tail[0], pdir.tail[1], pair[0], pair[1]); // pdir.tail[0], pdir.tail[1], pair[0], pair[1]);
//
lfs_pair_tole32(pair); // lfs_pair_tole32(pair);
err = lfs_dir_commit(lfs, &pdir, LFS_MKATTRS( // err = lfs_dir_commit(lfs, &pdir, LFS_MKATTRS(
{LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 8), pair})); // {LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 8), pair}));
lfs_pair_fromle32(pair); // lfs_pair_fromle32(pair);
if (err) { // if (err) {
return err; // return err;
} // }
//
// refetch tail // // refetch tail
continue; // continue;
} // }
} }
pdir = dir; pdir = dir;