diff options
author | Christopher Haster <chaster@utexas.edu> | 2018-10-21 19:25:48 +0300 |
---|---|---|
committer | Christopher Haster <chaster@utexas.edu> | 2018-10-21 19:25:48 +0300 |
commit | 4a1b8ae22277fbb0901b3b34649aaf0135bbdc73 (patch) | |
tree | b824c41d818bb98c60cbd2e0856704a7209b3d0f | |
parent | c8a39c4b23baa2b1dc5f41c8d0711e205035f4f4 (diff) |
Fixed issues found by more aggressive rename tests
- Fixed underflow issue caused by search id shortcuts that would result
in early termination from lfs_dir_get
- Fixed issue where entry file delete would toss out the best id during
lfs_dir_fetchmatch
- Fixed globals going out of date when canceling in same metadata-pair
- Fixed early removal of metadata-pair when attribute list contains
creates after deletes bring dir->count to zero
-rw-r--r-- | lfs.c | 48 |
1 files changed, 30 insertions, 18 deletions
@@ -518,7 +518,10 @@ static int lfs_dir_traverse(lfs_t *lfs, if (lfs_tag_subtype(tag) == LFS_TYPE_CRC) { lastcommit = 2 & lfs_tag_type(tag); - } else if (lfs_tag_subtype(tag) == LFS_TYPE_DELETE) { + } + + if (lfs_tag_id(matchmask) != 0 && + lfs_tag_subtype(tag) == LFS_TYPE_DELETE) { // something was deleted, need to move around it if (lfs_tag_id(tag) <= lfs_tag_id(matchtag - matchdiff)) { matchdiff -= LFS_MKTAG(0, 1, 0); @@ -533,11 +536,13 @@ static int lfs_dir_traverse(lfs_t *lfs, } } - if (lfs_tag_subtype(tag) == LFS_TYPE_CREATE) { + if (lfs_tag_id(matchmask) != 0 && + lfs_tag_subtype(tag) == LFS_TYPE_CREATE) { // found where something was created if (lfs_tag_id(tag) == lfs_tag_id(matchtag - matchdiff)) { break; - } else if (lfs_tag_id(tag) < lfs_tag_id(matchtag - matchdiff)) { + } else if (lfs_tag_id(tag) < + lfs_tag_id(matchtag - matchdiff)) { matchdiff += LFS_MKTAG(0, 1, 0); } } @@ -686,7 +691,7 @@ static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs, LFS_ASSERT(temp.count > 0); temp.count -= 1; - if (tempfoundtag && + if (tempfoundtag && !lfs_tag_isdelete(tempfoundtag) && lfs_tag_id(tag) == lfs_tag_id(tempfoundtag)) { tempfoundtag = 0; } else if (tempfoundtag && @@ -1390,7 +1395,8 @@ commit: } // commit with a move - for (uint16_t id = begin; id < end || commit.off < commit.ack; id++) { + for (uint16_t id = begin; + id < end || commit.off < commit.ack; id++) { for (int pass = 0; pass < 2; pass++) { err = lfs_commit_move(lfs, &commit, pass, 0x003fe000, LFS_MKTAG(0, id, 0), @@ -1556,6 +1562,7 @@ relocate: static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, const struct lfs_mattr *attrs) { + // check for globals work struct lfs_mattr cancelattr; struct lfs_globals cancels; lfs_global_zero(&cancels); @@ -1564,7 +1571,7 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, // Wait, we have the move? Just cancel this out here // We need to, or else the move can become outdated cancelattr.tag = LFS_MKTAG(LFS_TYPE_DELETE, lfs->globals.id, 0); - cancelattr.next = attrs; // TODO need order + cancelattr.next = attrs; attrs = &cancelattr; cancels.hasmove = lfs->globals.hasmove; @@ -1584,26 +1591,31 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, if (lfs_tag_subtype(a->tag) == LFS_TYPE_CREATE) { dir->count += 1; createtag = a->tag; + + // Oh no, did we tweak globals? We need to fix that too + if (lfs_tag_id(a->tag) <= lfs_tag_id(cancelattr.tag)) { + cancelattr.tag += LFS_MKTAG(0, 1, 0); + } } else if (lfs_tag_subtype(a->tag) == LFS_TYPE_DELETE) { LFS_ASSERT(dir->count > 0); dir->count -= 1; deletetag = a->tag; + } - if (dir->count == 0) { - // should we actually drop the directory block? - lfs_mdir_t pdir; - int err = lfs_fs_pred(lfs, dir->pair, &pdir); - if (err && err != LFS_ERR_NOENT) { - return err; - } + attrcount += 1; + } - if (err != LFS_ERR_NOENT && pdir.split) { - return lfs_dir_drop(lfs, &pdir, dir); - } - } + // should we actually drop the directory block? + if (lfs_tag_isvalid(deletetag) && dir->count == 0) { + lfs_mdir_t pdir; + int err = lfs_fs_pred(lfs, dir->pair, &pdir); + if (err && err != LFS_ERR_NOENT) { + return err; } - attrcount += 1; + if (err != LFS_ERR_NOENT && pdir.split) { + return lfs_dir_drop(lfs, &pdir, dir); + } } if (dir->erased) { |