mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Modified results from find-like functions to use tags
Tags offer all of the necessary info from the find functions (which makes sense, this is the structure that stores the info on disk). Passing around a single tag instead of separate id and type fields simplifies the internal functions while leverages the tag's compactness.
This commit is contained in:
		
							
								
								
									
										152
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										152
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -263,7 +263,7 @@ int lfs_fs_traverse(lfs_t *lfs, | ||||
|         int (*cb)(lfs_t*, void*, lfs_block_t), void *data); | ||||
| static int lfs_pred(lfs_t *lfs, const lfs_block_t dir[2], lfs_mdir_t *pdir); | ||||
| static int lfs_parent(lfs_t *lfs, const lfs_block_t dir[2], | ||||
|         lfs_mdir_t *parent, lfs_mattr_t *attr); | ||||
|         lfs_mdir_t *parent, lfs_tag_t *foundtag); | ||||
| static int lfs_relocate(lfs_t *lfs, | ||||
|         const lfs_block_t oldpair[2], const lfs_block_t newpair[2]); | ||||
| int lfs_scan(lfs_t *lfs); | ||||
| @@ -768,7 +768,7 @@ static int lfs_dir_find(lfs_t *lfs, | ||||
|     dir->pair[0] = pair[0]; | ||||
|     dir->pair[1] = pair[1]; | ||||
|     dir->stop_at_commit = false; | ||||
|     *foundtag = 0xffffffff; | ||||
|     lfs_tag_t localfoundtag = 0xffffffff; | ||||
|  | ||||
|     // find the block with the most recent revision | ||||
|     uint32_t rev[2]; | ||||
| @@ -801,7 +801,7 @@ static int lfs_dir_find(lfs_t *lfs, | ||||
|         dir->rev = lfs_fromle32(dir->rev); | ||||
|  | ||||
|         lfs_mdir_t tempdir = *dir; | ||||
|         lfs_tag_t tempfoundtag = *foundtag; | ||||
|         lfs_tag_t tempfoundtag = localfoundtag; | ||||
|  | ||||
|         while (true) { | ||||
|             // extract next tag | ||||
| @@ -850,7 +850,7 @@ static int lfs_dir_find(lfs_t *lfs, | ||||
|                 tempdir.etag = tag; | ||||
|                 crc = 0xffffffff; | ||||
|                 *dir = tempdir; | ||||
|                 *foundtag = tempfoundtag; | ||||
|                 localfoundtag = tempfoundtag; | ||||
|             } else { | ||||
|                 err = lfs_bd_crc(lfs, tempdir.pair[0], | ||||
|                         off+sizeof(tag), lfs_tag_size(tag), &crc); | ||||
| @@ -914,25 +914,29 @@ static int lfs_dir_find(lfs_t *lfs, | ||||
| done: | ||||
|     // synthetic move | ||||
|     if (lfs_paircmp(dir->pair, lfs->globals.move.pair) == 0) { | ||||
|         if (lfs->globals.move.id == lfs_tag_id(*foundtag)) { | ||||
|             *foundtag = 0xffffffff; | ||||
|         } else if (lfs_tag_id(*foundtag) < 0x3ff && | ||||
|                 lfs->globals.move.id < lfs_tag_id(*foundtag)) { | ||||
|             *foundtag -= lfs_mktag(0, 1, 0); | ||||
|         if (lfs->globals.move.id == lfs_tag_id(localfoundtag)) { | ||||
|             localfoundtag = 0xffffffff; | ||||
|         } else if (lfs_tag_id(localfoundtag) < 0x3ff && | ||||
|                 lfs->globals.move.id < lfs_tag_id(localfoundtag)) { | ||||
|             localfoundtag -= lfs_mktag(0, 1, 0); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (*foundtag == 0xffffffff) { | ||||
|     if (localfoundtag == 0xffffffff) { | ||||
|         return LFS_ERR_NOENT; | ||||
|     } | ||||
|  | ||||
|     if (foundtag) { | ||||
|         *foundtag = localfoundtag; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int lfs_dir_fetch(lfs_t *lfs, | ||||
|         lfs_mdir_t *dir, const lfs_block_t pair[2]) { | ||||
|     int err = lfs_dir_find(lfs, dir, pair, | ||||
|             0xffffffff, 0xffffffff, NULL, &(lfs_tag_t){0}); | ||||
|             0xffffffff, 0xffffffff, NULL, NULL); | ||||
|     if (err && err != LFS_ERR_NOENT) { | ||||
|         return err; | ||||
|     } | ||||
| @@ -1402,9 +1406,8 @@ static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir, | ||||
| } | ||||
|  | ||||
|  | ||||
| // TODO drop others, make this only return id, also make get take in only entry to populate (with embedded tag) | ||||
| static int lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, | ||||
|         const char **path, uint16_t *id, uint8_t *type) { | ||||
|         const char **path, lfs_tag_t *foundtag) { | ||||
|     lfs_mattr_t attr = { | ||||
|         .u.pair[0] = lfs->root[0], | ||||
|         .u.pair[1] = lfs->root[1], | ||||
| @@ -1412,6 +1415,7 @@ static int lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, | ||||
|  | ||||
|     const char *name = *path; | ||||
|     lfs_size_t namelen; | ||||
|     lfs_tag_t localfoundtag; | ||||
|  | ||||
|     while (true) { | ||||
|     nextname: | ||||
| @@ -1423,7 +1427,9 @@ static int lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, | ||||
|         if (name[0] == '\0') { | ||||
|             // Return ISDIR when we hit root | ||||
|             // TODO change this to -1 or 0x3ff? | ||||
|             *type = LFS_TYPE_DIR; | ||||
|             if (foundtag) { | ||||
|                 *foundtag = lfs_mktag(LFS_TYPE_DIR, 0, 0); | ||||
|             } | ||||
|             return LFS_ERR_ISDIR; | ||||
|         } | ||||
|  | ||||
| @@ -1463,18 +1469,15 @@ static int lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, | ||||
|  | ||||
|         // find path | ||||
|         while (true) { | ||||
|             lfs_tag_t foundtag = -1; | ||||
|             int err = lfs_dir_find(lfs, dir, attr.u.pair, | ||||
|                     0x7c000fff, lfs_mktag(LFS_TYPE_NAME, 0, namelen), | ||||
|                     name, &foundtag); | ||||
|                     name, &localfoundtag); | ||||
|             if (err && err != LFS_ERR_NOENT) { | ||||
|                 return err; | ||||
|             } | ||||
|  | ||||
|             if (err != LFS_ERR_NOENT) { | ||||
|                 // found it | ||||
|                 *id = lfs_tag_id(foundtag); | ||||
|                 *type = lfs_tag_type(foundtag); | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
| @@ -1486,6 +1489,10 @@ static int lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, | ||||
|             attr.u.pair[1] = dir->tail[1]; | ||||
|         } | ||||
|  | ||||
|         if (foundtag) { | ||||
|             *foundtag = localfoundtag; | ||||
|         } | ||||
|  | ||||
|         name += namelen; | ||||
|         name += strspn(name, "/"); | ||||
|         if (name[0] == '\0') { | ||||
| @@ -1494,7 +1501,7 @@ static int lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, | ||||
|  | ||||
|         // don't continue on if we didn't hit a directory | ||||
|         // TODO update with what's on master? | ||||
|         if (*type != LFS_TYPE_DIR) { | ||||
|         if (lfs_tag_type(localfoundtag) != LFS_TYPE_DIR) { | ||||
|             return LFS_ERR_NOTDIR; | ||||
|         } | ||||
|  | ||||
| @@ -1502,7 +1509,7 @@ static int lfs_dir_lookup(lfs_t *lfs, lfs_mdir_t *dir, | ||||
|         // TODO would this mean more code? | ||||
|         // grab the entry data | ||||
|         int err = lfs_dir_get(lfs, dir, 0x7c3ff000, | ||||
|                 lfs_mktag(LFS_TYPE_STRUCT, *id, 8), | ||||
|                 lfs_mktag(LFS_TYPE_STRUCT, lfs_tag_id(localfoundtag), 8), | ||||
|                 &attr.tag, &attr.u); | ||||
|         if (err) { | ||||
|             return err; | ||||
| @@ -1521,7 +1528,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { | ||||
|     } | ||||
|  | ||||
|     lfs_mdir_t cwd; | ||||
|     int err = lfs_dir_lookup(lfs, &cwd, &path, &(uint16_t){0}, &(uint8_t){0}); | ||||
|     int err = lfs_dir_lookup(lfs, &cwd, &path, NULL); | ||||
|     if (err != LFS_ERR_NOENT || strchr(path, '/') != NULL) { | ||||
|         if (!err || err == LFS_ERR_ISDIR) { | ||||
|             return LFS_ERR_EXIST; | ||||
| @@ -1572,14 +1579,13 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { | ||||
| } | ||||
|  | ||||
| int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) { | ||||
|     uint16_t id; | ||||
|     uint8_t type; | ||||
|     int err = lfs_dir_lookup(lfs, &dir->m, &path, &id, &type); | ||||
|     lfs_tag_t tag; | ||||
|     int err = lfs_dir_lookup(lfs, &dir->m, &path, &tag); | ||||
|     if (err && err != LFS_ERR_ISDIR) { | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     if (type != LFS_TYPE_DIR) { | ||||
|     if (lfs_tag_type(tag) != LFS_TYPE_DIR) { | ||||
|         return LFS_ERR_NOTDIR; | ||||
|     } | ||||
|  | ||||
| @@ -1591,7 +1597,7 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) { | ||||
|     } else { | ||||
|         // get dir pair from parent | ||||
|         err = lfs_dir_get(lfs, &dir->m, 0x7c3ff000, | ||||
|                 lfs_mktag(LFS_TYPE_STRUCT, id, 8), | ||||
|                 lfs_mktag(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), | ||||
|                 &attr.tag, &attr.u); | ||||
|         if (err) { | ||||
|             return err; | ||||
| @@ -1926,15 +1932,16 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, | ||||
|  | ||||
|     // allocate entry for file if it doesn't exist | ||||
|     lfs_mdir_t cwd; | ||||
|     uint16_t id; | ||||
|     uint8_t type; | ||||
|     int err = lfs_dir_lookup(lfs, &cwd, &path, &id, &type); | ||||
|     lfs_tag_t tag; | ||||
|     int err = lfs_dir_lookup(lfs, &cwd, &path, &tag); | ||||
|     if (err && (err != LFS_ERR_NOENT || strchr(path, '/') != NULL) && | ||||
|             err != LFS_ERR_ISDIR) { | ||||
|         return err; | ||||
|     } | ||||
|     uint16_t id = lfs_tag_id(tag); | ||||
|     uint8_t type = lfs_tag_type(tag); | ||||
|  | ||||
|     lfs_mattr_t attr; | ||||
|     lfs_mattr_t attr; // TODO stop copying things (attr, id, type, tag) | ||||
|     if (err == LFS_ERR_NOENT) { | ||||
|         if (!(flags & LFS_O_CREAT)) { | ||||
|             return LFS_ERR_NOENT; | ||||
| @@ -2603,9 +2610,9 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) { | ||||
| /// General fs operations /// | ||||
| int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) { | ||||
|     lfs_mdir_t cwd; | ||||
|     uint16_t id; | ||||
|     lfs_tag_t tag; | ||||
|     // TODO pass to getinfo? | ||||
|     int err = lfs_dir_lookup(lfs, &cwd, &path, &id, &(uint8_t){0}); | ||||
|     int err = lfs_dir_lookup(lfs, &cwd, &path, &tag); | ||||
|     if (err && err != LFS_ERR_ISDIR) { | ||||
|         return err; | ||||
|     } | ||||
| @@ -2617,7 +2624,7 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     return lfs_dir_getinfo(lfs, &cwd, id, info); | ||||
|     return lfs_dir_getinfo(lfs, &cwd, lfs_tag_id(tag), info); | ||||
| } | ||||
|  | ||||
| int lfs_remove(lfs_t *lfs, const char *path) { | ||||
| @@ -2635,19 +2642,18 @@ int lfs_remove(lfs_t *lfs, const char *path) { | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     uint16_t id; | ||||
|     uint8_t type; | ||||
|     err = lfs_dir_lookup(lfs, &cwd, &path, &id, &type); | ||||
|     lfs_tag_t tag; | ||||
|     err = lfs_dir_lookup(lfs, &cwd, &path, &tag); | ||||
|     if (err) { | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     lfs_mdir_t dir; | ||||
|     if (type == LFS_TYPE_DIR) { | ||||
|     if (lfs_tag_type(tag) == LFS_TYPE_DIR) { | ||||
|         // must be empty before removal | ||||
|         lfs_mattr_t attr; | ||||
|         err = lfs_dir_get(lfs, &cwd, 0x7c3ff000, | ||||
|                 lfs_mktag(LFS_TYPE_STRUCT, id, 8), | ||||
|                 lfs_mktag(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), | ||||
|                 &attr.tag, &attr.u); | ||||
|         if (err) { | ||||
|             return err; | ||||
| @@ -2665,12 +2671,12 @@ int lfs_remove(lfs_t *lfs, const char *path) { | ||||
|     } | ||||
|  | ||||
|     // delete the entry | ||||
|     err = lfs_dir_delete(lfs, &cwd, id); | ||||
|     err = lfs_dir_delete(lfs, &cwd, lfs_tag_id(tag)); | ||||
|     if (err) { | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     if (type == LFS_TYPE_DIR) { | ||||
|     if (lfs_tag_type(tag) == LFS_TYPE_DIR) { | ||||
|         int res = lfs_pred(lfs, dir.pair, &cwd); | ||||
|         if (res < 0) { | ||||
|             return res; | ||||
| @@ -2698,33 +2704,32 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | ||||
|  | ||||
|     // find old entry | ||||
|     lfs_mdir_t oldcwd; | ||||
|     uint16_t oldid; | ||||
|     uint8_t oldtype; | ||||
|     int err = lfs_dir_lookup(lfs, &oldcwd, &oldpath, &oldid, &oldtype); | ||||
|     lfs_tag_t oldtag; | ||||
|     int err = lfs_dir_lookup(lfs, &oldcwd, &oldpath, &oldtag); | ||||
|     if (err) { | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     // find new entry | ||||
|     lfs_mdir_t newcwd; | ||||
|     uint16_t newid; | ||||
|     uint8_t prevtype; | ||||
|     err = lfs_dir_lookup(lfs, &newcwd, &newpath, &newid, &prevtype); | ||||
|     lfs_tag_t prevtag; | ||||
|     err = lfs_dir_lookup(lfs, &newcwd, &newpath, &prevtag); | ||||
|     if (err && err != LFS_ERR_NOENT) { | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     uint16_t newid = lfs_tag_id(prevtag); | ||||
|     bool prevexists = (err != LFS_ERR_NOENT); | ||||
|     //bool samepair = (lfs_paircmp(oldcwd.pair, newcwd.pair) == 0); | ||||
|  | ||||
|     lfs_mdir_t prevdir; | ||||
|     if (prevexists) { | ||||
|         // check that we have same type | ||||
|         if (prevtype != oldtype) { | ||||
|         if (lfs_tag_type(prevtag) != lfs_tag_type(oldtag)) { | ||||
|             return LFS_ERR_ISDIR; | ||||
|         } | ||||
|  | ||||
|         if (prevtype == LFS_TYPE_DIR) { | ||||
|         if (lfs_tag_type(prevtag) == LFS_TYPE_DIR) { | ||||
|             // must be empty before removal | ||||
|             lfs_mattr_t prevattr; | ||||
|             err = lfs_dir_get(lfs, &newcwd, 0x7c3ff000, | ||||
| @@ -2761,13 +2766,13 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | ||||
|     // create move to fix later | ||||
|     lfs->diff.move.pair[0] = oldcwd.pair[0]     ^ lfs->globals.move.pair[0]; | ||||
|     lfs->diff.move.pair[1] = oldcwd.pair[1]     ^ lfs->globals.move.pair[1]; | ||||
|     lfs->diff.move.id      = oldid          ^ lfs->globals.move.id; | ||||
|     lfs->diff.move.id      = lfs_tag_id(oldtag) ^ lfs->globals.move.id; | ||||
|  | ||||
|     // move over all attributes | ||||
|     err = lfs_dir_commit(lfs, &newcwd, &(lfs_mattrlist_t){ | ||||
|             {lfs_mktag(oldtype, newid, strlen(newpath)), | ||||
|             {lfs_mktag(lfs_tag_type(oldtag), newid, strlen(newpath)), | ||||
|                 .u.buffer=(void*)newpath}, &(lfs_mattrlist_t){ | ||||
|             {lfs_mktag(LFS_FROM_DIR, newid, oldid), | ||||
|             {lfs_mktag(LFS_FROM_DIR, newid, lfs_tag_id(oldtag)), | ||||
|                 .u.dir=&oldcwd}}}); | ||||
|     if (err) { | ||||
|         return err; | ||||
| @@ -2779,7 +2784,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     if (prevexists && prevtype == LFS_TYPE_DIR) { | ||||
|     if (prevexists && lfs_tag_type(prevtag) == LFS_TYPE_DIR) { | ||||
|         int res = lfs_pred(lfs, prevdir.pair, &newcwd); | ||||
|         if (res < 0) { | ||||
|             return res; | ||||
| @@ -3286,7 +3291,7 @@ static int lfs_pred(lfs_t *lfs, const lfs_block_t pair[2], lfs_mdir_t *pdir) { | ||||
| } | ||||
|  | ||||
| static int lfs_parent(lfs_t *lfs, const lfs_block_t pair[2], | ||||
|         lfs_mdir_t *parent, lfs_mattr_t *attr) { | ||||
|         lfs_mdir_t *parent, lfs_tag_t *foundtag) { | ||||
|     // search for both orderings so we can reuse the find function | ||||
|     lfs_block_t child[2] = {pair[0], pair[1]}; | ||||
|  | ||||
| @@ -3295,31 +3300,18 @@ static int lfs_parent(lfs_t *lfs, const lfs_block_t pair[2], | ||||
|         parent->tail[0] = 0; | ||||
|         parent->tail[1] = 1; | ||||
|         while (!lfs_pairisnull(parent->tail)) { | ||||
|             lfs_tag_t foundtag = -1; | ||||
|             int err = lfs_dir_find(lfs, parent, parent->tail, | ||||
|                     0x7fc00fff, lfs_mktag(LFS_STRUCT_DIR, 0, sizeof(child)), | ||||
|                     child, &foundtag); | ||||
|             if (err && err != LFS_ERR_NOENT) { | ||||
|                 return err; | ||||
|             } | ||||
|  | ||||
|                     child, foundtag); | ||||
|             if (err != LFS_ERR_NOENT) { | ||||
|                 // found our parent | ||||
|                 int err = lfs_dir_get(lfs, parent, | ||||
|                         0x7ffff000, foundtag, | ||||
|                         &attr->tag, &attr->u); | ||||
|                 if (err) { | ||||
|                 return err; | ||||
|             } | ||||
|  | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         lfs_pairswap(child); | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
|     return LFS_ERR_NOENT; | ||||
| } | ||||
|  | ||||
| // TODO rename to lfs_dir_relocate? | ||||
| @@ -3328,12 +3320,12 @@ static int lfs_relocate(lfs_t *lfs, | ||||
|     // find parent | ||||
|     lfs_mdir_t parent; | ||||
|     lfs_mattr_t attr; | ||||
|     int res = lfs_parent(lfs, oldpair, &parent, &attr); | ||||
|     if (res < 0) { | ||||
|         return res; | ||||
|     int err = lfs_parent(lfs, oldpair, &parent, &attr.tag); | ||||
|     if (err && err != LFS_ERR_NOENT) { | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     if (res) { | ||||
|     if (err != LFS_ERR_NOENT) { | ||||
|         // update disk, this creates a desync | ||||
|         attr.u.pair[0] = newpair[0]; | ||||
|         attr.u.pair[1] = newpair[1]; | ||||
| @@ -3356,7 +3348,7 @@ static int lfs_relocate(lfs_t *lfs, | ||||
|     } | ||||
|  | ||||
|     // find pred | ||||
|     res = lfs_pred(lfs, oldpair, &parent); | ||||
|     int res = lfs_pred(lfs, oldpair, &parent); | ||||
|     if (res < 0) { | ||||
|         return res; | ||||
|     } | ||||
| @@ -3476,12 +3468,12 @@ int lfs_deorphan(lfs_t *lfs) { | ||||
|             // check if we have a parent | ||||
|             lfs_mdir_t parent; | ||||
|             lfs_mattr_t attr; | ||||
|             int res = lfs_parent(lfs, pdir.tail, &parent, &attr); | ||||
|             if (res < 0) { | ||||
|                 return res; | ||||
|             int err = lfs_parent(lfs, pdir.tail, &parent, &attr.tag); | ||||
|             if (err && err != LFS_ERR_NOENT) { | ||||
|                 return err; | ||||
|             } | ||||
|  | ||||
|             if (!res) { | ||||
|             if (err == LFS_ERR_NOENT) { | ||||
|                 // we are an orphan | ||||
|                 LFS_DEBUG("Found orphan %d %d", | ||||
|                         pdir.tail[0], pdir.tail[1]); | ||||
| @@ -3499,6 +3491,12 @@ int lfs_deorphan(lfs_t *lfs) { | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             err = lfs_dir_get(lfs, &parent, | ||||
|                     0x7ffff000, attr.tag, NULL, &attr.u); | ||||
|             if (err) { | ||||
|                 return err; | ||||
|             } | ||||
|  | ||||
|             if (!lfs_pairsync(attr.u.pair, pdir.tail)) { | ||||
|                 // we have desynced | ||||
|                 LFS_DEBUG("Found half-orphan %d %d", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user