mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Added sticky-bit for preventing file syncs after write errors
Short story, files are no longer committed to directories during file sync/close if the last write did not complete successfully. This avoids a set of interesting user-experience issues related to the end-of-life behaviour of the filesystem. As a filesystem approaches end-of-life, the chances of running into LFS_ERR_NOSPC grows rather quickly. Since this condition occurs after at the end of a devices life, it's likely that operating in these conditions hasn't been tested thoroughly. In the specific case of file-writes, you can hit an LFS_ERR_NOSPC after parts of the file have been written out. If the program simply continues and closes the file, the file is written out half completed. Since littlefs has a strong garuntee the prevents half-writes, it's unlikely this state of the file would be expected. To make things worse, since close is also responsible for memory cleanup, it's actually _impossible_ to continue working as it was without leaking memory. By prevent the file commits, end-of-life behaviour should at least retain a previous copy of the filesystem without any surprises.
This commit is contained in:
		
							
								
								
									
										9
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -1403,7 +1403,9 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) { | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     if ((file->flags & LFS_F_DIRTY) && !lfs_pairisnull(file->pair)) { | ||||
|     if ((file->flags & LFS_F_DIRTY) && | ||||
|             !(file->flags & LFS_F_ERRED) && | ||||
|             !lfs_pairisnull(file->pair)) { | ||||
|         // update dir entry | ||||
|         lfs_dir_t cwd; | ||||
|         int err = lfs_dir_fetch(lfs, &cwd, file->pair); | ||||
| @@ -1537,6 +1539,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, | ||||
|                         file->head, file->size, | ||||
|                         file->pos-1, &file->block, &file->off); | ||||
|                 if (err) { | ||||
|                     file->flags |= LFS_F_ERRED; | ||||
|                     return err; | ||||
|                 } | ||||
|  | ||||
| @@ -1550,6 +1553,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, | ||||
|                     file->block, file->pos, | ||||
|                     &file->block, &file->off); | ||||
|             if (err) { | ||||
|                 file->flags |= LFS_F_ERRED; | ||||
|                 return err; | ||||
|             } | ||||
|  | ||||
| @@ -1565,6 +1569,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, | ||||
|                 if (err == LFS_ERR_CORRUPT) { | ||||
|                     goto relocate; | ||||
|                 } | ||||
|                 file->flags |= LFS_F_ERRED; | ||||
|                 return err; | ||||
|             } | ||||
|  | ||||
| @@ -1572,6 +1577,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, | ||||
| relocate: | ||||
|             err = lfs_file_relocate(lfs, file); | ||||
|             if (err) { | ||||
|                 file->flags |= LFS_F_ERRED; | ||||
|                 return err; | ||||
|             } | ||||
|         } | ||||
| @@ -1584,6 +1590,7 @@ relocate: | ||||
|         lfs_alloc_ack(lfs); | ||||
|     } | ||||
|  | ||||
|     file->flags &= ~LFS_F_ERRED; | ||||
|     return size; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user