WIP so close
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user