Implicitly ckpoint alloc in lfsr_mdir_commit, merged prepareappend
All in-flight blocks should be tracked by at least an open file handle
when calling lfsr_mdir_commit. It's the internals of lfsr_mdir_commit
that are really protected by the lfsr_alloc_ckpoint system.
Making lfsr_mdir_commit implicitly call lfsr_alloc_ckpoint removes one
step that was easy to forget, and means we don't need to pepper every
function with lfsr_alloc_ckpoint willy-nilly.
This also merges lfsr_fs_prepareappend -> lfsr_fs_mkconsistent, which
were really two names for the same function. lfsr_fs_grow not calling
lfsr_fs_prepareappend made this name potentially confusing.
Code changes:
code stack
before: 33942 2592
after: 33922 (-0.1%) 2592 (+0.0%)
This commit is contained in:
@@ -6792,6 +6792,9 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
// lfs->mroot must have mid=-1
|
// lfs->mroot must have mid=-1
|
||||||
LFS_ASSERT(lfs->mroot.mid == -1);
|
LFS_ASSERT(lfs->mroot.mid == -1);
|
||||||
|
|
||||||
|
// checkpoint the allocator
|
||||||
|
lfs_alloc_ckpoint(lfs);
|
||||||
|
|
||||||
// play out any attrs that affect our grm _before_ committing to disk,
|
// play out any attrs that affect our grm _before_ committing to disk,
|
||||||
// keep in mind we revert to on-disk gstate if we run into an error
|
// keep in mind we revert to on-disk gstate if we run into an error
|
||||||
lfsr_smid_t mid_ = mdir->mid;
|
lfsr_smid_t mid_ = mdir->mid;
|
||||||
@@ -9127,12 +9130,9 @@ static int lfsr_fs_fixorphans(lfs_t *lfs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prepare the filesystem for mutation
|
// prepare the filesystem for mutation
|
||||||
static int lfsr_fs_preparemutation(lfs_t *lfs) {
|
int lfsr_fs_mkconsistent(lfs_t *lfs) {
|
||||||
// checkpoint the allocator
|
|
||||||
lfs_alloc_ckpoint(lfs);
|
|
||||||
|
|
||||||
// fix pending grms
|
// fix pending grms
|
||||||
bool inconsistent = false;
|
bool wasinconsistent = false;
|
||||||
if (lfsr_grm_hasrm(&lfs->grm)) {
|
if (lfsr_grm_hasrm(&lfs->grm)) {
|
||||||
if (lfsr_grm_count(&lfs->grm) == 2) {
|
if (lfsr_grm_count(&lfs->grm) == 2) {
|
||||||
LFS_DEBUG("Fixing grm "
|
LFS_DEBUG("Fixing grm "
|
||||||
@@ -9146,16 +9146,12 @@ static int lfsr_fs_preparemutation(lfs_t *lfs) {
|
|||||||
lfsr_mid_bid(lfs, lfs->grm.mids[0]) >> lfs->mdir_bits,
|
lfsr_mid_bid(lfs, lfs->grm.mids[0]) >> lfs->mdir_bits,
|
||||||
lfsr_mid_rid(lfs, lfs->grm.mids[0]));
|
lfsr_mid_rid(lfs, lfs->grm.mids[0]));
|
||||||
}
|
}
|
||||||
inconsistent = true;
|
wasinconsistent = true;
|
||||||
|
|
||||||
int err = lfsr_fs_fixgrm(lfs);
|
int err = lfsr_fs_fixgrm(lfs);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkpoint the allocator again since fixgrm completed
|
|
||||||
// some work
|
|
||||||
lfs_alloc_ckpoint(lfs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix orphaned files
|
// fix orphaned files
|
||||||
@@ -9165,28 +9161,20 @@ static int lfsr_fs_preparemutation(lfs_t *lfs) {
|
|||||||
//
|
//
|
||||||
if (lfs->hasorphans) {
|
if (lfs->hasorphans) {
|
||||||
LFS_DEBUG("Fixing orphans...");
|
LFS_DEBUG("Fixing orphans...");
|
||||||
inconsistent = true;
|
wasinconsistent = true;
|
||||||
|
|
||||||
int err = lfsr_fs_fixorphans(lfs);
|
int err = lfsr_fs_fixorphans(lfs);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkpoint the allocator again since fixorphans completed
|
|
||||||
// some work
|
|
||||||
lfs_alloc_ckpoint(lfs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inconsistent) {
|
if (wasinconsistent) {
|
||||||
LFS_DEBUG("littlefs is now consistent");
|
LFS_DEBUG("littlefs is now consistent");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lfsr_fs_mkconsistent(lfs_t *lfs) {
|
|
||||||
return lfsr_fs_preparemutation(lfs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int lfsr_fs_grow(lfs_t *lfs, lfs_size_t block_count_) {
|
int lfsr_fs_grow(lfs_t *lfs, lfs_size_t block_count_) {
|
||||||
// shrinking the filesystem is not supported
|
// shrinking the filesystem is not supported
|
||||||
@@ -9197,15 +9185,14 @@ int lfsr_fs_grow(lfs_t *lfs, lfs_size_t block_count_) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note we do _not_ call lfsr_fs_preparemutation here. This is a bit
|
// Note we do _not_ call lfsr_fs_mkconsistent here. This is a bit scary,
|
||||||
// scary, but we should be ok as long as we patch grms in
|
// but we should be ok as long as we patch grms in lfsr_mdir_commit and
|
||||||
// lfsr_mdir_commit and only commit to the mroot.
|
// only commit to the mroot.
|
||||||
//
|
//
|
||||||
// Calling lfsr_fs_preparemutation risks locking our filesystem up trying
|
// Calling lfsr_fs_mkconsistent risks locking our filesystem up trying
|
||||||
// to fix grms/orphans before we can commit the new filesystem size. If
|
// to fix grms/orphans before we can commit the new filesystem size. If
|
||||||
// we don't, we should always be able to recover a stuck filesystem with
|
// we don't, we should always be able to recover a stuck filesystem with
|
||||||
// lfsr_fs_grow.
|
// lfsr_fs_grow.
|
||||||
//
|
|
||||||
|
|
||||||
LFS_DEBUG("Growing littlefs %"PRId32"x%"PRId32" -> %"PRId32"x%"PRId32,
|
LFS_DEBUG("Growing littlefs %"PRId32"x%"PRId32" -> %"PRId32"x%"PRId32,
|
||||||
lfs->cfg->block_size, lfs->block_count,
|
lfs->cfg->block_size, lfs->block_count,
|
||||||
@@ -9219,7 +9206,6 @@ int lfsr_fs_grow(lfs_t *lfs, lfs_size_t block_count_) {
|
|||||||
lfs->block_count = block_count_;
|
lfs->block_count = block_count_;
|
||||||
// discard stale lookahead buffer
|
// discard stale lookahead buffer
|
||||||
lfs_alloc_discard(lfs);
|
lfs_alloc_discard(lfs);
|
||||||
lfs_alloc_ckpoint(lfs);
|
|
||||||
|
|
||||||
// update our on-disk config
|
// update our on-disk config
|
||||||
int err = lfsr_mdir_commit(lfs, &lfs->mroot, LFSR_ATTRS(
|
int err = lfsr_mdir_commit(lfs, &lfs->mroot, LFSR_ATTRS(
|
||||||
@@ -9253,7 +9239,7 @@ static inline bool lfsr_f_iszombie(uint32_t flags);
|
|||||||
|
|
||||||
int lfsr_mkdir(lfs_t *lfs, const char *path) {
|
int lfsr_mkdir(lfs_t *lfs, const char *path) {
|
||||||
// prepare our filesystem for writing
|
// prepare our filesystem for writing
|
||||||
int err = lfsr_fs_preparemutation(lfs);
|
int err = lfsr_fs_mkconsistent(lfs);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -9417,7 +9403,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
|
|||||||
|
|
||||||
int lfsr_remove(lfs_t *lfs, const char *path) {
|
int lfsr_remove(lfs_t *lfs, const char *path) {
|
||||||
// prepare our filesystem for writing
|
// prepare our filesystem for writing
|
||||||
int err = lfsr_fs_preparemutation(lfs);
|
int err = lfsr_fs_mkconsistent(lfs);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -9548,7 +9534,7 @@ int lfsr_remove(lfs_t *lfs, const char *path) {
|
|||||||
|
|
||||||
int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
|
int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
|
||||||
// prepare our filesystem for writing
|
// prepare our filesystem for writing
|
||||||
int err = lfsr_fs_preparemutation(lfs);
|
int err = lfsr_fs_mkconsistent(lfs);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -10185,7 +10171,7 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
|
|||||||
|
|
||||||
if (!lfsr_o_isrdonly(flags)) {
|
if (!lfsr_o_isrdonly(flags)) {
|
||||||
// prepare our filesystem for writing
|
// prepare our filesystem for writing
|
||||||
int err = lfsr_fs_preparemutation(lfs);
|
int err = lfsr_fs_mkconsistent(lfs);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -11700,7 +11686,6 @@ lfs_ssize_t lfsr_file_write(lfs_t *lfs, lfsr_file_t *file,
|
|||||||
|
|
||||||
// checkpoint the allocator
|
// checkpoint the allocator
|
||||||
lfs_alloc_ckpoint(lfs);
|
lfs_alloc_ckpoint(lfs);
|
||||||
int err;
|
|
||||||
|
|
||||||
// update pos if we are appending
|
// update pos if we are appending
|
||||||
lfs_off_t pos = file->pos;
|
lfs_off_t pos = file->pos;
|
||||||
@@ -11721,6 +11706,7 @@ lfs_ssize_t lfsr_file_write(lfs_t *lfs, lfsr_file_t *file,
|
|||||||
|
|
||||||
const uint8_t *buffer_ = buffer;
|
const uint8_t *buffer_ = buffer;
|
||||||
lfs_size_t written = 0;
|
lfs_size_t written = 0;
|
||||||
|
int err;
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
// bypass buffer?
|
// bypass buffer?
|
||||||
//
|
//
|
||||||
@@ -11860,9 +11846,9 @@ int lfsr_file_flush(lfs_t *lfs, lfsr_file_t *file) {
|
|||||||
|
|
||||||
// checkpoint the allocator
|
// checkpoint the allocator
|
||||||
lfs_alloc_ckpoint(lfs);
|
lfs_alloc_ckpoint(lfs);
|
||||||
int err;
|
|
||||||
|
|
||||||
// flush our buffer if it contains any unwritten data
|
// flush our buffer if it contains any unwritten data
|
||||||
|
int err;
|
||||||
if (lfsr_f_isunflush(file->o.flags)
|
if (lfsr_f_isunflush(file->o.flags)
|
||||||
&& file->buffer.size != 0) {
|
&& file->buffer.size != 0) {
|
||||||
// flush
|
// flush
|
||||||
@@ -11941,9 +11927,6 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkpoint the allocator again
|
|
||||||
lfs_alloc_ckpoint(lfs);
|
|
||||||
|
|
||||||
// commit any changes to our file's metadata
|
// commit any changes to our file's metadata
|
||||||
lfsr_attr_t attrs[2];
|
lfsr_attr_t attrs[2];
|
||||||
lfs_size_t attr_count = 0;
|
lfs_size_t attr_count = 0;
|
||||||
@@ -12136,9 +12119,9 @@ int lfsr_file_truncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
|||||||
|
|
||||||
// checkpoint the allocator
|
// checkpoint the allocator
|
||||||
lfs_alloc_ckpoint(lfs);
|
lfs_alloc_ckpoint(lfs);
|
||||||
int err;
|
|
||||||
|
|
||||||
// does our file become small?
|
// does our file become small?
|
||||||
|
int err;
|
||||||
if (size_ <= lfsr_file_inlinesize(lfs, file)) {
|
if (size_ <= lfsr_file_inlinesize(lfs, file)) {
|
||||||
// if our data is not already in our buffer we unfortunately
|
// if our data is not already in our buffer we unfortunately
|
||||||
// need to flush so our buffer is available to hold everything
|
// need to flush so our buffer is available to hold everything
|
||||||
@@ -12243,9 +12226,9 @@ int lfsr_file_fruncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
|||||||
|
|
||||||
// checkpoint the allocator
|
// checkpoint the allocator
|
||||||
lfs_alloc_ckpoint(lfs);
|
lfs_alloc_ckpoint(lfs);
|
||||||
int err;
|
|
||||||
|
|
||||||
// does our file become small?
|
// does our file become small?
|
||||||
|
int err;
|
||||||
if (size_ <= lfsr_file_inlinesize(lfs, file)) {
|
if (size_ <= lfsr_file_inlinesize(lfs, file)) {
|
||||||
// if our data is not already in our buffer we unfortunately
|
// if our data is not already in our buffer we unfortunately
|
||||||
// need to flush so our buffer is available to hold everything
|
// need to flush so our buffer is available to hold everything
|
||||||
|
|||||||
Reference in New Issue
Block a user