mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 16:14:16 +01:00 
			
		
		
		
	Fixed issue with aggressively rounding down lookahead configuration
The littlefs allows buffers to be passed statically in the case that a system does not have a heap. Unfortunately, this means we can't round up in the case of an unaligned lookahead buffer. Double unfortunately, rounding down after clamping to the block device size could result in a lookahead of zero for block devices < 32 blocks large. The assert in littlefs does catch this case, but rounding down prevents support for < 32 block devices. The solution is to simply require a 32-bit aligned buffer with an assert. This avoids runtime problems while allowing a user to pass in the correct buffer for < 32 block devices. Rounding up can be handled at higher API levels.
This commit is contained in:
		| @@ -15,7 +15,7 @@ script: | |||||||
|     - CFLAGS="-DLFS_READ_SIZE=1   -DLFS_PROG_SIZE=1"   make test |     - CFLAGS="-DLFS_READ_SIZE=1   -DLFS_PROG_SIZE=1"   make test | ||||||
|     - CFLAGS="-DLFS_READ_SIZE=512 -DLFS_PROG_SIZE=512" make test |     - CFLAGS="-DLFS_READ_SIZE=512 -DLFS_PROG_SIZE=512" make test | ||||||
|     - CFLAGS="-DLFS_BLOCK_COUNT=1023" make test |     - CFLAGS="-DLFS_BLOCK_COUNT=1023" make test | ||||||
|     - CFLAGS="-DLFS_LOOKAHEAD=2047"   make test |     - CFLAGS="-DLFS_LOOKAHEAD=2048"   make test | ||||||
|  |  | ||||||
|     # self-host with littlefs-fuse for fuzz test |     # self-host with littlefs-fuse for fuzz test | ||||||
|     - make -C littlefs-fuse |     - make -C littlefs-fuse | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -278,7 +278,7 @@ static int lfs_alloc_lookahead(void *p, lfs_block_t block) { | |||||||
|                 % (lfs_soff_t)(lfs->cfg->block_count)) |                 % (lfs_soff_t)(lfs->cfg->block_count)) | ||||||
|             + lfs->cfg->block_count) % lfs->cfg->block_count; |             + lfs->cfg->block_count) % lfs->cfg->block_count; | ||||||
|  |  | ||||||
|     if (off < lfs->free.lookahead) { |     if (off < lfs->cfg->lookahead) { | ||||||
|         lfs->free.buffer[off / 32] |= 1U << (off % 32); |         lfs->free.buffer[off / 32] |= 1U << (off % 32); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -294,7 +294,8 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { | |||||||
|                 return LFS_ERR_NOSPC; |                 return LFS_ERR_NOSPC; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (lfs->free.off >= lfs->free.lookahead) { |             if (lfs->free.off >= lfs_min( | ||||||
|  |                     lfs->cfg->lookahead, lfs->cfg->block_count)) { | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -308,11 +309,11 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         lfs->free.begin += lfs->free.lookahead; |         lfs->free.begin += lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count); | ||||||
|         lfs->free.off = 0; |         lfs->free.off = 0; | ||||||
|  |  | ||||||
|         // find mask of free blocks from tree |         // find mask of free blocks from tree | ||||||
|         memset(lfs->free.buffer, 0, lfs->free.lookahead/8); |         memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8); | ||||||
|         int err = lfs_traverse(lfs, lfs_alloc_lookahead, lfs); |         int err = lfs_traverse(lfs, lfs_alloc_lookahead, lfs); | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
| @@ -1870,13 +1871,12 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // setup lookahead, round down to nearest 32-bits |     // setup lookahead, round down to nearest 32-bits | ||||||
|     lfs->free.lookahead = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count); |     assert(lfs->cfg->lookahead % 32 == 0); | ||||||
|     lfs->free.lookahead = 32 * (lfs->free.lookahead / 32); |     assert(lfs->cfg->lookahead > 0); | ||||||
|     assert(lfs->free.lookahead > 0); |  | ||||||
|     if (lfs->cfg->lookahead_buffer) { |     if (lfs->cfg->lookahead_buffer) { | ||||||
|         lfs->free.buffer = lfs->cfg->lookahead_buffer; |         lfs->free.buffer = lfs->cfg->lookahead_buffer; | ||||||
|     } else { |     } else { | ||||||
|         lfs->free.buffer = malloc(lfs->free.lookahead/8); |         lfs->free.buffer = malloc(lfs->cfg->lookahead/8); | ||||||
|         if (!lfs->free.buffer) { |         if (!lfs->free.buffer) { | ||||||
|             return LFS_ERR_NOMEM; |             return LFS_ERR_NOMEM; | ||||||
|         } |         } | ||||||
| @@ -1919,7 +1919,7 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // create free lookahead |     // create free lookahead | ||||||
|     memset(lfs->free.buffer, 0, lfs->free.lookahead/8); |     memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8); | ||||||
|     lfs->free.begin = 0; |     lfs->free.begin = 0; | ||||||
|     lfs->free.off = 0; |     lfs->free.off = 0; | ||||||
|     lfs->free.end = lfs->free.begin + lfs->cfg->block_count; |     lfs->free.end = lfs->free.begin + lfs->cfg->block_count; | ||||||
| @@ -1998,8 +1998,8 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // setup free lookahead |     // setup free lookahead | ||||||
|     lfs->free.begin = -lfs->free.lookahead; |     lfs->free.begin = -lfs->cfg->lookahead; | ||||||
|     lfs->free.off = lfs->free.lookahead; |     lfs->free.off = lfs->cfg->lookahead; | ||||||
|     lfs->free.end = lfs->free.begin + lfs->cfg->block_count; |     lfs->free.end = lfs->free.begin + lfs->cfg->block_count; | ||||||
|  |  | ||||||
|     // load superblock |     // load superblock | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user