mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 16:14:16 +01:00 
			
		
		
		
	WIP Fixed issues around wrong ids after bad commits
This commit is contained in:
		
							
								
								
									
										80
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -721,16 +721,18 @@ static int lfs_commit_move(lfs_t *lfs, struct lfs_commit *commit, | |||||||
|  |  | ||||||
| static int lfs_commit_globals(lfs_t *lfs, struct lfs_commit *commit, | static int lfs_commit_globals(lfs_t *lfs, struct lfs_commit *commit, | ||||||
|         const lfs_globals_t *source, const lfs_globals_t *diff) { |         const lfs_globals_t *source, const lfs_globals_t *diff) { | ||||||
|     lfs_globals_t res = lfs_globals_xor(source, diff); |     if (lfs_globals_iszero(diff)) { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (!lfs_globals_iszero(&res)) { |     // TODO check performance/complexity of different strategies here | ||||||
|         int err = lfs_commit_commit(lfs, commit, (lfs_mattr_t){ |     lfs_globals_t res = lfs_globals_xor(source, diff); | ||||||
|                 lfs_mktag(LFS_TYPE_IDELETE, |     int err = lfs_commit_commit(lfs, commit, (lfs_mattr_t){ | ||||||
|                     res.move.id, sizeof(res.move.pair)), |             lfs_mktag(LFS_TYPE_IDELETE, | ||||||
|                     .u.buffer=res.move.pair}); |                 res.move.id, sizeof(res.move.pair)), | ||||||
|         if (err) { |                 .u.buffer=res.move.pair}); | ||||||
|             return err; |     if (err) { | ||||||
|         } |         return err; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return 0; |     return 0; | ||||||
| @@ -878,6 +880,17 @@ static int lfs_dir_fetchwith(lfs_t *lfs, | |||||||
|                 temp.etag = tag; |                 temp.etag = tag; | ||||||
|                 crc = 0xffffffff; |                 crc = 0xffffffff; | ||||||
|                 *dir = temp; |                 *dir = temp; | ||||||
|  |  | ||||||
|  |                 // TODO simplify this? | ||||||
|  |                 if (cb) { | ||||||
|  |                     err = cb(lfs, data, (lfs_mattr_t){ | ||||||
|  |                             (tag | 0x80000000), | ||||||
|  |                             .u.d.block=temp.pair[0], | ||||||
|  |                             .u.d.off=off+sizeof(tag)}); | ||||||
|  |                     if (err) { | ||||||
|  |                         return err; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|             } else { |             } else { | ||||||
|                 // TODO crc before callback??? |                 // TODO crc before callback??? | ||||||
|                 err = lfs_bd_crc(lfs, temp.pair[0], |                 err = lfs_bd_crc(lfs, temp.pair[0], | ||||||
| @@ -1008,6 +1021,11 @@ static int lfs_dir_compact(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list, | |||||||
|     const lfs_block_t oldpair[2] = {dir->pair[1], dir->pair[0]}; |     const lfs_block_t oldpair[2] = {dir->pair[1], dir->pair[0]}; | ||||||
|     bool relocated = false; |     bool relocated = false; | ||||||
|  |  | ||||||
|  |     // There's nothing special about our global delta, so feed it back | ||||||
|  |     // into the global global delta | ||||||
|  |     lfs->diff = lfs_globals_xor(&lfs->diff, &dir->globals); | ||||||
|  |     dir->globals = (lfs_globals_t){0}; | ||||||
|  |  | ||||||
|     // increment revision count |     // increment revision count | ||||||
|     dir->rev += 1; |     dir->rev += 1; | ||||||
|  |  | ||||||
| @@ -1207,14 +1225,12 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list) { | |||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!lfs_globals_iszero(&lfs->diff)) { |         err = lfs_commit_globals(lfs, &commit, &dir->globals, &lfs->diff); | ||||||
|             err = lfs_commit_globals(lfs, &commit, &dir->globals, &lfs->diff); |         if (err) { | ||||||
|             if (err) { |             if (err == LFS_ERR_NOSPC || err == LFS_ERR_CORRUPT) { | ||||||
|                 if (err == LFS_ERR_NOSPC || err == LFS_ERR_CORRUPT) { |                 goto compact; | ||||||
|                     goto compact; |  | ||||||
|                 } |  | ||||||
|                 return err; |  | ||||||
|             } |             } | ||||||
|  |             return err; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         err = lfs_commit_crc(lfs, &commit); |         err = lfs_commit_crc(lfs, &commit); | ||||||
| @@ -1242,6 +1258,7 @@ compact: | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // update any directories that are affected |     // update any directories that are affected | ||||||
|  |     // TODO what about pairs? what if we're splitting?? | ||||||
|     for (lfs_dir_t *d = lfs->dirs; d; d = d->next) { |     for (lfs_dir_t *d = lfs->dirs; d; d = d->next) { | ||||||
|         if (lfs_paircmp(d->m.pair, dir->pair) == 0) { |         if (lfs_paircmp(d->m.pair, dir->pair) == 0) { | ||||||
|             d->m = *dir; |             d->m = *dir; | ||||||
| @@ -1441,6 +1458,7 @@ struct lfs_dir_find { | |||||||
|     const char *name; |     const char *name; | ||||||
|     uint16_t len; |     uint16_t len; | ||||||
|     int16_t id; |     int16_t id; | ||||||
|  |     int16_t tempid; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) { | static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) { | ||||||
| @@ -1456,14 +1474,16 @@ static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) { | |||||||
|  |  | ||||||
|         if (res) { |         if (res) { | ||||||
|             // found a match |             // found a match | ||||||
|             find->id = lfs_tag_id(attr.tag); |             find->tempid = lfs_tag_id(attr.tag); | ||||||
|         } |         } | ||||||
|     } else if (lfs_tag_type(attr.tag) == LFS_STRUCT_DELETE) { |     } else if (lfs_tag_type(attr.tag) == LFS_STRUCT_DELETE) { | ||||||
|         if (lfs_tag_id(attr.tag) == find->id) { |         if (lfs_tag_id(attr.tag) == find->tempid) { | ||||||
|             find->id = -1; |             find->tempid = -1; | ||||||
|         } else if (lfs_tag_id(attr.tag) < find->id) { |         } else if (lfs_tag_id(attr.tag) < find->tempid) { | ||||||
|             find->id -= 1; |             find->tempid -= 1; | ||||||
|         } |         } | ||||||
|  |     } else if (lfs_tag_type(attr.tag) == LFS_TYPE_CRC) { | ||||||
|  |         find->id = find->tempid; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return 0; |     return 0; | ||||||
| @@ -1531,6 +1551,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, | |||||||
|         while (true) { |         while (true) { | ||||||
|             //printf("checking %d %d for %s\n", attr.u.pair[0], attr.u.pair[1], *path); |             //printf("checking %d %d for %s\n", attr.u.pair[0], attr.u.pair[1], *path); | ||||||
|             find.id = -1; |             find.id = -1; | ||||||
|  |             find.tempid = -1; | ||||||
|             int err = lfs_dir_fetchwith(lfs, dir, attr.u.pair, |             int err = lfs_dir_fetchwith(lfs, dir, attr.u.pair, | ||||||
|                     lfs_dir_findscan, &find); |                     lfs_dir_findscan, &find); | ||||||
|             if (err) { |             if (err) { | ||||||
| @@ -3451,9 +3472,11 @@ static int lfs_pred(lfs_t *lfs, const lfs_block_t dir[2], lfs_mdir_t *pdir) { | |||||||
| */ | */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // TODO combine parentscan and findscan? | ||||||
| struct lfs_dir_parentscan { | struct lfs_dir_parentscan { | ||||||
|     lfs_block_t pair[2]; |     lfs_block_t pair[2]; | ||||||
|     int16_t id; |     int16_t id; | ||||||
|  |     int16_t tempid; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static int lfs_parentscan(lfs_t *lfs, void *p, lfs_mattr_t attr) { | static int lfs_parentscan(lfs_t *lfs, void *p, lfs_mattr_t attr) { | ||||||
| @@ -3468,14 +3491,16 @@ static int lfs_parentscan(lfs_t *lfs, void *p, lfs_mattr_t attr) { | |||||||
|  |  | ||||||
|         if (lfs_paircmp(attr.u.pair, parentscan->pair) == 0) { |         if (lfs_paircmp(attr.u.pair, parentscan->pair) == 0) { | ||||||
|             // found a match |             // found a match | ||||||
|             parentscan->id = lfs_tag_id(attr.tag); |             parentscan->tempid = lfs_tag_id(attr.tag); | ||||||
|         } |         } | ||||||
|     } else if (lfs_tag_struct(attr.tag) == LFS_STRUCT_DELETE) { |     } else if (lfs_tag_struct(attr.tag) == LFS_STRUCT_DELETE) { | ||||||
|         if (lfs_tag_id(attr.tag) == parentscan->id) { |         if (lfs_tag_id(attr.tag) == parentscan->tempid) { | ||||||
|             parentscan->id = -1; |             parentscan->tempid = -1; | ||||||
|         } else if (lfs_tag_id(attr.tag) < parentscan->id) { |         } else if (lfs_tag_id(attr.tag) < parentscan->tempid) { | ||||||
|             parentscan->id -= 1; |             parentscan->tempid -= 1; | ||||||
|         } |         } | ||||||
|  |     } else if (lfs_tag_type(attr.tag) == LFS_TYPE_CRC) { | ||||||
|  |         parentscan->id = parentscan->tempid; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return 0; |     return 0; | ||||||
| @@ -3490,7 +3515,8 @@ static int lfs_parent(lfs_t *lfs, const lfs_block_t pair[2], | |||||||
|         struct lfs_dir_parentscan parentscan = { |         struct lfs_dir_parentscan parentscan = { | ||||||
|             .pair[0] = pair[0], |             .pair[0] = pair[0], | ||||||
|             .pair[1] = pair[1], |             .pair[1] = pair[1], | ||||||
|             .id = -1 |             .id = -1, | ||||||
|  |             .tempid = -1, | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         int err = lfs_dir_fetchwith(lfs, parent, parent->tail, |         int err = lfs_dir_fetchwith(lfs, parent, parent->tail, | ||||||
|   | |||||||
| @@ -152,8 +152,6 @@ tests/test.py << TEST | |||||||
|     strcmp(info.name, "..") => 0; |     strcmp(info.name, "..") => 0; | ||||||
|     info.type => LFS_TYPE_DIR; |     info.type => LFS_TYPE_DIR; | ||||||
|     lfs_dir_read(&lfs, &dir[0], &info) => 1; |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|     printf("nameee \"%s\"\n", info.name); |  | ||||||
|     printf("expect \"%s\"\n", "burito"); |  | ||||||
|     strcmp(info.name, "burito") => 0; |     strcmp(info.name, "burito") => 0; | ||||||
|     info.type => LFS_TYPE_REG; |     info.type => LFS_TYPE_REG; | ||||||
|     lfs_dir_read(&lfs, &dir[0], &info) => 1; |     lfs_dir_read(&lfs, &dir[0], &info) => 1; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user