mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Removed unnecessary randomization of offsets in lfs_alloc_reset
On first read, randomizing the allocators offset may seem appropriate for lfs_alloc_reset. However, it ends up using the filesystem-fed pseudorandom seed in situations it wasn't designed for. As noted by gtaska, the combination of using xors for feeding the seed and multiple traverses of the same CRCs can cause the seed to flip to zeros with concerning frequency. Removed the randomization from lfs_alloc_reset, leaving it in only lfs_mount. Found by gtaska
This commit is contained in:
		
							
								
								
									
										18
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -452,14 +452,16 @@ static int lfs_alloc_lookahead(void *p, lfs_block_t block) { | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // indicate allocated blocks have been committed into the filesystem, this | ||||||
|  | // is to prevent blocks from being garbage collected in the middle of a | ||||||
|  | // commit operation | ||||||
| static void lfs_alloc_ack(lfs_t *lfs) { | static void lfs_alloc_ack(lfs_t *lfs) { | ||||||
|     lfs->free.ack = lfs->cfg->block_count; |     lfs->free.ack = lfs->cfg->block_count; | ||||||
| } | } | ||||||
|  |  | ||||||
| // Invalidate the lookahead buffer. This is done during mounting and | // drop the lookahead buffer, this is done during mounting and failed | ||||||
| // failed traversals | // traversals in order to avoid invalid lookahead state | ||||||
| static void lfs_alloc_reset(lfs_t *lfs) { | static void lfs_alloc_drop(lfs_t *lfs) { | ||||||
|     lfs->free.off = lfs->seed % lfs->cfg->block_count; |  | ||||||
|     lfs->free.size = 0; |     lfs->free.size = 0; | ||||||
|     lfs->free.i = 0; |     lfs->free.i = 0; | ||||||
|     lfs_alloc_ack(lfs); |     lfs_alloc_ack(lfs); | ||||||
| @@ -505,7 +507,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { | |||||||
|         memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size); |         memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size); | ||||||
|         int err = lfs_fs_traverseraw(lfs, lfs_alloc_lookahead, lfs, true); |         int err = lfs_fs_traverseraw(lfs, lfs_alloc_lookahead, lfs, true); | ||||||
|         if (err) { |         if (err) { | ||||||
|             lfs_alloc_reset(lfs); |             lfs_alloc_drop(lfs); | ||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -3797,8 +3799,10 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { | |||||||
|     lfs->gstate.tag += !lfs_tag_isvalid(lfs->gstate.tag); |     lfs->gstate.tag += !lfs_tag_isvalid(lfs->gstate.tag); | ||||||
|     lfs->gdisk = lfs->gstate; |     lfs->gdisk = lfs->gstate; | ||||||
|  |  | ||||||
|     // setup free lookahead |     // setup free lookahead, to distribute allocations uniformly across | ||||||
|     lfs_alloc_reset(lfs); |     // boots, we start the allocator at a random location | ||||||
|  |     lfs->free.off = lfs->seed % lfs->cfg->block_count; | ||||||
|  |     lfs_alloc_drop(lfs); | ||||||
|  |  | ||||||
|     LFS_TRACE("lfs_mount -> %d", 0); |     LFS_TRACE("lfs_mount -> %d", 0); | ||||||
|     return 0; |     return 0; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user