mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 00:32:38 +01:00 
			
		
		
		
	Fixed issue with long names causing unbounded recursion
This was caused by any commit containing entries large enough to _always_ force a compaction. This would cause littlefs to think that it would need to split infinitely because there was no base case. The fix here is pretty simple: treat any commit with only a single entry as unsplittable. This forces littlefs to first try overcompacting (fitting more in a block than what has optimal runtime), and then failing that return LFS_ERR_NOSPC for higher layers to handle. found by TheLoneWolfling
This commit is contained in:
		
							
								
								
									
										5
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -1414,7 +1414,8 @@ static int lfs_dir_compact(lfs_t *lfs, | ||||
|     bool relocated = false; | ||||
|     bool exhausted = false; | ||||
|  | ||||
|     while (true) { | ||||
|     // should we split? | ||||
|     while (end - begin > 1) { | ||||
|         // find size | ||||
|         lfs_size_t size = 0; | ||||
|         int err = lfs_dir_traverse(lfs, | ||||
| @@ -1429,7 +1430,7 @@ static int lfs_dir_compact(lfs_t *lfs, | ||||
|  | ||||
|         // space is complicated, we need room for tail, crc, gstate, | ||||
|         // cleanup delete, and we cap at half a block to give room | ||||
|         // for metadata updates | ||||
|         // for metadata updates. | ||||
|         if (size <= lfs_min(lfs->cfg->block_size - 36, | ||||
|                 lfs_alignup(lfs->cfg->block_size/2, lfs->cfg->prog_size))) { | ||||
|             break; | ||||
|   | ||||
| @@ -165,5 +165,29 @@ tests/test.py << TEST | ||||
|     lfs_unmount(&lfs) => 0; | ||||
| TEST | ||||
|  | ||||
| echo "--- Really big path test ---" | ||||
| tests/test.py << TEST | ||||
|     lfs_mount(&lfs, &cfg) => 0; | ||||
|     memset(buffer, 'w', LFS_NAME_MAX); | ||||
|     buffer[LFS_NAME_MAX+1] = '\0'; | ||||
|     lfs_mkdir(&lfs, (char*)buffer) => 0; | ||||
|     lfs_remove(&lfs, (char*)buffer) => 0; | ||||
|     lfs_file_open(&lfs, &file[0], (char*)buffer, | ||||
|             LFS_O_WRONLY | LFS_O_CREAT) => 0; | ||||
|     lfs_file_close(&lfs, &file[0]) => 0; | ||||
|     lfs_remove(&lfs, (char*)buffer) => 0; | ||||
|  | ||||
|     memcpy(buffer, "coffee/", strlen("coffee/")); | ||||
|     memset(buffer+strlen("coffee/"), 'w', LFS_NAME_MAX); | ||||
|     buffer[strlen("coffee/")+LFS_NAME_MAX+1] = '\0'; | ||||
|     lfs_mkdir(&lfs, (char*)buffer) => 0; | ||||
|     lfs_remove(&lfs, (char*)buffer) => 0; | ||||
|     lfs_file_open(&lfs, &file[0], (char*)buffer, | ||||
|             LFS_O_WRONLY | LFS_O_CREAT) => 0; | ||||
|     lfs_file_close(&lfs, &file[0]) => 0; | ||||
|     lfs_remove(&lfs, (char*)buffer) => 0; | ||||
|     lfs_unmount(&lfs) => 0; | ||||
| TEST | ||||
|  | ||||
| echo "--- Results ---" | ||||
| tests/stats.py | ||||
|   | ||||
		Reference in New Issue
	
	Block a user