mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Cleaned up config options
- Updated documentation where needed - Added asserts which take into account relationships with the new cache_size configuration - Restructured ordering to be consistent for the three main configurables: LFS_ATTR_MAX, LFS_NAME_MAX, and LFS_INLINE_MAX
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