mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Fixed problem with lookaheads larger than block device
Simply limiting the lookahead region to the size of the block device fixes the problem. Also added logic to limit the allocated region and floor to nearest word, since the additional memory couldn't really be used effectively.
This commit is contained in:
		| @@ -15,3 +15,4 @@ 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 | ||||||
|   | |||||||
							
								
								
									
										45
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -262,12 +262,12 @@ int lfs_deorphan(lfs_t *lfs); | |||||||
| static int lfs_alloc_lookahead(void *p, lfs_block_t block) { | static int lfs_alloc_lookahead(void *p, lfs_block_t block) { | ||||||
|     lfs_t *lfs = p; |     lfs_t *lfs = p; | ||||||
|  |  | ||||||
|     lfs_block_t off = (((lfs_soff_t)(block - lfs->free.start) |     lfs_block_t off = (((lfs_soff_t)(block - lfs->free.begin) | ||||||
|                 % (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->cfg->lookahead) { |     if (off < lfs->free.lookahead) { | ||||||
|         lfs->free.lookahead[off / 32] |= 1U << (off % 32); |         lfs->free.buffer[off / 32] |= 1U << (off % 32); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return 0; |     return 0; | ||||||
| @@ -285,30 +285,30 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { | |||||||
|     while (true) { |     while (true) { | ||||||
|         while (true) { |         while (true) { | ||||||
|             // check if we have looked at all blocks since last ack |             // check if we have looked at all blocks since last ack | ||||||
|             if (lfs->free.start + lfs->free.off == lfs->free.end) { |             if (lfs->free.begin + lfs->free.off == lfs->free.end) { | ||||||
|                 LFS_WARN("No more free space %d", lfs->free.end); |                 LFS_WARN("No more free space %d", lfs->free.end); | ||||||
|                 return LFS_ERR_NOSPC; |                 return LFS_ERR_NOSPC; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (lfs->free.off >= lfs->cfg->lookahead) { |             if (lfs->free.off >= lfs->free.lookahead) { | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             lfs_block_t off = lfs->free.off; |             lfs_block_t off = lfs->free.off; | ||||||
|             lfs->free.off += 1; |             lfs->free.off += 1; | ||||||
|  |  | ||||||
|             if (!(lfs->free.lookahead[off / 32] & (1U << (off % 32)))) { |             if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) { | ||||||
|                 // found a free block |                 // found a free block | ||||||
|                 *block = (lfs->free.start + off) % lfs->cfg->block_count; |                 *block = (lfs->free.begin + off) % lfs->cfg->block_count; | ||||||
|                 return 0; |                 return 0; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         lfs->free.start += lfs->cfg->lookahead; |         lfs->free.begin += lfs->free.lookahead; | ||||||
|         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.lookahead, 0, lfs->cfg->lookahead/8); |         memset(lfs->free.buffer, 0, lfs->free.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; | ||||||
| @@ -317,7 +317,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { | |||||||
| } | } | ||||||
|  |  | ||||||
| static void lfs_alloc_ack(lfs_t *lfs) { | static void lfs_alloc_ack(lfs_t *lfs) { | ||||||
|     lfs->free.end = lfs->free.start + lfs->free.off + lfs->cfg->block_count; |     lfs->free.end = lfs->free.begin + lfs->free.off + lfs->cfg->block_count; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1786,12 +1786,15 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // setup lookahead |     // setup lookahead, round down to nearest 32-bits | ||||||
|  |     lfs->free.lookahead = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count); | ||||||
|  |     lfs->free.lookahead = 32 * (lfs->free.lookahead / 32); | ||||||
|  |     assert(lfs->free.lookahead > 0); | ||||||
|     if (lfs->cfg->lookahead_buffer) { |     if (lfs->cfg->lookahead_buffer) { | ||||||
|         lfs->free.lookahead = lfs->cfg->lookahead_buffer; |         lfs->free.buffer = lfs->cfg->lookahead_buffer; | ||||||
|     } else { |     } else { | ||||||
|         lfs->free.lookahead = malloc(lfs->cfg->lookahead/8); |         lfs->free.buffer = malloc(lfs->free.lookahead/8); | ||||||
|         if (!lfs->free.lookahead) { |         if (!lfs->free.buffer) { | ||||||
|             return LFS_ERR_NOMEM; |             return LFS_ERR_NOMEM; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -1816,7 +1819,7 @@ static int lfs_deinit(lfs_t *lfs) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!lfs->cfg->lookahead_buffer) { |     if (!lfs->cfg->lookahead_buffer) { | ||||||
|         free(lfs->free.lookahead); |         free(lfs->free.buffer); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return 0; |     return 0; | ||||||
| @@ -1829,10 +1832,10 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // create free lookahead |     // create free lookahead | ||||||
|     memset(lfs->free.lookahead, 0, lfs->cfg->lookahead/8); |     memset(lfs->free.buffer, 0, lfs->free.lookahead/8); | ||||||
|     lfs->free.start = 0; |     lfs->free.begin = 0; | ||||||
|     lfs->free.off = 0; |     lfs->free.off = 0; | ||||||
|     lfs->free.end = lfs->free.start + lfs->cfg->block_count; |     lfs->free.end = lfs->free.begin + lfs->cfg->block_count; | ||||||
|  |  | ||||||
|     // create superblock dir |     // create superblock dir | ||||||
|     lfs_alloc_ack(lfs); |     lfs_alloc_ack(lfs); | ||||||
| @@ -1908,9 +1911,9 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // setup free lookahead |     // setup free lookahead | ||||||
|     lfs->free.start = -lfs->cfg->lookahead; |     lfs->free.begin = -lfs->free.lookahead; | ||||||
|     lfs->free.off = lfs->cfg->lookahead; |     lfs->free.off = lfs->free.lookahead; | ||||||
|     lfs->free.end = lfs->free.start + lfs->cfg->block_count; |     lfs->free.end = lfs->free.begin + lfs->cfg->block_count; | ||||||
|  |  | ||||||
|     // load superblock |     // load superblock | ||||||
|     lfs_dir_t dir; |     lfs_dir_t dir; | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								lfs.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								lfs.h
									
									
									
									
									
								
							| @@ -225,10 +225,11 @@ typedef struct lfs_superblock { | |||||||
| } lfs_superblock_t; | } lfs_superblock_t; | ||||||
|  |  | ||||||
| typedef struct lfs_free { | typedef struct lfs_free { | ||||||
|  |     lfs_size_t lookahead; | ||||||
|  |     lfs_block_t begin; | ||||||
|     lfs_block_t end; |     lfs_block_t end; | ||||||
|     lfs_block_t start; |  | ||||||
|     lfs_block_t off; |     lfs_block_t off; | ||||||
|     uint32_t *lookahead; |     uint32_t *buffer; | ||||||
| } lfs_free_t; | } lfs_free_t; | ||||||
|  |  | ||||||
| // The littlefs type | // The littlefs type | ||||||
| @@ -237,12 +238,12 @@ typedef struct lfs { | |||||||
|  |  | ||||||
|     lfs_block_t root[2]; |     lfs_block_t root[2]; | ||||||
|     lfs_file_t *files; |     lfs_file_t *files; | ||||||
|     bool deorphaned; |  | ||||||
|  |  | ||||||
|     lfs_cache_t rcache; |     lfs_cache_t rcache; | ||||||
|     lfs_cache_t pcache; |     lfs_cache_t pcache; | ||||||
|  |  | ||||||
|     lfs_free_t free; |     lfs_free_t free; | ||||||
|  |     bool deorphaned; | ||||||
| } lfs_t; | } lfs_t; | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user