Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/littlefs-project/littlefs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lfs.c
diff options
context:
space:
mode:
authorChristopher Haster <geky@geky.net>2023-12-21 07:56:26 +0300
committerChristopher Haster <geky@geky.net>2024-01-19 22:00:27 +0300
commit8b8fd14187d8b798606f579c49fbd8a0b7d4355c (patch)
treedfe01c6d2355c4250dfe3041e588b27b7c54e9a0 /lfs.c
parent09972a1710a68f245ed2c8cd6f229748edfc1994 (diff)
Added inline_max, to optionally limit the size of inlined filesinline-max
Inlined files live in metadata and decrease storage requirements, but may be limited to improve metadata-related performance. This is especially important given the current plague of metadata performance. Though decreasing inline_max may make metadata more dense and increase block usage, so it's important to benchmark if optimizing for speed. The underlying limits of inlined files haven't changed: 1. Inlined files need to fit in RAM, so <= cache_size 2. Inlined files need to fit in a single attr, so <= attr_max 3. Inlined files need to fit in 1/8 of a block to avoid metadata overflow issues, this is after limiting by metadata_max, so <= min(metadata_max, block_size)/8 By default, the largest possible inline_max is used. This preserves backwards compatibility and is probably a good default for most use cases. This does have the awkward effect of requiring inline_max=-1 to indicate disabled inlined files, but I don't think there's a good way around this.
Diffstat (limited to 'lfs.c')
-rw-r--r--lfs.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/lfs.c b/lfs.c
index 44a8261..93b9b8f 100644
--- a/lfs.c
+++ b/lfs.c
@@ -3524,11 +3524,7 @@ static lfs_ssize_t lfs_file_flushedwrite(lfs_t *lfs, lfs_file_t *file,
lfs_size_t nsize = size;
if ((file->flags & LFS_F_INLINE) &&
- lfs_max(file->pos+nsize, file->ctz.size) >
- lfs_min(0x3fe, lfs_min(
- lfs->cfg->cache_size,
- (lfs->cfg->metadata_max ?
- lfs->cfg->metadata_max : lfs->cfg->block_size) / 8))) {
+ lfs_max(file->pos+nsize, file->ctz.size) > lfs->inline_max) {
// inline file doesn't fit anymore
int err = lfs_file_outline(lfs, file);
if (err) {
@@ -3725,10 +3721,7 @@ static int lfs_file_rawtruncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
lfs_off_t oldsize = lfs_file_rawsize(lfs, file);
if (size < oldsize) {
// revert to inline file?
- if (size <= lfs_min(0x3fe, lfs_min(
- lfs->cfg->cache_size,
- (lfs->cfg->metadata_max ?
- lfs->cfg->metadata_max : lfs->cfg->block_size) / 8))) {
+ if (size <= lfs->inline_max) {
// flush+seek to head
lfs_soff_t res = lfs_file_rawseek(lfs, file, 0, LFS_SEEK_SET);
if (res < 0) {
@@ -4259,6 +4252,27 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
LFS_ASSERT(lfs->cfg->metadata_max <= lfs->cfg->block_size);
+ LFS_ASSERT(lfs->cfg->inline_max == (lfs_size_t)-1
+ || lfs->cfg->inline_max <= lfs->cfg->cache_size);
+ LFS_ASSERT(lfs->cfg->inline_max == (lfs_size_t)-1
+ || lfs->cfg->inline_max <= lfs->attr_max);
+ LFS_ASSERT(lfs->cfg->inline_max == (lfs_size_t)-1
+ || lfs->cfg->inline_max <= ((lfs->cfg->metadata_max)
+ ? lfs->cfg->metadata_max
+ : lfs->cfg->block_size)/8);
+ lfs->inline_max = lfs->cfg->inline_max;
+ if (lfs->inline_max == (lfs_size_t)-1) {
+ lfs->inline_max = 0;
+ } else if (lfs->inline_max == 0) {
+ lfs->inline_max = lfs_min(
+ lfs->cfg->cache_size,
+ lfs_min(
+ lfs->attr_max,
+ ((lfs->cfg->metadata_max)
+ ? lfs->cfg->metadata_max
+ : lfs->cfg->block_size)/8));
+ }
+
// setup default state
lfs->root[0] = LFS_BLOCK_NULL;
lfs->root[1] = LFS_BLOCK_NULL;
@@ -4482,6 +4496,9 @@ static int lfs_rawmount(lfs_t *lfs, const struct lfs_config *cfg) {
}
lfs->attr_max = superblock.attr_max;
+
+ // we also need to update inline_max in case attr_max changed
+ lfs->inline_max = lfs_min(lfs->inline_max, lfs->attr_max);
}
// this is where we get the block_count from disk if block_count=0