Added lfs_fs_mkconsistent

lfs_fs_mkconsistent allows running the internal consistency operations
(desuperblock/deorphan/demove) on demand and without any other
filesystem changes.

This can be useful for front-loading and persisting consistency operations
when you don't want to pay for this cost on the first write to the
filesystem.

Conveniently, this also offers a way to force the on-disk minor version
to bump, if that is wanted behavior.

Idea from kasper0
This commit is contained in:
Christopher Haster
2023-04-26 21:26:40 -05:00
parent 94d9e097a6
commit 259535ee73
3 changed files with 135 additions and 0 deletions
+46
View File
@@ -4887,6 +4887,36 @@ static int lfs_fs_forceconsistency(lfs_t *lfs) {
}
#endif
#ifndef LFS_READONLY
int lfs_fs_rawmkconsistent(lfs_t *lfs) {
// lfs_fs_forceconsistency does most of the work here
int err = lfs_fs_forceconsistency(lfs);
if (err) {
return err;
}
// do we have any pending gstate?
lfs_gstate_t delta = {0};
lfs_gstate_xor(&delta, &lfs->gdisk);
lfs_gstate_xor(&delta, &lfs->gstate);
if (!lfs_gstate_iszero(&delta)) {
// lfs_dir_commit will implicitly write out any pending gstate
lfs_mdir_t root;
err = lfs_dir_fetch(lfs, &root, lfs->root);
if (err) {
return err;
}
err = lfs_dir_commit(lfs, &root, NULL, 0);
if (err) {
return err;
}
}
return 0;
}
#endif
static int lfs_fs_size_count(void *p, lfs_block_t block) {
(void)block;
lfs_size_t *size = p;
@@ -6052,6 +6082,22 @@ int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void *, lfs_block_t), void *data) {
return err;
}
#ifndef LFS_READONLY
int lfs_fs_mkconsistent(lfs_t *lfs) {
int err = LFS_LOCK(lfs->cfg);
if (err) {
return err;
}
LFS_TRACE("lfs_fs_mkconsistent(%p)", (void*)lfs);
err = lfs_fs_rawmkconsistent(lfs);
LFS_TRACE("lfs_fs_mkconsistent -> %d", err);
LFS_UNLOCK(lfs->cfg);
return err;
}
#endif
#ifdef LFS_MIGRATE
int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg) {
int err = LFS_LOCK(cfg);