mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 00:32:38 +01:00 
			
		
		
		
	lfs: do not reposition seek pointer on truncate
When using lfs_file_truncate() to make a file shorter the file block and off were incorrectly positioned at the new end, resulting in invalid data accessed when reading. Lift the seek pointer restoration to apply to both increasing and reducing truncates. Signed-off-by: Peter A. Bigot <pab@pabigot.com>
This commit is contained in:
		
							
								
								
									
										15
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -2981,6 +2981,7 @@ int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) { | ||||
|         return LFS_ERR_INVAL; | ||||
|     } | ||||
|  | ||||
|     lfs_off_t pos = file->pos; | ||||
|     lfs_off_t oldsize = lfs_file_size(lfs, file); | ||||
|     if (size < oldsize) { | ||||
|         // need to flush since directly changing metadata | ||||
| @@ -3003,8 +3004,6 @@ int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) { | ||||
|         file->ctz.size = size; | ||||
|         file->flags |= LFS_F_DIRTY | LFS_F_READING; | ||||
|     } else if (size > oldsize) { | ||||
|         lfs_off_t pos = file->pos; | ||||
|  | ||||
|         // flush+seek if not already at end | ||||
|         if (file->pos != oldsize) { | ||||
|             int err = lfs_file_seek(lfs, file, 0, LFS_SEEK_END); | ||||
| @@ -3022,13 +3021,13 @@ int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) { | ||||
|                 return res; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|         // restore pos | ||||
|         int err = lfs_file_seek(lfs, file, pos, LFS_SEEK_SET); | ||||
|         if (err < 0) { | ||||
|             LFS_TRACE("lfs_file_truncate -> %d", err); | ||||
|             return err; | ||||
|         } | ||||
|     // restore pos | ||||
|     int err = lfs_file_seek(lfs, file, pos, LFS_SEEK_SET); | ||||
|     if (err < 0) { | ||||
|       LFS_TRACE("lfs_file_truncate -> %d", err); | ||||
|       return err; | ||||
|     } | ||||
|  | ||||
|     LFS_TRACE("lfs_file_truncate -> %d", 0); | ||||
|   | ||||
| @@ -107,6 +107,57 @@ scripts/test.py << TEST | ||||
|     lfs_unmount(&lfs) => 0; | ||||
| TEST | ||||
|  | ||||
| echo "--- Write, truncate, and read ---" | ||||
| scripts/test.py << TEST | ||||
|     lfs_mount(&lfs, &cfg) => 0; | ||||
|     lfs_file_open(&lfs, &file, "sequence", | ||||
|             LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC) => 0; | ||||
|  | ||||
|     lfs_size_t size = lfs.cfg->cache_size; | ||||
|     lfs_size_t qsize = size / 4; | ||||
|     uint8_t *wb = buffer; | ||||
|     uint8_t *rb = buffer + size; | ||||
|     for (lfs_off_t j = 0; j < size; ++j) { | ||||
|         wb[j] = j; | ||||
|     } | ||||
|  | ||||
|     /* Spread sequence over size */ | ||||
|     lfs_file_write(&lfs, &file, wb, size) => size; | ||||
|     lfs_file_size(&lfs, &file) => size; | ||||
|     lfs_file_tell(&lfs, &file) => size; | ||||
|  | ||||
|     lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0; | ||||
|     lfs_file_tell(&lfs, &file) => 0; | ||||
|  | ||||
|     /* Chop off the last quarter */ | ||||
|     lfs_size_t trunc = size - qsize; | ||||
|     lfs_file_truncate(&lfs, &file, trunc) => 0; | ||||
|     lfs_file_tell(&lfs, &file) => 0; | ||||
|     lfs_file_size(&lfs, &file) => trunc; | ||||
|  | ||||
|     /* Read should produce first 3/4 */ | ||||
|     lfs_file_read(&lfs, &file, rb, size) => trunc; | ||||
|     memcmp(rb, wb, trunc) => 0; | ||||
|  | ||||
|     /* Move to 1/4 */ | ||||
|     lfs_file_size(&lfs, &file) => trunc; | ||||
|     lfs_file_seek(&lfs, &file, qsize, LFS_SEEK_SET) => qsize; | ||||
|     lfs_file_tell(&lfs, &file) => qsize; | ||||
|  | ||||
|     /* Chop to 1/2 */ | ||||
|     trunc -= qsize; | ||||
|     lfs_file_truncate(&lfs, &file, trunc) => 0; | ||||
|     lfs_file_tell(&lfs, &file) => qsize; | ||||
|     lfs_file_size(&lfs, &file) => trunc; | ||||
|      | ||||
|     /* Read should produce second quarter */ | ||||
|     lfs_file_read(&lfs, &file, rb, size) => trunc - qsize; | ||||
|     memcmp(rb, wb + qsize, trunc - qsize) => 0; | ||||
|  | ||||
|     lfs_file_close(&lfs, &file) => 0; | ||||
|     lfs_unmount(&lfs) => 0; | ||||
| TEST | ||||
|  | ||||
| echo "--- Truncate and write ---" | ||||
| scripts/test.py << TEST | ||||
|     lfs_mount(&lfs, &cfg) => 0; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user