mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 16:14:16 +01:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			v2.3.0
			...
			fix-lookah
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | f935fc0be6 | ||
|  | 6a89ecba39 | 
							
								
								
									
										44
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -270,8 +270,7 @@ int lfs_deorphan(lfs_t *lfs); | ||||
| static int lfs_alloc_lookahead(void *p, lfs_block_t block) { | ||||
|     lfs_t *lfs = p; | ||||
|  | ||||
|     lfs_block_t off = (((lfs_soff_t)(block - lfs->free.begin) | ||||
|                 % (lfs_soff_t)(lfs->cfg->block_count)) | ||||
|     lfs_block_t off = ((block - lfs->free.off) | ||||
|             + lfs->cfg->block_count) % lfs->cfg->block_count; | ||||
|  | ||||
|     if (off < lfs->free.size) { | ||||
| @@ -283,20 +282,22 @@ static int lfs_alloc_lookahead(void *p, lfs_block_t block) { | ||||
|  | ||||
| static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { | ||||
|     while (true) { | ||||
|         while (lfs->free.off != lfs->free.size) { | ||||
|             lfs_block_t off = lfs->free.off; | ||||
|             lfs->free.off += 1; | ||||
|         while (lfs->free.i != lfs->free.size) { | ||||
|             lfs_block_t off = lfs->free.i; | ||||
|             lfs->free.i += 1; | ||||
|             lfs->free.ack -= 1; | ||||
|  | ||||
|             if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) { | ||||
|                 // found a free block | ||||
|                 *block = (lfs->free.begin + off) % lfs->cfg->block_count; | ||||
|                 *block = (lfs->free.off + off) % lfs->cfg->block_count; | ||||
|  | ||||
|                 // eagerly find next off so an alloc ack can | ||||
|                 // discredit old lookahead blocks | ||||
|                 while (lfs->free.off != lfs->free.size && | ||||
|                         (lfs->free.buffer[lfs->free.off / 32] & | ||||
|                             (1U << (lfs->free.off % 32)))) { | ||||
|                     lfs->free.off += 1; | ||||
|                 while (lfs->free.i != lfs->free.size && | ||||
|                         (lfs->free.buffer[lfs->free.i / 32] | ||||
|                             & (1U << (lfs->free.i % 32)))) { | ||||
|                     lfs->free.i += 1; | ||||
|                     lfs->free.ack -= 1; | ||||
|                 } | ||||
|  | ||||
|                 return 0; | ||||
| @@ -304,15 +305,16 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { | ||||
|         } | ||||
|  | ||||
|         // check if we have looked at all blocks since last ack | ||||
|         if (lfs->free.off == lfs->free.ack - lfs->free.begin) { | ||||
|             LFS_WARN("No more free space %d", lfs->free.off + lfs->free.begin); | ||||
|         //if (lfs->free.i == lfs->free.ack - lfs->free.off) { | ||||
|         if (lfs->free.ack == 0) { | ||||
|             LFS_WARN("No more free space %d", lfs->free.i + lfs->free.off); | ||||
|             return LFS_ERR_NOSPC; | ||||
|         } | ||||
|  | ||||
|         lfs->free.begin += lfs->free.size; | ||||
|         lfs->free.size = lfs_min(lfs->cfg->lookahead, | ||||
|                 lfs->free.ack - lfs->free.begin); | ||||
|         lfs->free.off = 0; | ||||
|         lfs->free.off = (lfs->free.off + lfs->free.size) | ||||
|                 % lfs->cfg->block_count; | ||||
|         lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->free.ack); | ||||
|         lfs->free.i = 0; | ||||
|  | ||||
|         // find mask of free blocks from tree | ||||
|         memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8); | ||||
| @@ -324,7 +326,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { | ||||
| } | ||||
|  | ||||
| static void lfs_alloc_ack(lfs_t *lfs) { | ||||
|     lfs->free.ack = lfs->free.begin+lfs->free.off + lfs->cfg->block_count; | ||||
|     lfs->free.ack = lfs->cfg->block_count; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -2103,9 +2105,9 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { | ||||
|  | ||||
|     // create free lookahead | ||||
|     memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8); | ||||
|     lfs->free.begin = 0; | ||||
|     lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count); | ||||
|     lfs->free.off = 0; | ||||
|     lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count); | ||||
|     lfs->free.i = 0; | ||||
|     lfs_alloc_ack(lfs); | ||||
|  | ||||
|     // create superblock dir | ||||
| @@ -2182,9 +2184,9 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { | ||||
|     } | ||||
|  | ||||
|     // setup free lookahead | ||||
|     lfs->free.begin = 0; | ||||
|     lfs->free.size = 0; | ||||
|     lfs->free.off = 0; | ||||
|     lfs->free.size = 0; | ||||
|     lfs->free.i = 0; | ||||
|     lfs_alloc_ack(lfs); | ||||
|  | ||||
|     // load superblock | ||||
|   | ||||
							
								
								
									
										4
									
								
								lfs.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								lfs.h
									
									
									
									
									
								
							| @@ -259,9 +259,9 @@ typedef struct lfs_superblock { | ||||
| } lfs_superblock_t; | ||||
|  | ||||
| typedef struct lfs_free { | ||||
|     lfs_block_t begin; | ||||
|     lfs_block_t size; | ||||
|     lfs_block_t off; | ||||
|     lfs_block_t size; | ||||
|     lfs_block_t i; | ||||
|     lfs_block_t ack; | ||||
|     uint32_t *buffer; | ||||
| } lfs_free_t; | ||||
|   | ||||
| @@ -110,10 +110,35 @@ lfs_alloc_singleproc multiprocreuse | ||||
| lfs_verify multiprocreuse | ||||
| lfs_verify singleprocreuse | ||||
|  | ||||
| echo "--- Cleanup ---" | ||||
| lfs_remove multiprocreuse | ||||
| lfs_remove singleprocreuse | ||||
|  | ||||
| echo "--- Lookahead overflow test ---" | ||||
| lfs_mkdir overflow | ||||
| for name in bacon eggs pancakes | ||||
| do | ||||
| tests/test.py << TEST | ||||
|     lfs_mount(&lfs, &cfg) => 0; | ||||
|  | ||||
| //    // setup lookahead to almost overflow | ||||
| //    lfs.free.begin = ((lfs_size_t)-1) - 2*$SIZE; | ||||
| //    lfs.free.size = 0; | ||||
| //    lfs.free.off = 0; | ||||
|  | ||||
|     lfs_file_open(&lfs, &file[0], "overflow/$name", | ||||
|             LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0; | ||||
|     size = strlen("$name"); | ||||
|     memcpy(buffer, "$name", size); | ||||
|     for (int i = 0; i < $SIZE; i++) { | ||||
|         lfs_file_write(&lfs, &file[0], buffer, size) => size; | ||||
|     } | ||||
|     lfs_file_close(&lfs, &file[0]) => 0; | ||||
|     lfs_unmount(&lfs) => 0; | ||||
| TEST | ||||
| done | ||||
| lfs_verify overflow | ||||
| lfs_remove overflow | ||||
|  | ||||
| echo "--- Exhaustion test ---" | ||||
| tests/test.py << TEST | ||||
|     lfs_mount(&lfs, &cfg) => 0; | ||||
| @@ -368,7 +393,6 @@ echo "--- Outdated lookahead and split dir test ---" | ||||
| rm -rf blocks | ||||
| tests/test.py << TEST | ||||
|     lfs_format(&lfs, &cfg) => 0; | ||||
|  | ||||
|     lfs_mount(&lfs, &cfg) => 0; | ||||
|  | ||||
|     // fill completely with two files | ||||
| @@ -424,5 +448,8 @@ tests/test.py << TEST | ||||
|     lfs_unmount(&lfs) => 0; | ||||
| TEST | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| echo "--- Results ---" | ||||
| tests/stats.py | ||||
|   | ||||
		Reference in New Issue
	
	Block a user