mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 00:38:29 +01:00
WIP cleaned up config options
This commit is contained in:
56
lfs.c
56
lfs.c
@@ -2703,6 +2703,16 @@ static inline void lfs_superblocktole32(lfs_superblock_t *superblock) {
|
|||||||
static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
|
static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
|
||||||
lfs->cfg = cfg;
|
lfs->cfg = cfg;
|
||||||
|
|
||||||
|
// check that block size is a multiple of cache size is a multiple
|
||||||
|
// of prog and read sizes
|
||||||
|
LFS_ASSERT(lfs->cfg->cache_size % lfs->cfg->read_size == 0);
|
||||||
|
LFS_ASSERT(lfs->cfg->cache_size % lfs->cfg->prog_size == 0);
|
||||||
|
LFS_ASSERT(lfs->cfg->block_size % lfs->cfg->cache_size == 0);
|
||||||
|
|
||||||
|
// check that the block size is large enough to fit ctz pointers
|
||||||
|
LFS_ASSERT(4*lfs_npw2(0xffffffff / (lfs->cfg->block_size-2*4))
|
||||||
|
<= lfs->cfg->block_size);
|
||||||
|
|
||||||
// setup read cache
|
// setup read cache
|
||||||
lfs->rcache.block = 0xffffffff;
|
lfs->rcache.block = 0xffffffff;
|
||||||
if (lfs->cfg->read_buffer) {
|
if (lfs->cfg->read_buffer) {
|
||||||
@@ -2725,7 +2735,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup lookahead, round down to nearest 32-bits
|
// setup lookahead, must be multiple of 32-bits
|
||||||
LFS_ASSERT(lfs->cfg->lookahead % 32 == 0);
|
LFS_ASSERT(lfs->cfg->lookahead % 32 == 0);
|
||||||
LFS_ASSERT(lfs->cfg->lookahead > 0);
|
LFS_ASSERT(lfs->cfg->lookahead > 0);
|
||||||
if (lfs->cfg->lookahead_buffer) {
|
if (lfs->cfg->lookahead_buffer) {
|
||||||
@@ -2737,22 +2747,12 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that block size is a multiple of cache size is a multiple
|
|
||||||
// of prog and read sizes
|
|
||||||
LFS_ASSERT(lfs->cfg->cache_size % lfs->cfg->read_size == 0);
|
|
||||||
LFS_ASSERT(lfs->cfg->cache_size % lfs->cfg->prog_size == 0);
|
|
||||||
LFS_ASSERT(lfs->cfg->block_size % lfs->cfg->cache_size == 0);
|
|
||||||
|
|
||||||
// check that the block size is large enough to fit ctz pointers
|
|
||||||
LFS_ASSERT(4*lfs_npw2(0xffffffff / (lfs->cfg->block_size-2*4))
|
|
||||||
<= lfs->cfg->block_size);
|
|
||||||
|
|
||||||
// check that the size limits are sane
|
// check that the size limits are sane
|
||||||
LFS_ASSERT(lfs->cfg->inline_size <= LFS_INLINE_MAX);
|
LFS_ASSERT(lfs->cfg->inline_size <= LFS_INLINE_MAX);
|
||||||
LFS_ASSERT(lfs->cfg->inline_size <= lfs->cfg->read_size); // TODO
|
LFS_ASSERT(lfs->cfg->inline_size <= lfs->cfg->cache_size);
|
||||||
lfs->inline_size = lfs->cfg->inline_size;
|
lfs->inline_size = lfs->cfg->inline_size;
|
||||||
if (!lfs->inline_size) {
|
if (!lfs->inline_size) {
|
||||||
lfs->inline_size = lfs_min(LFS_INLINE_MAX, lfs->cfg->read_size);
|
lfs->inline_size = lfs_min(LFS_INLINE_MAX, lfs->cfg->cache_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
LFS_ASSERT(lfs->cfg->attr_size <= LFS_ATTR_MAX);
|
LFS_ASSERT(lfs->cfg->attr_size <= LFS_ATTR_MAX);
|
||||||
@@ -2841,9 +2841,9 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
|
|
||||||
.block_size = lfs->cfg->block_size,
|
.block_size = lfs->cfg->block_size,
|
||||||
.block_count = lfs->cfg->block_count,
|
.block_count = lfs->cfg->block_count,
|
||||||
.inline_size = lfs->inline_size,
|
|
||||||
.attr_size = lfs->attr_size,
|
.attr_size = lfs->attr_size,
|
||||||
.name_size = lfs->name_size,
|
.name_size = lfs->name_size,
|
||||||
|
.inline_size = lfs->inline_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
lfs_superblocktole32(&superblock);
|
lfs_superblocktole32(&superblock);
|
||||||
@@ -2883,9 +2883,6 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
lfs_mdir_t superdir;
|
lfs_mdir_t superdir;
|
||||||
err = lfs_dir_fetch(lfs, &superdir, (const lfs_block_t[2]){0, 1});
|
err = lfs_dir_fetch(lfs, &superdir, (const lfs_block_t[2]){0, 1});
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err == LFS_ERR_CORRUPT) {
|
|
||||||
LFS_ERROR("Invalid superblock at %d %d", 0, 1);
|
|
||||||
}
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2899,8 +2896,8 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
lfs_superblockfromle32(&superblock);
|
lfs_superblockfromle32(&superblock);
|
||||||
|
|
||||||
if (memcmp(superblock.magic, "littlefs", 8) != 0) {
|
if (memcmp(superblock.magic, "littlefs", 8) != 0) {
|
||||||
LFS_ERROR("Invalid superblock at %d %d", 0, 1);
|
LFS_ERROR("Invalid superblock \"%.8s\"", superblock.magic);
|
||||||
return LFS_ERR_CORRUPT;
|
return LFS_ERR_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t major_version = (0xffff & (superblock.version >> 16));
|
uint16_t major_version = (0xffff & (superblock.version >> 16));
|
||||||
@@ -2919,16 +2916,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
}
|
}
|
||||||
lfs_pairfromle32(lfs->root);
|
lfs_pairfromle32(lfs->root);
|
||||||
|
|
||||||
if (superblock.inline_size) {
|
// check superblock configuration
|
||||||
if (superblock.inline_size > lfs->inline_size) {
|
|
||||||
LFS_ERROR("Unsupported inline size (%d > %d)",
|
|
||||||
superblock.inline_size, lfs->inline_size);
|
|
||||||
return LFS_ERR_INVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lfs->inline_size = superblock.inline_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (superblock.attr_size) {
|
if (superblock.attr_size) {
|
||||||
if (superblock.attr_size > lfs->attr_size) {
|
if (superblock.attr_size > lfs->attr_size) {
|
||||||
LFS_ERROR("Unsupported attr size (%d > %d)",
|
LFS_ERROR("Unsupported attr size (%d > %d)",
|
||||||
@@ -2949,6 +2937,16 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
lfs->name_size = superblock.name_size;
|
lfs->name_size = superblock.name_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (superblock.inline_size) {
|
||||||
|
if (superblock.inline_size > lfs->inline_size) {
|
||||||
|
LFS_ERROR("Unsupported inline size (%d > %d)",
|
||||||
|
superblock.inline_size, lfs->inline_size);
|
||||||
|
return LFS_ERR_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
lfs->inline_size = superblock.inline_size;
|
||||||
|
}
|
||||||
|
|
||||||
// scan for any global updates
|
// scan for any global updates
|
||||||
lfs_mdir_t dir = {.tail = {0, 1}};
|
lfs_mdir_t dir = {.tail = {0, 1}};
|
||||||
while (!lfs_pairisnull(dir.tail)) {
|
while (!lfs_pairisnull(dir.tail)) {
|
||||||
|
|||||||
54
lfs.h
54
lfs.h
@@ -50,31 +50,29 @@ typedef int32_t lfs_soff_t;
|
|||||||
|
|
||||||
typedef uint32_t lfs_block_t;
|
typedef uint32_t lfs_block_t;
|
||||||
|
|
||||||
// Maximum inline file size in bytes. Large inline files require a larger
|
|
||||||
// read and prog cache, but if a file can be inline it does not need its own
|
|
||||||
// data block. LFS_ATTR_MAX + LFS_INLINE_MAX must be <= 0xffff. Stored in
|
|
||||||
// superblock and must be respected by other littlefs drivers.
|
|
||||||
// TODO doc
|
|
||||||
#ifndef LFS_INLINE_MAX
|
|
||||||
#define LFS_INLINE_MAX 0xfff
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Maximum size of all attributes per file in bytes, may be redefined but a
|
// Maximum size of all attributes per file in bytes, may be redefined but a
|
||||||
// a smaller LFS_ATTR_MAX has no benefit. LFS_ATTR_MAX + LFS_INLINE_MAX
|
// a smaller LFS_ATTR_MAX has no benefit. Stored in 12-bits and limited
|
||||||
// must be <= 0xffff. Stored in superblock and must be respected by other
|
// to <= 0xfff. Stored in superblock and must be respected by other
|
||||||
// littlefs drivers.
|
// littlefs drivers.
|
||||||
// TODO doc
|
|
||||||
#ifndef LFS_ATTR_MAX
|
#ifndef LFS_ATTR_MAX
|
||||||
#define LFS_ATTR_MAX 0xfff
|
#define LFS_ATTR_MAX 0xfff
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Max name size in bytes, may be redefined to reduce the size of the
|
// Maximum name size in bytes, may be redefined to reduce the size of the
|
||||||
// info struct. Stored in superblock and must be respected by other
|
// info struct. Limited to <= LFS_ATTR_MAX. Stored in superblock and must
|
||||||
// littlefs drivers.
|
// be respected by other littlefs drivers.
|
||||||
#ifndef LFS_NAME_MAX
|
#ifndef LFS_NAME_MAX
|
||||||
#define LFS_NAME_MAX 0xff
|
#define LFS_NAME_MAX 0xff
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Maximum inline file size in bytes. Large inline files require a larger
|
||||||
|
// cache size, but if a file can be inline it does not need its own data
|
||||||
|
// block. Limited to <= LFS_ATTR_MAX and <= cache_size. Stored in superblock
|
||||||
|
// and must be respected by other littlefs drivers.
|
||||||
|
#ifndef LFS_INLINE_MAX
|
||||||
|
#define LFS_INLINE_MAX 0xfff
|
||||||
|
#endif
|
||||||
|
|
||||||
// Possible error codes, these are negative to allow
|
// Possible error codes, these are negative to allow
|
||||||
// valid positive return values
|
// valid positive return values
|
||||||
enum lfs_error {
|
enum lfs_error {
|
||||||
@@ -110,7 +108,7 @@ enum lfs_type {
|
|||||||
LFS_TYPE_TAIL = 0x0c0,
|
LFS_TYPE_TAIL = 0x0c0,
|
||||||
LFS_TYPE_SOFTTAIL = 0x0c0,
|
LFS_TYPE_SOFTTAIL = 0x0c0,
|
||||||
LFS_TYPE_HARDTAIL = 0x0c1,
|
LFS_TYPE_HARDTAIL = 0x0c1,
|
||||||
LFS_TYPE_CRC = 0x0f0, // TODO are trailing ones useful?
|
LFS_TYPE_CRC = 0x0f0,
|
||||||
|
|
||||||
LFS_TYPE_INLINESTRUCT = 0x040,
|
LFS_TYPE_INLINESTRUCT = 0x040,
|
||||||
LFS_TYPE_CTZSTRUCT = 0x041,
|
LFS_TYPE_CTZSTRUCT = 0x041,
|
||||||
@@ -216,15 +214,8 @@ struct lfs_config {
|
|||||||
// lookahead block.
|
// lookahead block.
|
||||||
void *lookahead_buffer;
|
void *lookahead_buffer;
|
||||||
|
|
||||||
// Optional upper limit on inlined files in bytes. Large inline files
|
// Optional upper limit on file attributes in bytes. No downside for larger
|
||||||
// require a larger read and prog cache, but if a file can be inlined it
|
// attributes size but must be less than LFS_ATTR_MAX. Defaults to
|
||||||
// does not need its own data block. Must be smaller than the read size
|
|
||||||
// and prog size. Defaults to min(LFS_INLINE_MAX, read_size) when zero.
|
|
||||||
// Stored in superblock and must be respected by other littlefs drivers.
|
|
||||||
lfs_size_t inline_size;
|
|
||||||
|
|
||||||
// Optional upper limit on attributes per file in bytes. No downside for
|
|
||||||
// larger attributes size but must be less than LFS_ATTR_MAX. Defaults to
|
|
||||||
// LFS_ATTR_MAX when zero.Stored in superblock and must be respected by
|
// LFS_ATTR_MAX when zero.Stored in superblock and must be respected by
|
||||||
// other littlefs drivers.
|
// other littlefs drivers.
|
||||||
lfs_size_t attr_size;
|
lfs_size_t attr_size;
|
||||||
@@ -234,6 +225,13 @@ struct lfs_config {
|
|||||||
// the LFS_NAME_MAX define. Defaults to LFS_NAME_MAX when zero. Stored in
|
// the LFS_NAME_MAX define. Defaults to LFS_NAME_MAX when zero. Stored in
|
||||||
// superblock and must be respected by other littlefs drivers.
|
// superblock and must be respected by other littlefs drivers.
|
||||||
lfs_size_t name_size;
|
lfs_size_t name_size;
|
||||||
|
|
||||||
|
// Optional upper limit on inlined files in bytes. Large inline files
|
||||||
|
// require a larger cache size, but if a file can be inlined it does not
|
||||||
|
// need its own data block. Must be smaller than cache_size and less than
|
||||||
|
// LFS_INLINE_MAX. Defaults to min(LFS_INLINE_MAX, read_size) when zero.
|
||||||
|
// Stored in superblock and must be respected by other littlefs drivers.
|
||||||
|
lfs_size_t inline_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
// File info structure
|
// File info structure
|
||||||
@@ -355,9 +353,9 @@ typedef struct lfs_superblock {
|
|||||||
lfs_size_t block_size;
|
lfs_size_t block_size;
|
||||||
lfs_size_t block_count;
|
lfs_size_t block_count;
|
||||||
|
|
||||||
lfs_size_t inline_size;
|
|
||||||
lfs_size_t attr_size;
|
lfs_size_t attr_size;
|
||||||
lfs_size_t name_size;
|
lfs_size_t name_size;
|
||||||
|
lfs_size_t inline_size;
|
||||||
} lfs_superblock_t;
|
} lfs_superblock_t;
|
||||||
|
|
||||||
typedef struct lfs_free {
|
typedef struct lfs_free {
|
||||||
@@ -381,9 +379,11 @@ typedef struct lfs {
|
|||||||
lfs_free_t free;
|
lfs_free_t free;
|
||||||
|
|
||||||
const struct lfs_config *cfg;
|
const struct lfs_config *cfg;
|
||||||
lfs_size_t inline_size;
|
lfs_size_t block_size;
|
||||||
|
lfs_size_t block_count;
|
||||||
lfs_size_t attr_size;
|
lfs_size_t attr_size;
|
||||||
lfs_size_t name_size;
|
lfs_size_t name_size;
|
||||||
|
lfs_size_t inline_size;
|
||||||
} lfs_t;
|
} lfs_t;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user