Fixed issue where fixorphans deleted opened mids

We were just missing a check here to make sure orphaned files aren't
open in-device (these aren't really orphaned because we still have a
reference).

This can't happen during mount, but can happen if fixorphans is
triggered because of an orphaned/zombied file.

Also added a test over this case to prevent regression.

Actually the test was harder to implement than the fix.
This commit is contained in:
Christopher Haster
2024-01-17 02:57:12 -06:00
parent 15593ccc49
commit 3eaee6877c
2 changed files with 252 additions and 26 deletions
+40 -24
View File
@@ -8256,39 +8256,55 @@ static int lfsr_fs_fixorphans(lfs_t *lfs) {
}
while (true) {
// are we an orphaned file?
err = lfsr_mdir_lookup(lfs, &mdir, mdir.mid, LFSR_TAG_ORPHAN,
NULL);
if (err && err != LFS_ERR_NOENT) {
return err;
// is this mid opened? skip
bool notopened = true;
for (lfsr_opened_t *opened = lfs->opened;
opened;
opened = opened->next) {
if (opened->type == LFS_TYPE_REG
&& opened->mdir.mid == mdir.mid) {
notopened = false;
break;
}
}
if (err != LFS_ERR_NOENT) {
// remove orphaned file
err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS(
LFSR_ATTR(mdir.mid, RM, -1, NULL())));
if (err) {
if (notopened) {
// are we an orphaned file?
err = lfsr_mdir_lookup(lfs, &mdir, mdir.mid, LFSR_TAG_ORPHAN,
NULL);
if (err && err != LFS_ERR_NOENT) {
return err;
}
// seek in case our mdir was dropped
err = lfsr_mtree_seek(lfs, &mdir, 0);
if (err) {
if (err == LFS_ERR_NOENT) {
break;
if (err != LFS_ERR_NOENT) {
// remove orphaned file
err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS(
LFSR_ATTR(mdir.mid, RM, -1, NULL())));
if (err) {
return err;
}
return err;
}
} else {
// lookup next entry
err = lfsr_mtree_seek(lfs, &mdir, 1);
if (err) {
if (err == LFS_ERR_NOENT) {
break;
// seek in case our mdir was dropped
err = lfsr_mtree_seek(lfs, &mdir, 0);
if (err) {
if (err == LFS_ERR_NOENT) {
break;
}
return err;
}
return err;
continue;
}
}
// lookup next entry
err = lfsr_mtree_seek(lfs, &mdir, 1);
if (err) {
if (err == LFS_ERR_NOENT) {
break;
}
return err;
}
}
lfs->hasorphans = false;