mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Edited tag structure to balance size vs id count
This is a minor tweak that resulted from looking at some other use cases for the littlefs data-structure on disk. Consider an implementation that does not need to buffer inline-files in RAM. In this case we should have as large a tag size field as possible. Unfortunately, we don't have much space to work with in the 32-bit tag struct, so we have to make some compromises. These limitations could be removed with a 64-bit tag struct, at the cost of code size. 32-bit tag structure: [--- 32 ---] [1|- 9 -|- 9 -|-- 13 --] ^ ^ ^ ^- entry length | | \-------- file id | \-------------- tag type \------------------ valid bit
This commit is contained in:
		
							
								
								
									
										72
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -265,7 +265,7 @@ typedef uint32_t lfs_tag_t; | |||||||
| typedef int32_t lfs_stag_t; | typedef int32_t lfs_stag_t; | ||||||
|  |  | ||||||
| #define LFS_MKTAG(type, id, size) \ | #define LFS_MKTAG(type, id, size) \ | ||||||
|     (((lfs_tag_t)(type) << 22) | ((lfs_tag_t)(id) << 12) | (lfs_tag_t)(size)) |     (((lfs_tag_t)(type) << 22) | ((lfs_tag_t)(id) << 13) | (lfs_tag_t)(size)) | ||||||
|  |  | ||||||
| static inline bool lfs_tag_isvalid(lfs_tag_t tag) { | static inline bool lfs_tag_isvalid(lfs_tag_t tag) { | ||||||
|     return !(tag & 0x80000000); |     return !(tag & 0x80000000); | ||||||
| @@ -276,7 +276,7 @@ static inline bool lfs_tag_isuser(lfs_tag_t tag) { | |||||||
| } | } | ||||||
|  |  | ||||||
| static inline bool lfs_tag_isdelete(lfs_tag_t tag) { | static inline bool lfs_tag_isdelete(lfs_tag_t tag) { | ||||||
|     return (tag & 0x00000fff) == 0xfff; |     return ((int32_t)(tag << 19) >> 19) == -1; | ||||||
| } | } | ||||||
|  |  | ||||||
| static inline uint16_t lfs_tag_type(lfs_tag_t tag) { | static inline uint16_t lfs_tag_type(lfs_tag_t tag) { | ||||||
| @@ -288,11 +288,11 @@ static inline uint16_t lfs_tag_subtype(lfs_tag_t tag) { | |||||||
| } | } | ||||||
|  |  | ||||||
| static inline uint16_t lfs_tag_id(lfs_tag_t tag) { | static inline uint16_t lfs_tag_id(lfs_tag_t tag) { | ||||||
|     return (tag & 0x003ff000) >> 12; |     return (tag & 0x003fe000) >> 13; | ||||||
| } | } | ||||||
|  |  | ||||||
| static inline lfs_size_t lfs_tag_size(lfs_tag_t tag) { | static inline lfs_size_t lfs_tag_size(lfs_tag_t tag) { | ||||||
|     return tag & 0x00000fff; |     return tag & 0x00001fff; | ||||||
| } | } | ||||||
|  |  | ||||||
| static inline lfs_size_t lfs_tag_dsize(lfs_tag_t tag) { | static inline lfs_size_t lfs_tag_dsize(lfs_tag_t tag) { | ||||||
| @@ -837,14 +837,14 @@ static int lfs_dir_getglobals(lfs_t *lfs, const lfs_mdir_t *dir, | |||||||
|  |  | ||||||
| static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir, | static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir, | ||||||
|         uint16_t id, struct lfs_info *info) { |         uint16_t id, struct lfs_info *info) { | ||||||
|     if (id == 0x3ff) { |     if (id == 0x1ff) { | ||||||
|         // special case for root |         // special case for root | ||||||
|         strcpy(info->name, "/"); |         strcpy(info->name, "/"); | ||||||
|         info->type = LFS_TYPE_DIR; |         info->type = LFS_TYPE_DIR; | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     lfs_stag_t tag = lfs_dir_get(lfs, dir, 0x7c3ff000, |     lfs_stag_t tag = lfs_dir_get(lfs, dir, 0x7c3fe000, | ||||||
|             LFS_MKTAG(LFS_TYPE_NAME, id, lfs->name_max+1), info->name); |             LFS_MKTAG(LFS_TYPE_NAME, id, lfs->name_max+1), info->name); | ||||||
|     if (tag < 0) { |     if (tag < 0) { | ||||||
|         return tag; |         return tag; | ||||||
| @@ -853,7 +853,7 @@ static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir, | |||||||
|     info->type = lfs_tag_type(tag); |     info->type = lfs_tag_type(tag); | ||||||
|  |  | ||||||
|     struct lfs_ctz ctz; |     struct lfs_ctz ctz; | ||||||
|     tag = lfs_dir_get(lfs, dir, 0x7c3ff000, |     tag = lfs_dir_get(lfs, dir, 0x7c3fe000, | ||||||
|             LFS_MKTAG(LFS_TYPE_STRUCT, id, sizeof(ctz)), &ctz); |             LFS_MKTAG(LFS_TYPE_STRUCT, id, sizeof(ctz)), &ctz); | ||||||
|     if (tag < 0) { |     if (tag < 0) { | ||||||
|         return tag; |         return tag; | ||||||
| @@ -912,7 +912,7 @@ static lfs_stag_t lfs_dir_find(lfs_t *lfs, | |||||||
|     *path = NULL; |     *path = NULL; | ||||||
|  |  | ||||||
|     // default to root dir |     // default to root dir | ||||||
|     lfs_stag_t tag = LFS_MKTAG(LFS_TYPE_DIR, 0x3ff, 0); |     lfs_stag_t tag = LFS_MKTAG(LFS_TYPE_DIR, 0x1ff, 0); | ||||||
|     lfs_block_t pair[2] = {lfs->root[0], lfs->root[1]}; |     lfs_block_t pair[2] = {lfs->root[0], lfs->root[1]}; | ||||||
|  |  | ||||||
|     while (true) { |     while (true) { | ||||||
| @@ -968,8 +968,8 @@ nextname: | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         // grab the entry data |         // grab the entry data | ||||||
|         if (lfs_tag_id(tag) != 0x3ff) { |         if (lfs_tag_id(tag) != 0x1ff) { | ||||||
|             lfs_stag_t res = lfs_dir_get(lfs, dir, 0x7c3ff000, |             lfs_stag_t res = lfs_dir_get(lfs, dir, 0x7c3fe000, | ||||||
|                     LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair); |                     LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair); | ||||||
|             if (res < 0) { |             if (res < 0) { | ||||||
|                 return res; |                 return res; | ||||||
| @@ -978,7 +978,7 @@ nextname: | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         // find entry matching name |         // find entry matching name | ||||||
|         tag = lfs_dir_findmatch(lfs, dir, pair, false, 0x7c000fff, |         tag = lfs_dir_findmatch(lfs, dir, pair, false, 0x7c001fff, | ||||||
|                 LFS_MKTAG(LFS_TYPE_NAME, 0, namelen), |                 LFS_MKTAG(LFS_TYPE_NAME, 0, namelen), | ||||||
|                 lfs_dir_find_match, &(struct lfs_dir_find_match){ |                 lfs_dir_find_match, &(struct lfs_dir_find_match){ | ||||||
|                     lfs, name, namelen}); |                     lfs, name, namelen}); | ||||||
| @@ -1046,7 +1046,7 @@ static int lfs_commit_move_match(void *data, | |||||||
|                     .pair[0] = commit->block, |                     .pair[0] = commit->block, | ||||||
|                     .off = commit->off, |                     .off = commit->off, | ||||||
|                     .etag = commit->ptag}, NULL, |                     .etag = commit->ptag}, NULL, | ||||||
|                 lfs_tag_isuser(tag) ? 0x7ffff000 : 0x7c3ff000, tag, 0, |                 lfs_tag_isuser(tag) ? 0x7fffe000 : 0x7c3fe000, tag, 0, | ||||||
|                 lfs_dir_get_match, &(struct lfs_dir_get_match){ |                 lfs_dir_get_match, &(struct lfs_dir_get_match){ | ||||||
|                     lfs, NULL, 0, true}); |                     lfs, NULL, 0, true}); | ||||||
|         if (res < 0 && res != LFS_ERR_NOENT) { |         if (res < 0 && res != LFS_ERR_NOENT) { | ||||||
| @@ -1089,7 +1089,7 @@ static int lfs_commit_attr(lfs_t *lfs, struct lfs_commit *commit, | |||||||
|     if (lfs_tag_type(tag) == LFS_FROM_MOVE) { |     if (lfs_tag_type(tag) == LFS_FROM_MOVE) { | ||||||
|         // special case for moves |         // special case for moves | ||||||
|         return lfs_commit_move(lfs, commit, 1, |         return lfs_commit_move(lfs, commit, 1, | ||||||
|                 0x003ff000, LFS_MKTAG(0, lfs_tag_size(tag), 0), |                 0x003fe000, LFS_MKTAG(0, lfs_tag_size(tag), 0), | ||||||
|                 LFS_MKTAG(0, lfs_tag_id(tag), 0) - |                 LFS_MKTAG(0, lfs_tag_id(tag), 0) - | ||||||
|                     LFS_MKTAG(0, lfs_tag_size(tag), 0), |                     LFS_MKTAG(0, lfs_tag_size(tag), 0), | ||||||
|                 buffer, NULL); |                 buffer, NULL); | ||||||
| @@ -1146,7 +1146,7 @@ static int lfs_commit_globals(lfs_t *lfs, struct lfs_commit *commit, | |||||||
|         struct lfs_globals *globals) { |         struct lfs_globals *globals) { | ||||||
|     return lfs_commit_attr(lfs, commit, |     return lfs_commit_attr(lfs, commit, | ||||||
|             LFS_MKTAG(LFS_TYPE_GLOBALS + 2*globals->hasmove + globals->orphans, |             LFS_MKTAG(LFS_TYPE_GLOBALS + 2*globals->hasmove + globals->orphans, | ||||||
|                 0x3ff, 10), globals); |                 0x1ff, 10), globals); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int lfs_commit_crc(lfs_t *lfs, struct lfs_commit *commit, | static int lfs_commit_crc(lfs_t *lfs, struct lfs_commit *commit, | ||||||
| @@ -1166,8 +1166,8 @@ static int lfs_commit_crc(lfs_t *lfs, struct lfs_commit *commit, | |||||||
|  |  | ||||||
|     // build crc tag |     // build crc tag | ||||||
|     bool reset = ~lfs_fromle32(tag) >> 31; |     bool reset = ~lfs_fromle32(tag) >> 31; | ||||||
|     tag = LFS_MKTAG(LFS_TYPE_CRC + (compacting << 1) + reset, |     tag = LFS_MKTAG(LFS_TYPE_CRC + 2*compacting + reset, | ||||||
|             0x3ff, off - (commit->off+sizeof(lfs_tag_t))); |             0x1ff, off - (commit->off+sizeof(lfs_tag_t))); | ||||||
|  |  | ||||||
|     // write out crc |     // write out crc | ||||||
|     uint32_t footer[2]; |     uint32_t footer[2]; | ||||||
| @@ -1267,7 +1267,7 @@ static int lfs_dir_drop(lfs_t *lfs, lfs_mdir_t *dir, const lfs_mdir_t *tail) { | |||||||
|     // update pred's tail |     // update pred's tail | ||||||
|     return lfs_dir_commit(lfs, dir, |     return lfs_dir_commit(lfs, dir, | ||||||
|             LFS_MKATTR(LFS_TYPE_TAIL + dir->split, |             LFS_MKATTR(LFS_TYPE_TAIL + dir->split, | ||||||
|                 0x3ff, dir->tail, sizeof(dir->tail), |                 0x1ff, dir->tail, sizeof(dir->tail), | ||||||
|             NULL)); |             NULL)); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1369,7 +1369,7 @@ commit: | |||||||
|         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++) { |             for (int pass = 0; pass < 2; pass++) { | ||||||
|                 err = lfs_commit_move(lfs, &commit, pass, |                 err = lfs_commit_move(lfs, &commit, pass, | ||||||
|                         0x003ff000, LFS_MKTAG(0, id, 0), |                         0x003fe000, LFS_MKTAG(0, id, 0), | ||||||
|                         -LFS_MKTAG(0, begin, 0), |                         -LFS_MKTAG(0, begin, 0), | ||||||
|                         source, attrs); |                         source, attrs); | ||||||
|                 if (err && !(splitted && !overcompacting && |                 if (err && !(splitted && !overcompacting && | ||||||
| @@ -1419,7 +1419,7 @@ commit: | |||||||
|             lfs_pair_tole32(dir->tail); |             lfs_pair_tole32(dir->tail); | ||||||
|             err = lfs_commit_attr(lfs, &commit, |             err = lfs_commit_attr(lfs, &commit, | ||||||
|                     LFS_MKTAG(LFS_TYPE_TAIL + dir->split, |                     LFS_MKTAG(LFS_TYPE_TAIL + dir->split, | ||||||
|                         0x3ff, sizeof(dir->tail)), dir->tail); |                         0x1ff, sizeof(dir->tail)), dir->tail); | ||||||
|             lfs_pair_fromle32(dir->tail); |             lfs_pair_fromle32(dir->tail); | ||||||
|             if (err) { |             if (err) { | ||||||
|                 if (err == LFS_ERR_CORRUPT) { |                 if (err == LFS_ERR_CORRUPT) { | ||||||
| @@ -1737,7 +1737,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { | |||||||
|     cwd.tail[1] = dir.pair[1]; |     cwd.tail[1] = dir.pair[1]; | ||||||
|     lfs_pair_tole32(dir.pair); |     lfs_pair_tole32(dir.pair); | ||||||
|     err = lfs_dir_commit(lfs, &cwd, |     err = lfs_dir_commit(lfs, &cwd, | ||||||
|             LFS_MKATTR(LFS_TYPE_SOFTTAIL, 0x3ff, cwd.tail, sizeof(cwd.tail), |             LFS_MKATTR(LFS_TYPE_SOFTTAIL, 0x1ff, cwd.tail, sizeof(cwd.tail), | ||||||
|             LFS_MKATTR(LFS_TYPE_DIRSTRUCT, id, dir.pair, sizeof(dir.pair), |             LFS_MKATTR(LFS_TYPE_DIRSTRUCT, id, dir.pair, sizeof(dir.pair), | ||||||
|             LFS_MKATTR(LFS_TYPE_DIR, id, path, nlen, |             LFS_MKATTR(LFS_TYPE_DIR, id, path, nlen, | ||||||
|             NULL)))); |             NULL)))); | ||||||
| @@ -1760,13 +1760,13 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     lfs_block_t pair[2]; |     lfs_block_t pair[2]; | ||||||
|     if (lfs_tag_id(tag) == 0x3ff) { |     if (lfs_tag_id(tag) == 0x1ff) { | ||||||
|         // handle root dir separately |         // handle root dir separately | ||||||
|         pair[0] = lfs->root[0]; |         pair[0] = lfs->root[0]; | ||||||
|         pair[1] = lfs->root[1]; |         pair[1] = lfs->root[1]; | ||||||
|     } else { |     } else { | ||||||
|         // get dir pair from parent |         // get dir pair from parent | ||||||
|         lfs_stag_t res = lfs_dir_get(lfs, &dir->m, 0x7c3ff000, |         lfs_stag_t res = lfs_dir_get(lfs, &dir->m, 0x7c3fe000, | ||||||
|                 LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair); |                 LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair); | ||||||
|         if (res < 0) { |         if (res < 0) { | ||||||
|             return res; |             return res; | ||||||
| @@ -2163,7 +2163,7 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, | |||||||
|         file->flags |= LFS_F_DIRTY; |         file->flags |= LFS_F_DIRTY; | ||||||
|     } else { |     } else { | ||||||
|         // try to load what's on disk, if it's inlined we'll fix it later |         // try to load what's on disk, if it's inlined we'll fix it later | ||||||
|         tag = lfs_dir_get(lfs, &file->m, 0x7c3ff000, |         tag = lfs_dir_get(lfs, &file->m, 0x7c3fe000, | ||||||
|                 LFS_MKTAG(LFS_TYPE_STRUCT, file->id, 8), &file->ctz); |                 LFS_MKTAG(LFS_TYPE_STRUCT, file->id, 8), &file->ctz); | ||||||
|         if (tag < 0) { |         if (tag < 0) { | ||||||
|             err = tag; |             err = tag; | ||||||
| @@ -2175,7 +2175,7 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, | |||||||
|     // fetch attrs |     // fetch attrs | ||||||
|     for (const struct lfs_attr *a = file->cfg->attrs; a; a = a->next) { |     for (const struct lfs_attr *a = file->cfg->attrs; a; a = a->next) { | ||||||
|         if ((file->flags & 3) != LFS_O_WRONLY) { |         if ((file->flags & 3) != LFS_O_WRONLY) { | ||||||
|             lfs_stag_t res = lfs_dir_get(lfs, &file->m, 0x7ffff000, |             lfs_stag_t res = lfs_dir_get(lfs, &file->m, 0x7fffe000, | ||||||
|                     LFS_MKTAG(0x100 | a->type, file->id, a->size), a->buffer); |                     LFS_MKTAG(0x100 | a->type, file->id, a->size), a->buffer); | ||||||
|             if (res < 0 && res != LFS_ERR_NOENT) { |             if (res < 0 && res != LFS_ERR_NOENT) { | ||||||
|                 err = res; |                 err = res; | ||||||
| @@ -2218,7 +2218,7 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, | |||||||
|  |  | ||||||
|         // don't always read (may be new/trunc file) |         // don't always read (may be new/trunc file) | ||||||
|         if (file->ctz.size > 0) { |         if (file->ctz.size > 0) { | ||||||
|             lfs_stag_t res = lfs_dir_get(lfs, &file->m, 0x7c3ff000, |             lfs_stag_t res = lfs_dir_get(lfs, &file->m, 0x7c3fe000, | ||||||
|                     LFS_MKTAG(LFS_TYPE_STRUCT, file->id, file->ctz.size), |                     LFS_MKTAG(LFS_TYPE_STRUCT, file->id, file->ctz.size), | ||||||
|                     file->cache.buffer); |                     file->cache.buffer); | ||||||
|             if (res < 0) { |             if (res < 0) { | ||||||
| @@ -2778,7 +2778,7 @@ int lfs_remove(lfs_t *lfs, const char *path) { | |||||||
|     if (lfs_tag_type(tag) == LFS_TYPE_DIR) { |     if (lfs_tag_type(tag) == LFS_TYPE_DIR) { | ||||||
|         // must be empty before removal |         // must be empty before removal | ||||||
|         lfs_block_t pair[2]; |         lfs_block_t pair[2]; | ||||||
|         lfs_stag_t res = lfs_dir_get(lfs, &cwd, 0x7c3ff000, |         lfs_stag_t res = lfs_dir_get(lfs, &cwd, 0x7c3fe000, | ||||||
|                 LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair); |                 LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair); | ||||||
|         if (res < 0) { |         if (res < 0) { | ||||||
|             return res; |             return res; | ||||||
| @@ -2862,7 +2862,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | |||||||
|     } else if (lfs_tag_type(prevtag) == LFS_TYPE_DIR) { |     } else if (lfs_tag_type(prevtag) == LFS_TYPE_DIR) { | ||||||
|         // must be empty before removal |         // must be empty before removal | ||||||
|         lfs_block_t prevpair[2]; |         lfs_block_t prevpair[2]; | ||||||
|         lfs_stag_t res = lfs_dir_get(lfs, &newcwd, 0x7c3ff000, |         lfs_stag_t res = lfs_dir_get(lfs, &newcwd, 0x7c3fe000, | ||||||
|                 LFS_MKTAG(LFS_TYPE_STRUCT, newid, 8), prevpair); |                 LFS_MKTAG(LFS_TYPE_STRUCT, newid, 8), prevpair); | ||||||
|         if (res < 0) { |         if (res < 0) { | ||||||
|             return res; |             return res; | ||||||
| @@ -2933,7 +2933,7 @@ lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path, | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     uint16_t id = lfs_tag_id(res); |     uint16_t id = lfs_tag_id(res); | ||||||
|     if (id == 0x3ff) { |     if (id == 0x1ff) { | ||||||
|         // special case for root |         // special case for root | ||||||
|         id = 0; |         id = 0; | ||||||
|         int err = lfs_dir_fetch(lfs, &cwd, lfs->root); |         int err = lfs_dir_fetch(lfs, &cwd, lfs->root); | ||||||
| @@ -2942,7 +2942,7 @@ lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path, | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     res = lfs_dir_get(lfs, &cwd, 0x7ffff000, |     res = lfs_dir_get(lfs, &cwd, 0x7fffe000, | ||||||
|             LFS_MKTAG(0x100 | type, id, lfs_min(size, lfs->attr_max)), |             LFS_MKTAG(0x100 | type, id, lfs_min(size, lfs->attr_max)), | ||||||
|             buffer); |             buffer); | ||||||
|     if (res < 0) { |     if (res < 0) { | ||||||
| @@ -2964,7 +2964,7 @@ static int lfs_commitattr(lfs_t *lfs, const char *path, | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     uint16_t id = lfs_tag_id(res); |     uint16_t id = lfs_tag_id(res); | ||||||
|     if (id == 0x3ff) { |     if (id == 0x1ff) { | ||||||
|         // special case for root |         // special case for root | ||||||
|         id = 0; |         id = 0; | ||||||
|         int err = lfs_dir_fetch(lfs, &cwd, lfs->root); |         int err = lfs_dir_fetch(lfs, &cwd, lfs->root); | ||||||
| @@ -2988,7 +2988,7 @@ int lfs_setattr(lfs_t *lfs, const char *path, | |||||||
| } | } | ||||||
|  |  | ||||||
| int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type) { | int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type) { | ||||||
|     return lfs_commitattr(lfs, path, type, NULL, LFS_ATTR_MAX+1); |     return lfs_commitattr(lfs, path, type, NULL, 0x1fff); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -3290,7 +3290,7 @@ int lfs_fs_traverse(lfs_t *lfs, | |||||||
|  |  | ||||||
|         for (uint16_t id = 0; id < dir.count; id++) { |         for (uint16_t id = 0; id < dir.count; id++) { | ||||||
|             struct lfs_ctz ctz; |             struct lfs_ctz ctz; | ||||||
|             lfs_stag_t tag = lfs_dir_get(lfs, &dir, 0x7c3ff000, |             lfs_stag_t tag = lfs_dir_get(lfs, &dir, 0x7c3fe000, | ||||||
|                     LFS_MKTAG(LFS_TYPE_STRUCT, id, sizeof(ctz)), &ctz); |                     LFS_MKTAG(LFS_TYPE_STRUCT, id, sizeof(ctz)), &ctz); | ||||||
|             if (tag < 0) { |             if (tag < 0) { | ||||||
|                 if (tag == LFS_ERR_NOENT) { |                 if (tag == LFS_ERR_NOENT) { | ||||||
| @@ -3393,7 +3393,7 @@ static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t pair[2], | |||||||
|     for (int i = 0; i < 2; i++) { |     for (int i = 0; i < 2; i++) { | ||||||
|         struct lfs_fs_parent_match match = {lfs, {pair[0], pair[1]}}; |         struct lfs_fs_parent_match match = {lfs, {pair[0], pair[1]}}; | ||||||
|         lfs_stag_t tag = lfs_dir_findmatch(lfs, parent, |         lfs_stag_t tag = lfs_dir_findmatch(lfs, parent, | ||||||
|                 (const lfs_block_t[2]){0, 1}, true, 0x7fc00fff, |                 (const lfs_block_t[2]){0, 1}, true, 0x7fc01fff, | ||||||
|                 LFS_MKTAG(LFS_TYPE_DIRSTRUCT, 0, 8), |                 LFS_MKTAG(LFS_TYPE_DIRSTRUCT, 0, 8), | ||||||
|                 lfs_fs_parent_match, &match); |                 lfs_fs_parent_match, &match); | ||||||
|         if (tag != LFS_ERR_NOENT) { |         if (tag != LFS_ERR_NOENT) { | ||||||
| @@ -3458,7 +3458,7 @@ static int lfs_fs_relocate(lfs_t *lfs, | |||||||
|         parent.tail[1] = newpair[1]; |         parent.tail[1] = newpair[1]; | ||||||
|         err = lfs_dir_commit(lfs, &parent, |         err = lfs_dir_commit(lfs, &parent, | ||||||
|                 LFS_MKATTR(LFS_TYPE_TAIL + parent.split, |                 LFS_MKATTR(LFS_TYPE_TAIL + parent.split, | ||||||
|                     0x3ff, parent.tail, sizeof(parent.tail), |                     0x1ff, parent.tail, sizeof(parent.tail), | ||||||
|                 NULL)); |                 NULL)); | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
| @@ -3532,7 +3532,7 @@ static int lfs_fs_deorphan(lfs_t *lfs) { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             lfs_block_t pair[2]; |             lfs_block_t pair[2]; | ||||||
|             lfs_stag_t res = lfs_dir_get(lfs, &parent, 0x7ffff000, tag, pair); |             lfs_stag_t res = lfs_dir_get(lfs, &parent, 0x7fffe000, tag, pair); | ||||||
|             if (res < 0) { |             if (res < 0) { | ||||||
|                 return res; |                 return res; | ||||||
|             } |             } | ||||||
| @@ -3547,7 +3547,7 @@ static int lfs_fs_deorphan(lfs_t *lfs) { | |||||||
|                 pdir.tail[1] = pair[1]; |                 pdir.tail[1] = pair[1]; | ||||||
|                 err = lfs_dir_commit(lfs, &pdir, |                 err = lfs_dir_commit(lfs, &pdir, | ||||||
|                         LFS_MKATTR(LFS_TYPE_SOFTTAIL, |                         LFS_MKATTR(LFS_TYPE_SOFTTAIL, | ||||||
|                             0x3ff, pdir.tail, sizeof(pdir.tail), |                             0x1ff, pdir.tail, sizeof(pdir.tail), | ||||||
|                         NULL)); |                         NULL)); | ||||||
|                 if (err) { |                 if (err) { | ||||||
|                     return err; |                     return err; | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								lfs.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								lfs.h
									
									
									
									
									
								
							| @@ -49,7 +49,7 @@ typedef uint32_t lfs_block_t; | |||||||
| // to <= 0xfff. Stored in superblock and must be respected by other | // to <= 0xfff. Stored in superblock and must be respected by other | ||||||
| // littlefs drivers. | // littlefs drivers. | ||||||
| #ifndef LFS_ATTR_MAX | #ifndef LFS_ATTR_MAX | ||||||
| #define LFS_ATTR_MAX 0xffe | #define LFS_ATTR_MAX 0x1ffe | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // Maximum name size in bytes, may be redefined to reduce the size of the | // Maximum name size in bytes, may be redefined to reduce the size of the | ||||||
| @@ -64,7 +64,7 @@ typedef uint32_t lfs_block_t; | |||||||
| // block. Limited to <= LFS_ATTR_MAX and <= cache_size. Stored in superblock | // block. Limited to <= LFS_ATTR_MAX and <= cache_size. Stored in superblock | ||||||
| // and must be respected by other littlefs drivers. | // and must be respected by other littlefs drivers. | ||||||
| #ifndef LFS_INLINE_MAX | #ifndef LFS_INLINE_MAX | ||||||
| #define LFS_INLINE_MAX 0xffe | #define LFS_INLINE_MAX 0x1ffe | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // Possible error codes, these are negative to allow | // Possible error codes, these are negative to allow | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ def corrupt(block): | |||||||
|                 break |                 break | ||||||
|  |  | ||||||
|             tag ^= ntag |             tag ^= ntag | ||||||
|             size = (tag & 0xfff) if (tag & 0xfff) != 0xfff else 0 |             size = (tag & 0x1fff) if (tag & 0x1fff) != 0x1fff else 0 | ||||||
|             file.seek(size, os.SEEK_CUR) |             file.seek(size, os.SEEK_CUR) | ||||||
|  |  | ||||||
|         # lob off last 3 bytes |         # lob off last 3 bytes | ||||||
|   | |||||||
| @@ -76,11 +76,11 @@ def main(*blocks): | |||||||
|         off += 4 |         off += 4 | ||||||
|  |  | ||||||
|         type = (tag & 0x7fc00000) >> 22 |         type = (tag & 0x7fc00000) >> 22 | ||||||
|         id   = (tag & 0x003ff000) >> 12 |         id   = (tag & 0x003fe000) >> 13 | ||||||
|         size = (tag & 0x00000fff) >> 0 |         size = (tag & 0x00001fff) >> 0 | ||||||
|         iscrc = (type & 0x1f0) == 0x0f0 |         iscrc = (type & 0x1f0) == 0x0f0 | ||||||
|  |  | ||||||
|         data = file.read(size if size != 0xfff else 0) |         data = file.read(size if size != 0x1fff else 0) | ||||||
|         if iscrc: |         if iscrc: | ||||||
|             crc = binascii.crc32(data[:4], crc) |             crc = binascii.crc32(data[:4], crc) | ||||||
|         else: |         else: | ||||||
| @@ -89,12 +89,12 @@ def main(*blocks): | |||||||
|         print '%04x: %08x  %-14s  %3s  %3s  %-23s  %-8s' % ( |         print '%04x: %08x  %-14s  %3s  %3s  %-23s  %-8s' % ( | ||||||
|             off, tag, |             off, tag, | ||||||
|             typeof(type) + (' bad!' if iscrc and ~crc else ''), |             typeof(type) + (' bad!' if iscrc and ~crc else ''), | ||||||
|             id if id != 0x3ff else '.', |             id if id != 0x1ff else '.', | ||||||
|             size if size != 0xfff else 'x', |             size if size != 0x1fff else 'x', | ||||||
|             ' '.join('%02x' % ord(c) for c in data[:8]), |             ' '.join('%02x' % ord(c) for c in data[:8]), | ||||||
|             ''.join(c if c >= ' ' and c <= '~' else '.' for c in data[:8])) |             ''.join(c if c >= ' ' and c <= '~' else '.' for c in data[:8])) | ||||||
|  |  | ||||||
|         off += size if size != 0xfff else 0 |         off += size if size != 0x1fff else 0 | ||||||
|         if iscrc: |         if iscrc: | ||||||
|             crc = 0 |             crc = 0 | ||||||
|             tag ^= (type & 1) << 31 |             tag ^= (type & 1) << 31 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user