mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Added better handling of large program sizes (> 1024)
The issue here is how commits handle padding to the nearest program size. This is done by exploiting the size field of the LFS_TYPE_CRC tag that completes the commit. Unfortunately, during developement, the size field shrank in size to make room for more type information, limiting the size field to 1024. Normally this isn't a problem, as very rarely do program sizes exceed 1024 bytes. However, using a simulated block device, user earlephilhower found that exceeding 1024 caused littlefs to crash. To make this corner case behave in a more user friendly manner, I've modified this situtation to treat >1024 program sizes as small commits that don't match the prog size. As a part of this, littlefs also needed to understand that non-matching commits indicate an "unerased" dir block, which would be needed for portability (something which notably lacks testing). This raises the question of if the tag size field size needs to be reconsidered, but to change that at this point would need a new major version. found by earlephilhower
This commit is contained in:
		
							
								
								
									
										8
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -827,7 +827,8 @@ static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs, | |||||||
|             // next commit not yet programmed or we're not in valid range |             // next commit not yet programmed or we're not in valid range | ||||||
|             if (!lfs_tag_isvalid(tag) || |             if (!lfs_tag_isvalid(tag) || | ||||||
|                     off + lfs_tag_dsize(tag) > lfs->cfg->block_size) { |                     off + lfs_tag_dsize(tag) > lfs->cfg->block_size) { | ||||||
|                 dir->erased = (lfs_tag_type1(ptag) == LFS_TYPE_CRC); |                 dir->erased = (lfs_tag_type1(ptag) == LFS_TYPE_CRC && | ||||||
|  |                         dir->off % lfs->cfg->prog_size == 0); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -1596,7 +1597,7 @@ static int lfs_dir_compact(lfs_t *lfs, | |||||||
|             dir->count = end - begin; |             dir->count = end - begin; | ||||||
|             dir->off = commit.off; |             dir->off = commit.off; | ||||||
|             dir->etag = commit.ptag; |             dir->etag = commit.ptag; | ||||||
|             dir->erased = true; |             dir->erased = (dir->off % lfs->cfg->prog_size == 0); | ||||||
|             // note we able to have already handled move here |             // note we able to have already handled move here | ||||||
|             if (lfs_gstate_hasmovehere(&lfs->gpending, dir->pair)) { |             if (lfs_gstate_hasmovehere(&lfs->gpending, dir->pair)) { | ||||||
|                 lfs_gstate_xormove(&lfs->gpending, |                 lfs_gstate_xormove(&lfs->gpending, | ||||||
| @@ -2381,7 +2382,8 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, | |||||||
|         if (file->ctz.size > 0) { |         if (file->ctz.size > 0) { | ||||||
|             lfs_stag_t res = lfs_dir_get(lfs, &file->m, |             lfs_stag_t res = lfs_dir_get(lfs, &file->m, | ||||||
|                     LFS_MKTAG(0x700, 0x3ff, 0), |                     LFS_MKTAG(0x700, 0x3ff, 0), | ||||||
|                     LFS_MKTAG(LFS_TYPE_STRUCT, file->id, file->cache.size), |                     LFS_MKTAG(LFS_TYPE_STRUCT, file->id, | ||||||
|  |                         lfs_min(file->cache.size, 0x3fe)), | ||||||
|                     file->cache.buffer); |                     file->cache.buffer); | ||||||
|             if (res < 0) { |             if (res < 0) { | ||||||
|                 err = res; |                 err = res; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user