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
This commit is contained in:
@@ -518,7 +518,10 @@ static int lfs_dir_traverse(lfs_t *lfs,
|
|||||||
|
|
||||||
if (lfs_tag_subtype(tag) == LFS_TYPE_CRC) {
|
if (lfs_tag_subtype(tag) == LFS_TYPE_CRC) {
|
||||||
lastcommit = 2 & lfs_tag_type(tag);
|
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
|
// something was deleted, need to move around it
|
||||||
if (lfs_tag_id(tag) <= lfs_tag_id(matchtag - matchdiff)) {
|
if (lfs_tag_id(tag) <= lfs_tag_id(matchtag - matchdiff)) {
|
||||||
matchdiff -= LFS_MKTAG(0, 1, 0);
|
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
|
// found where something was created
|
||||||
if (lfs_tag_id(tag) == lfs_tag_id(matchtag - matchdiff)) {
|
if (lfs_tag_id(tag) == lfs_tag_id(matchtag - matchdiff)) {
|
||||||
break;
|
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);
|
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);
|
LFS_ASSERT(temp.count > 0);
|
||||||
temp.count -= 1;
|
temp.count -= 1;
|
||||||
|
|
||||||
if (tempfoundtag &&
|
if (tempfoundtag && !lfs_tag_isdelete(tempfoundtag) &&
|
||||||
lfs_tag_id(tag) == lfs_tag_id(tempfoundtag)) {
|
lfs_tag_id(tag) == lfs_tag_id(tempfoundtag)) {
|
||||||
tempfoundtag = 0;
|
tempfoundtag = 0;
|
||||||
} else if (tempfoundtag &&
|
} else if (tempfoundtag &&
|
||||||
@@ -1390,7 +1395,8 @@ commit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// commit with a move
|
// 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++) {
|
for (int pass = 0; pass < 2; pass++) {
|
||||||
err = lfs_commit_move(lfs, &commit, pass,
|
err = lfs_commit_move(lfs, &commit, pass,
|
||||||
0x003fe000, LFS_MKTAG(0, id, 0),
|
0x003fe000, LFS_MKTAG(0, id, 0),
|
||||||
@@ -1556,6 +1562,7 @@ relocate:
|
|||||||
|
|
||||||
static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
|
static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
|
||||||
const struct lfs_mattr *attrs) {
|
const struct lfs_mattr *attrs) {
|
||||||
|
// check for globals work
|
||||||
struct lfs_mattr cancelattr;
|
struct lfs_mattr cancelattr;
|
||||||
struct lfs_globals cancels;
|
struct lfs_globals cancels;
|
||||||
lfs_global_zero(&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
|
// Wait, we have the move? Just cancel this out here
|
||||||
// We need to, or else the move can become outdated
|
// We need to, or else the move can become outdated
|
||||||
cancelattr.tag = LFS_MKTAG(LFS_TYPE_DELETE, lfs->globals.id, 0);
|
cancelattr.tag = LFS_MKTAG(LFS_TYPE_DELETE, lfs->globals.id, 0);
|
||||||
cancelattr.next = attrs; // TODO need order
|
cancelattr.next = attrs;
|
||||||
attrs = &cancelattr;
|
attrs = &cancelattr;
|
||||||
|
|
||||||
cancels.hasmove = lfs->globals.hasmove;
|
cancels.hasmove = lfs->globals.hasmove;
|
||||||
@@ -1584,13 +1591,22 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
|
|||||||
if (lfs_tag_subtype(a->tag) == LFS_TYPE_CREATE) {
|
if (lfs_tag_subtype(a->tag) == LFS_TYPE_CREATE) {
|
||||||
dir->count += 1;
|
dir->count += 1;
|
||||||
createtag = a->tag;
|
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) {
|
} else if (lfs_tag_subtype(a->tag) == LFS_TYPE_DELETE) {
|
||||||
LFS_ASSERT(dir->count > 0);
|
LFS_ASSERT(dir->count > 0);
|
||||||
dir->count -= 1;
|
dir->count -= 1;
|
||||||
deletetag = a->tag;
|
deletetag = a->tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
attrcount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (dir->count == 0) {
|
|
||||||
// should we actually drop the directory block?
|
// should we actually drop the directory block?
|
||||||
|
if (lfs_tag_isvalid(deletetag) && dir->count == 0) {
|
||||||
lfs_mdir_t pdir;
|
lfs_mdir_t pdir;
|
||||||
int err = lfs_fs_pred(lfs, dir->pair, &pdir);
|
int err = lfs_fs_pred(lfs, dir->pair, &pdir);
|
||||||
if (err && err != LFS_ERR_NOENT) {
|
if (err && err != LFS_ERR_NOENT) {
|
||||||
@@ -1601,10 +1617,6 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
|
|||||||
return lfs_dir_drop(lfs, &pdir, dir);
|
return lfs_dir_drop(lfs, &pdir, dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
attrcount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dir->erased) {
|
if (dir->erased) {
|
||||||
// try to commit
|
// try to commit
|
||||||
|
|||||||
Reference in New Issue
Block a user