mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Fixed corner case in block_cycles eviction logic
The problem was when we allocate a dir-pair, it's possible for the revision count to immediately overflow and the dir-pair be evicted and returned to the unused blocks without being written even once. In the case that block_cycles = 1, this made it impossible to ever create a dir-pair, even in lfs_format. I've also added a bit of logic to lfs_dir_alloc that will prevent any immediate evictions because of the revision count. found by TheLoneWolfling
This commit is contained in:
		
							
								
								
									
										10
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -1316,15 +1316,14 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) { | |||||||
|     int err = lfs_bd_read(lfs, |     int err = lfs_bd_read(lfs, | ||||||
|             NULL, &lfs->rcache, sizeof(dir->rev), |             NULL, &lfs->rcache, sizeof(dir->rev), | ||||||
|             dir->pair[0], 0, &dir->rev, sizeof(dir->rev)); |             dir->pair[0], 0, &dir->rev, sizeof(dir->rev)); | ||||||
|     if (err) { |  | ||||||
|         return err; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     dir->rev = lfs_fromle32(dir->rev); |     dir->rev = lfs_fromle32(dir->rev); | ||||||
|     if (err && err != LFS_ERR_CORRUPT) { |     if (err && err != LFS_ERR_CORRUPT) { | ||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // make sure we don't immediately evict | ||||||
|  |     dir->rev += dir->rev & 1; | ||||||
|  |  | ||||||
|     // set defaults |     // set defaults | ||||||
|     dir->off = sizeof(dir->rev); |     dir->off = sizeof(dir->rev); | ||||||
|     dir->etag = 0xffffffff; |     dir->etag = 0xffffffff; | ||||||
| @@ -1457,7 +1456,8 @@ static int lfs_dir_compact(lfs_t *lfs, | |||||||
|  |  | ||||||
|     // increment revision count |     // increment revision count | ||||||
|     dir->rev += 1; |     dir->rev += 1; | ||||||
|     if (lfs->cfg->block_cycles && dir->rev % lfs->cfg->block_cycles == 0) { |     if (lfs->cfg->block_cycles && | ||||||
|  |             (dir->rev % (lfs->cfg->block_cycles+1) == 0)) { | ||||||
|         if (lfs_pair_cmp(dir->pair, (const lfs_block_t[2]){0, 1}) == 0) { |         if (lfs_pair_cmp(dir->pair, (const lfs_block_t[2]){0, 1}) == 0) { | ||||||
|             // oh no! we're writing too much to the superblock, |             // oh no! we're writing too much to the superblock, | ||||||
|             // should we expand? |             // should we expand? | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user