mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Removed clamping to block size in ctz linked-list
Initially, I was concerned that the number of pointers in the ctz linked-list could exceed the storage in a block. Long story short this isn't really possible outside of extremely small block sizes. Since clamping impacts the layout of files on disk, removing the block size removed quite a bit of logic and corner cases. Replaced with an assert on block size during initialization. --- Long story long, the minimum block size needed to store all ctz pointers in a filesystem can be found with this formula: B = (w/8)*log2(2^w / (B - 2*(w/8))) where: B = block size in bytes w = pointer width in bits It's not a very pretty formula, but does give us some useful info if we apply some math: min block size: 32 bit ctz linked-list = 104 bytes 64 bit ctz linked-list = 448 bytes For littlefs, 128 bytes is a perfectly reasonable minimum block size.
This commit is contained in:
		
							
								
								
									
										13
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -1005,12 +1005,11 @@ int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir) { | |||||||
| /// File index list operations /// | /// File index list operations /// | ||||||
| static int lfs_index(lfs_t *lfs, lfs_off_t *off) { | static int lfs_index(lfs_t *lfs, lfs_off_t *off) { | ||||||
|     lfs_off_t i = 0; |     lfs_off_t i = 0; | ||||||
|     lfs_size_t words = lfs->cfg->block_size / 4; |  | ||||||
|  |  | ||||||
|     while (*off >= lfs->cfg->block_size) { |     while (*off >= lfs->cfg->block_size) { | ||||||
|         i += 1; |         i += 1; | ||||||
|         *off -= lfs->cfg->block_size; |         *off -= lfs->cfg->block_size; | ||||||
|         *off += 4*lfs_min(lfs_ctz(i)+1, words-1); |         *off += 4*(lfs_ctz(i) + 1); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return i; |     return i; | ||||||
| @@ -1028,12 +1027,11 @@ static int lfs_index_find(lfs_t *lfs, | |||||||
|  |  | ||||||
|     lfs_off_t current = lfs_index(lfs, &(lfs_off_t){size-1}); |     lfs_off_t current = lfs_index(lfs, &(lfs_off_t){size-1}); | ||||||
|     lfs_off_t target = lfs_index(lfs, &pos); |     lfs_off_t target = lfs_index(lfs, &pos); | ||||||
|     lfs_size_t words = lfs->cfg->block_size / 4; |  | ||||||
|  |  | ||||||
|     while (current > target) { |     while (current > target) { | ||||||
|         lfs_size_t skip = lfs_min( |         lfs_size_t skip = lfs_min( | ||||||
|                 lfs_npw2(current-target+1) - 1, |                 lfs_npw2(current-target+1) - 1, | ||||||
|                 lfs_min(lfs_ctz(current)+1, words-1) - 1); |                 lfs_ctz(current)); | ||||||
|  |  | ||||||
|         int err = lfs_cache_read(lfs, rcache, pcache, head, 4*skip, &head, 4); |         int err = lfs_cache_read(lfs, rcache, pcache, head, 4*skip, &head, 4); | ||||||
|         if (err) { |         if (err) { | ||||||
| @@ -1102,8 +1100,7 @@ static int lfs_index_extend(lfs_t *lfs, | |||||||
|  |  | ||||||
|         // append block |         // append block | ||||||
|         index += 1; |         index += 1; | ||||||
|         lfs_size_t words = lfs->cfg->block_size / 4; |         lfs_size_t skips = lfs_ctz(index) + 1; | ||||||
|         lfs_size_t skips = lfs_min(lfs_ctz(index)+1, words-1); |  | ||||||
|  |  | ||||||
|         for (lfs_off_t i = 0; i < skips; i++) { |         for (lfs_off_t i = 0; i < skips; i++) { | ||||||
|             int err = lfs_cache_prog(lfs, pcache, rcache, |             int err = lfs_cache_prog(lfs, pcache, rcache, | ||||||
| @@ -1880,6 +1877,10 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // check that the block size is large enough to fit ctz pointers | ||||||
|  |     assert(4*lfs_npw2(0xffffffff / (lfs->cfg->block_size-2*4)) | ||||||
|  |             <= lfs->cfg->block_size); | ||||||
|  |  | ||||||
|     // setup default state |     // setup default state | ||||||
|     lfs->root[0] = 0xffffffff; |     lfs->root[0] = 0xffffffff; | ||||||
|     lfs->root[1] = 0xffffffff; |     lfs->root[1] = 0xffffffff; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user