mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Fixed inline files when inline_max == cache_size
The initial implementation of inline files was thrown together fairly quicky, however it has worked well so far and there hasn't been much reason to change it. One shortcut was to trick file writes into thinking they are writing to imaginary blocks. This works well and reuses most of the file code paths, as long as we don't flush the imaginary block out to disk. Initially we did this by limiting inline_max to cache_max-1, ensuring that the cache never fills up and gets flushed. This was a rather dirty hack, the better solution, implemented here, is to handle the representation of an "imaginary" block correctly all the way down into the cache layer. So now for files specifically, the value -1 represents a null pointer, and the value -2 represents an "imaginary" block. This may become a problem if the number of blocks approaches the max, however this -2 value is never written to disk and can be changed in the future without breaking compatibility.
This commit is contained in:
		
							
								
								
									
										9
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -142,7 +142,7 @@ static inline void lfs_cache_zero(lfs_t *lfs, lfs_cache_t *pcache) { | ||||
|  | ||||
| static int lfs_cache_flush(lfs_t *lfs, | ||||
|         lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) { | ||||
|     if (pcache->block != 0xffffffff) { | ||||
|     if (pcache->block != 0xffffffff && pcache->block != 0xfffffffe) { | ||||
|         LFS_ASSERT(pcache->block < lfs->cfg->block_count); | ||||
|         lfs_size_t diff = lfs_alignup(pcache->size, lfs->cfg->prog_size); | ||||
|         int err = lfs->cfg->prog(lfs->cfg, pcache->block, | ||||
| @@ -2158,7 +2158,10 @@ static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) { | ||||
|         return 0; | ||||
|  | ||||
| relocate: | ||||
|         continue; | ||||
|         LFS_DEBUG("Bad block at %"PRIu32, nblock); | ||||
|  | ||||
|         // just clear cache and try a new block | ||||
|         lfs_cache_drop(lfs, &lfs->pcache); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -2397,7 +2400,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, | ||||
|     } | ||||
|  | ||||
|     if ((file->flags & LFS_F_INLINE) && | ||||
|             file->pos + nsize >= lfs->inline_max) { | ||||
|             file->pos + nsize > lfs->inline_max) { | ||||
|         // inline file doesn't fit anymore | ||||
|         file->block = 0xfffffffe; | ||||
|         file->off = file->pos; | ||||
|   | ||||
| @@ -341,6 +341,10 @@ tests/test.py << TEST | ||||
|     } | ||||
|     lfs_file_close(&lfs, &file[0]) => 0; | ||||
|  | ||||
|     // remount to force reset of lookahead | ||||
|     lfs_unmount(&lfs) => 0; | ||||
|     lfs_mount(&lfs, &cfg) => 0; | ||||
|  | ||||
|     // open hole | ||||
|     lfs_remove(&lfs, "bump") => 0; | ||||
|  | ||||
| @@ -350,7 +354,7 @@ tests/test.py << TEST | ||||
|     for (lfs_size_t i = 0; i < cfg.block_size; i += 2) { | ||||
|         memcpy(&buffer[i], "hi", 2); | ||||
|     } | ||||
|     lfs_file_write(&lfs, &file[0], buffer, cfg.block_size) => LFS_ERR_NOSPC; | ||||
|     lfs_file_write(&lfs, &file[0], buffer, 2*cfg.block_size) => LFS_ERR_NOSPC; | ||||
|     lfs_file_close(&lfs, &file[0]) => 0; | ||||
|  | ||||
|     lfs_unmount(&lfs) => 0; | ||||
| @@ -388,7 +392,6 @@ tests/test.py << TEST | ||||
|  | ||||
|     // remount to force reset of lookahead | ||||
|     lfs_unmount(&lfs) => 0; | ||||
|  | ||||
|     lfs_mount(&lfs, &cfg) => 0; | ||||
|  | ||||
|     // rewrite one file | ||||
| @@ -451,7 +454,6 @@ tests/test.py << TEST | ||||
|  | ||||
|     // remount to force reset of lookahead | ||||
|     lfs_unmount(&lfs) => 0; | ||||
|  | ||||
|     lfs_mount(&lfs, &cfg) => 0; | ||||
|  | ||||
|     // rewrite one file with a hole of one block | ||||
|   | ||||
		Reference in New Issue
	
	Block a user