mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Fixed issues found by more aggressive rename tests
- Fixed underflow issue caused by search id shortcuts that would result in early termination from lfs_dir_get - Fixed issue where entry file delete would toss out the best id during lfs_dir_fetchmatch - Fixed globals going out of date when canceling in same metadata-pair - Fixed early removal of metadata-pair when attribute list contains creates after deletes bring dir->count to zero
This commit is contained in:
		
							
								
								
									
										50
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -518,7 +518,10 @@ static int lfs_dir_traverse(lfs_t *lfs, | ||||
|  | ||||
|         if (lfs_tag_subtype(tag) == LFS_TYPE_CRC) { | ||||
|             lastcommit = 2 & lfs_tag_type(tag); | ||||
|         } else if (lfs_tag_subtype(tag) == LFS_TYPE_DELETE) { | ||||
|         } | ||||
|  | ||||
|         if (lfs_tag_id(matchmask) != 0 && | ||||
|                 lfs_tag_subtype(tag) == LFS_TYPE_DELETE) { | ||||
|             // something was deleted, need to move around it | ||||
|             if (lfs_tag_id(tag) <= lfs_tag_id(matchtag - matchdiff)) { | ||||
|                 matchdiff -= LFS_MKTAG(0, 1, 0); | ||||
| @@ -533,11 +536,13 @@ static int lfs_dir_traverse(lfs_t *lfs, | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (lfs_tag_subtype(tag) == LFS_TYPE_CREATE) { | ||||
|         if (lfs_tag_id(matchmask) != 0 && | ||||
|                 lfs_tag_subtype(tag) == LFS_TYPE_CREATE) { | ||||
|             // found where something was created | ||||
|             if (lfs_tag_id(tag) == lfs_tag_id(matchtag - matchdiff)) { | ||||
|                 break; | ||||
|             } else if (lfs_tag_id(tag) < lfs_tag_id(matchtag - matchdiff)) { | ||||
|             } else if (lfs_tag_id(tag) < | ||||
|                     lfs_tag_id(matchtag - matchdiff)) { | ||||
|                 matchdiff += LFS_MKTAG(0, 1, 0); | ||||
|             } | ||||
|         } | ||||
| @@ -686,7 +691,7 @@ static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs, | ||||
|                     LFS_ASSERT(temp.count > 0); | ||||
|                     temp.count -= 1; | ||||
|  | ||||
|                     if (tempfoundtag && | ||||
|                     if (tempfoundtag && !lfs_tag_isdelete(tempfoundtag) && | ||||
|                             lfs_tag_id(tag) == lfs_tag_id(tempfoundtag)) { | ||||
|                         tempfoundtag = 0; | ||||
|                     } else if (tempfoundtag && | ||||
| @@ -1390,7 +1395,8 @@ commit: | ||||
|             } | ||||
|  | ||||
|             // commit with a move | ||||
|             for (uint16_t id = begin; id < end || commit.off < commit.ack; id++) { | ||||
|             for (uint16_t id = begin; | ||||
|                     id < end || commit.off < commit.ack; id++) { | ||||
|                 for (int pass = 0; pass < 2; pass++) { | ||||
|                     err = lfs_commit_move(lfs, &commit, pass, | ||||
|                             0x003fe000, LFS_MKTAG(0, id, 0), | ||||
| @@ -1556,6 +1562,7 @@ relocate: | ||||
|  | ||||
| static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, | ||||
|         const struct lfs_mattr *attrs) { | ||||
|     // check for globals work | ||||
|     struct lfs_mattr cancelattr; | ||||
|     struct lfs_globals cancels; | ||||
|     lfs_global_zero(&cancels); | ||||
| @@ -1564,7 +1571,7 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, | ||||
|         // Wait, we have the move? Just cancel this out here | ||||
|         // We need to, or else the move can become outdated | ||||
|         cancelattr.tag = LFS_MKTAG(LFS_TYPE_DELETE, lfs->globals.id, 0); | ||||
|         cancelattr.next = attrs; // TODO need order | ||||
|         cancelattr.next = attrs; | ||||
|         attrs = &cancelattr; | ||||
|  | ||||
|         cancels.hasmove = lfs->globals.hasmove; | ||||
| @@ -1584,28 +1591,33 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, | ||||
|         if (lfs_tag_subtype(a->tag) == LFS_TYPE_CREATE) { | ||||
|             dir->count += 1; | ||||
|             createtag = a->tag; | ||||
|  | ||||
|             // Oh no, did we tweak globals? We need to fix that too | ||||
|             if (lfs_tag_id(a->tag) <= lfs_tag_id(cancelattr.tag)) { | ||||
|                 cancelattr.tag += LFS_MKTAG(0, 1, 0); | ||||
|             } | ||||
|         } else if (lfs_tag_subtype(a->tag) == LFS_TYPE_DELETE) { | ||||
|             LFS_ASSERT(dir->count > 0); | ||||
|             dir->count -= 1; | ||||
|             deletetag = a->tag; | ||||
|  | ||||
|             if (dir->count == 0) { | ||||
|                 // should we actually drop the directory block? | ||||
|                 lfs_mdir_t pdir; | ||||
|                 int err = lfs_fs_pred(lfs, dir->pair, &pdir); | ||||
|                 if (err && err != LFS_ERR_NOENT) { | ||||
|                     return err; | ||||
|                 } | ||||
|  | ||||
|                 if (err != LFS_ERR_NOENT && pdir.split) { | ||||
|                     return lfs_dir_drop(lfs, &pdir, dir); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         attrcount += 1; | ||||
|     } | ||||
|  | ||||
|     // should we actually drop the directory block? | ||||
|     if (lfs_tag_isvalid(deletetag) && dir->count == 0) { | ||||
|         lfs_mdir_t pdir; | ||||
|         int err = lfs_fs_pred(lfs, dir->pair, &pdir); | ||||
|         if (err && err != LFS_ERR_NOENT) { | ||||
|             return err; | ||||
|         } | ||||
|  | ||||
|         if (err != LFS_ERR_NOENT && pdir.split) { | ||||
|             return lfs_dir_drop(lfs, &pdir, dir); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (dir->erased) { | ||||
|         // try to commit | ||||
|         struct lfs_commit commit = { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user