Changed gc_steps into a runtime parameter, better dedup mount gc

So instead of configuring gc_steps at mount time (or eventually compile
time), lfsr_fs_gc now takes a steps parameter that controls how much gc
work to attempt:

  int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags);

This API was needed internally to better deduplicate on-mount gc, and I
figured it might also be useful for users to be able to easily change
gc_steps per lfsr_fs_gc call.

I realize this could also be accomplished with the theoretical
lfsr_fs_gccfg, but it's a bit easier to not need a struct every call.

Most likely, depending on project/system, users will always call
lfsr_fs_gc with either 1 (minimal work) or -1 (maximal work), or, worst
case, can define a system-wide GC_STEPS somewhere.

---

Deduplicating on-mount gc work better saved some code, though it's worth
noting this could have been done internally and not exposed to users:

           code          stack
  before: 36476           2680 (+0.0%)
  after:  36316 (-0.4%)   2680 (+0.0%)
This commit is contained in:
Christopher Haster
2024-07-17 01:56:12 -05:00
parent 54ecc94702
commit eced943685
5 changed files with 163 additions and 222 deletions
+9 -14
View File
@@ -310,17 +310,6 @@ struct lfs_config {
// can track 8 blocks.
lfs_size_t lookahead_size;
// How many gc steps to perform on each lfsr_fs_gc call.
//
// Each gc step progresses janitorial work by ~1 block (this is equivalent
// to lfsr_traversal_read). More steps per call may make more progress if
// interleaving with other work.
//
// 0 defaults to 1 step, and -1 will perform a full traversal every call,
// though multiple traversals may still be needed to complete all
// janitorial work.
int32_t gc_steps;
// Threshold for metadata compaction during gc in bytes. Metadata logs
// that exceed this threshold will be compacted during gc operations.
// Defaults to ~88% block_size when zero, though this default may change
@@ -1183,14 +1172,20 @@ int lfsr_fs_ckdata(lfs_t *lfs);
#ifndef LFS_READONLY
// Perform any janitorial work that may be pending.
//
// The exact janitorial work depends on the provided flags. Note multiple
// calls may be required to complete all janitorial work.
// The exact janitorial work depends on the provided flags.
//
// The steps parameter controls how many gc steps to progress before
// returning, with each gc step being ~1 block of work. More steps per call
// will make more progress if interleaved with other filesystem writes, but
// may also introduce more latency. steps=1 will do the minimum amount of
// work to make progress, and steps=-1 will not return until all pending
// janitorial work has been completed.
//
// Calling this function is not required, but may allow the offloading of
// expensive janitorial work to a less time-critical code path.
//
// Returns a negative error code on failure.
int lfsr_fs_gc(lfs_t *lfs, uint32_t flags);
int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags);
#endif
#ifndef LFS_READONLY