mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-11-01 00:38:29 +01:00 
			
		
		
		
	WIP WIP yes two wips
This commit is contained in:
		
							
								
								
									
										332
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										332
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -473,6 +473,10 @@ struct lfs_commit { | |||||||
|     } filter; |     } filter; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | // TODO predelcare | ||||||
|  | static int lfs_commit_move_(lfs_t *lfs, struct lfs_commit *commit, | ||||||
|  |         lfs_entry_t entry); | ||||||
|  |  | ||||||
| //static int lfs_commit_compactcheck(lfs_t *lfs, void *p, lfs_entry_t entry) { | //static int lfs_commit_compactcheck(lfs_t *lfs, void *p, lfs_entry_t entry) { | ||||||
| //    struct lfs_commit *commit = p; | //    struct lfs_commit *commit = p; | ||||||
| //    if (lfs_tag_id(entry.tag) != commit->compact.id) { | //    if (lfs_tag_id(entry.tag) != commit->compact.id) { | ||||||
| @@ -492,6 +496,12 @@ static int lfs_commit_commit(lfs_t *lfs, | |||||||
|             lfs_tag_id(entry.tag) >= commit->filter.end)) { |             lfs_tag_id(entry.tag) >= commit->filter.end)) { | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // special cases | ||||||
|  |     if ((lfs_tag_type(entry.tag) & 0x103) == LFS_FROM_MOVE) { | ||||||
|  |         return lfs_commit_move_(lfs, commit, entry);  | ||||||
|  |     } | ||||||
|  |  | ||||||
|     uint16_t id = lfs_tag_id(entry.tag) - commit->filter.begin; |     uint16_t id = lfs_tag_id(entry.tag) - commit->filter.begin; | ||||||
|     entry.tag = lfs_mktag(0, id, 0) | (entry.tag & 0xffe00fff); |     entry.tag = lfs_mktag(0, id, 0) | (entry.tag & 0xffe00fff); | ||||||
|  |  | ||||||
| @@ -607,8 +617,21 @@ static int lfs_commit_regions(lfs_t *lfs, void *p, struct lfs_commit *commit) { | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int lfs_commit_list(lfs_t *lfs, struct lfs_commit *commit, | ||||||
|  |         lfs_entrylist_t *list) { | ||||||
|  |     for (; list; list = list->next) { | ||||||
|  |         int err = lfs_commit_commit(lfs, commit, list->e); | ||||||
|  |         if (err) { | ||||||
|  |             return err; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| // committer for moves | // committer for moves | ||||||
|  | // TODO rename? | ||||||
| struct lfs_commit_move { | struct lfs_commit_move { | ||||||
|     lfs_dir_t *dir; |     lfs_dir_t *dir; | ||||||
|     struct { |     struct { | ||||||
| @@ -619,6 +642,7 @@ struct lfs_commit_move { | |||||||
|     struct lfs_commit *commit; |     struct lfs_commit *commit; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| // TODO redeclare | // TODO redeclare | ||||||
| static int lfs_dir_traverse(lfs_t *lfs, lfs_dir_t *dir, | static int lfs_dir_traverse(lfs_t *lfs, lfs_dir_t *dir, | ||||||
|         int (*cb)(lfs_t *lfs, void *data, lfs_entry_t entry), |         int (*cb)(lfs_t *lfs, void *data, lfs_entry_t entry), | ||||||
| @@ -689,6 +713,23 @@ static int lfs_commit_move(lfs_t *lfs, void *p, struct lfs_commit *commit) { | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int lfs_commit_move_(lfs_t *lfs, struct lfs_commit *commit, | ||||||
|  |         lfs_entry_t entry) { | ||||||
|  |     struct lfs_commit_move move = { | ||||||
|  |         .dir = entry.u.dir, | ||||||
|  |         .id.to = lfs_tag_id(entry.tag), | ||||||
|  |         .id.from = lfs_tag_size(entry.tag), | ||||||
|  |         .commit = commit, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     int err = lfs_dir_traverse(lfs, entry.u.dir, lfs_commit_movescan, &move); | ||||||
|  |     if (err) { | ||||||
|  |         return err; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int lfs_dir_alloc(lfs_t *lfs, lfs_dir_t *dir, | static int lfs_dir_alloc(lfs_t *lfs, lfs_dir_t *dir, | ||||||
|         bool split, const lfs_block_t tail[2]) { |         bool split, const lfs_block_t tail[2]) { | ||||||
|     // allocate pair of dir blocks (backwards, so we write to block 1 first) |     // allocate pair of dir blocks (backwards, so we write to block 1 first) | ||||||
| @@ -1139,6 +1180,228 @@ relocate: | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int lfs_dir_compact_(lfs_t *lfs, lfs_dir_t *dir, lfs_entrylist_t *list, | ||||||
|  |         lfs_dir_t *source, uint16_t begin, uint16_t end) { | ||||||
|  |     // save some state in case block is bad | ||||||
|  |     const lfs_block_t oldpair[2] = {dir->pair[1], dir->pair[0]}; | ||||||
|  |     bool relocated = false; | ||||||
|  |  | ||||||
|  |     // increment revision count | ||||||
|  |     dir->rev += 1; | ||||||
|  |  | ||||||
|  |     while (true) { | ||||||
|  |         // last complete id | ||||||
|  |         int16_t ack = -1; | ||||||
|  |         dir->count = end - begin; | ||||||
|  |  | ||||||
|  |         if (true) { | ||||||
|  |             // erase block to write to | ||||||
|  |             int err = lfs_bd_erase(lfs, dir->pair[1]); | ||||||
|  |             if (err) { | ||||||
|  |                 if (err == LFS_ERR_CORRUPT) { | ||||||
|  |                     goto relocate; | ||||||
|  |                 } | ||||||
|  |                 return err; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // write out header | ||||||
|  |             uint32_t crc = 0xffffffff; | ||||||
|  |             uint32_t rev = lfs_tole32(dir->rev); | ||||||
|  |             lfs_crc(&crc, &rev, sizeof(rev)); | ||||||
|  |             err = lfs_bd_prog(lfs, dir->pair[1], 0, &rev, sizeof(rev)); | ||||||
|  |             if (err) { | ||||||
|  |                 if (err == LFS_ERR_CORRUPT) { | ||||||
|  |                     goto relocate; | ||||||
|  |                 } | ||||||
|  |                 return err; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // setup compaction | ||||||
|  |             struct lfs_commit commit = { | ||||||
|  |                 .block = dir->pair[1], | ||||||
|  |                 .off = sizeof(dir->rev), | ||||||
|  |  | ||||||
|  |                 // space is complicated, we need room for tail, crc, | ||||||
|  |                 // and we keep cap at around half a block | ||||||
|  |                 .begin = 0, | ||||||
|  |                 .end = lfs_min( | ||||||
|  |                         lfs_alignup(lfs->cfg->block_size / 2, | ||||||
|  |                             lfs->cfg->prog_size), | ||||||
|  |                         lfs->cfg->block_size - 5*sizeof(uint32_t)), | ||||||
|  |                 .crc = crc, | ||||||
|  |                 .ptag = 0, | ||||||
|  |  | ||||||
|  |                 // filter out ids | ||||||
|  |                 .filter.begin = begin, | ||||||
|  |                 .filter.end = end, | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             // commit regions which can't fend for themselves | ||||||
|  |             err = lfs_commit_list(lfs, &commit, list); | ||||||
|  |             if (err) { | ||||||
|  |                 if (err == LFS_ERR_NOSPC) { | ||||||
|  |                     goto split; | ||||||
|  |                 } else if (err == LFS_ERR_CORRUPT) { | ||||||
|  |                     goto relocate; | ||||||
|  |                 } | ||||||
|  |                 return err; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // move over other commits, leaving it up to lfs_commit_move to | ||||||
|  |             // filter out duplicates, and the commit filtering to reassign ids | ||||||
|  |             for (uint16_t id = begin; id < end; id++) { | ||||||
|  |                 err = lfs_commit_commit(lfs, &commit, (lfs_entry_t){ | ||||||
|  |                         lfs_mktag(LFS_FROM_MOVE, id, id), .u.dir=source}); | ||||||
|  |                 if (err) { | ||||||
|  |                     if (err == LFS_ERR_NOSPC) { | ||||||
|  |                         goto split; | ||||||
|  |                     } else if (err == LFS_ERR_CORRUPT) { | ||||||
|  |                         goto relocate; | ||||||
|  |                     } | ||||||
|  |                     return err; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 ack = id; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             commit.end = lfs->cfg->block_size - 2*sizeof(uint32_t); | ||||||
|  |             if (!lfs_pairisnull(dir->tail)) { | ||||||
|  |                 // TODO le32 | ||||||
|  |                 err = lfs_commit_commit(lfs, &commit, (lfs_entry_t){ | ||||||
|  |                         lfs_mktag(LFS_TYPE_SOFTTAIL + dir->split*0x10, | ||||||
|  |                             0x1ff, sizeof(dir->tail)), | ||||||
|  |                         .u.buffer=dir->tail}); | ||||||
|  |                 if (err) { | ||||||
|  |                     if (err == LFS_ERR_CORRUPT) { | ||||||
|  |                         goto relocate; | ||||||
|  |                     } | ||||||
|  |                     return err; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             err = lfs_commit_crc(lfs, &commit); | ||||||
|  |             if (err) { | ||||||
|  |                 if (err == LFS_ERR_CORRUPT) { | ||||||
|  |                     goto relocate; | ||||||
|  |                 } | ||||||
|  |                 return err; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // successful compaction, swap dir pair to indicate most recent | ||||||
|  |             lfs_pairswap(dir->pair); | ||||||
|  |             dir->off = commit.off; | ||||||
|  |             dir->etag = commit.ptag; | ||||||
|  |             dir->erased = true; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |  | ||||||
|  | split: | ||||||
|  |         // commit no longer fits, need to split dir, | ||||||
|  |         // drop caches and create tail | ||||||
|  |         lfs->pcache.block = 0xffffffff; | ||||||
|  |  | ||||||
|  |         lfs_dir_t tail; | ||||||
|  |         int err = lfs_dir_alloc(lfs, &tail, dir->split, dir->tail); | ||||||
|  |         if (err) { | ||||||
|  |             return err; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         err = lfs_dir_compact_(lfs, &tail, list, dir, ack+1, end); | ||||||
|  |         if (err) { | ||||||
|  |             return err; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         end = ack+1; | ||||||
|  |         dir->tail[0] = tail.pair[0]; | ||||||
|  |         dir->tail[1] = tail.pair[1]; | ||||||
|  |         dir->split = true; | ||||||
|  |         continue; | ||||||
|  |  | ||||||
|  | relocate: | ||||||
|  |         //commit was corrupted | ||||||
|  |         LFS_DEBUG("Bad block at %d", dir->pair[1]); | ||||||
|  |  | ||||||
|  |         // drop caches and prepare to relocate block | ||||||
|  |         relocated = true; | ||||||
|  |         lfs->pcache.block = 0xffffffff; | ||||||
|  |  | ||||||
|  |         // can't relocate superblock, filesystem is now frozen | ||||||
|  |         if (lfs_paircmp(oldpair, (const lfs_block_t[2]){0, 1}) == 0) { | ||||||
|  |             LFS_WARN("Superblock %d has become unwritable", oldpair[1]); | ||||||
|  |             return LFS_ERR_CORRUPT; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // relocate half of pair | ||||||
|  |         err = lfs_alloc(lfs, &dir->pair[1]); | ||||||
|  |         if (err) { | ||||||
|  |             return err; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         continue; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (relocated) { | ||||||
|  |         // update references if we relocated | ||||||
|  |         LFS_DEBUG("Relocating %d %d to %d %d", | ||||||
|  |                 oldpair[0], oldpair[1], dir->pair[0], dir->pair[1]); | ||||||
|  |         int err = lfs_relocate(lfs, oldpair, dir->pair); | ||||||
|  |         if (err) { | ||||||
|  |             return err; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // shift over any directories that are affected | ||||||
|  |     for (lfs_dir_t *d = lfs->dirs; d; d = d->next) { | ||||||
|  |         if (lfs_paircmp(d->pair, dir->pair) == 0) { | ||||||
|  |             d->pair[0] = dir->pair[0]; | ||||||
|  |             d->pair[1] = dir->pair[1]; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int lfs_dir_commit_(lfs_t *lfs, lfs_dir_t *dir, lfs_entrylist_t *list) { | ||||||
|  |     if (!dir->erased) { | ||||||
|  |         // not erased, must compact | ||||||
|  |         return lfs_dir_compact_(lfs, dir, list, dir, 0, dir->count); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     struct lfs_commit commit = { | ||||||
|  |         .block = dir->pair[0], | ||||||
|  |         .begin = dir->off, | ||||||
|  |         .off = dir->off, | ||||||
|  |         .end = lfs->cfg->block_size - 2*sizeof(uint32_t), | ||||||
|  |         .crc = 0xffffffff, | ||||||
|  |         .ptag = dir->etag, | ||||||
|  |         .filter.begin = 0, | ||||||
|  |         .filter.end = 0x1ff, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     int err = lfs_commit_list(lfs, &commit, list); | ||||||
|  |     if (err) { | ||||||
|  |         if (err == LFS_ERR_NOSPC || err == LFS_ERR_CORRUPT) { | ||||||
|  |             lfs->pcache.block = 0xffffffff; | ||||||
|  |             return lfs_dir_compact_(lfs, dir, list, dir, 0, dir->count); | ||||||
|  |         } | ||||||
|  |         return err; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     err = lfs_commit_crc(lfs, &commit); | ||||||
|  |     if (err) { | ||||||
|  |         if (err == LFS_ERR_NOSPC || err == LFS_ERR_CORRUPT) { | ||||||
|  |             lfs->pcache.block = 0xffffffff; | ||||||
|  |             return lfs_dir_compact_(lfs, dir, list, dir, 0, dir->count); | ||||||
|  |         } | ||||||
|  |         return err; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // successful commit, lets update dir | ||||||
|  |     dir->off = commit.off; | ||||||
|  |     dir->etag = commit.ptag; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int lfs_dir_commitwith(lfs_t *lfs, lfs_dir_t *dir, | static int lfs_dir_commitwith(lfs_t *lfs, lfs_dir_t *dir, | ||||||
|         int (*cb)(lfs_t *lfs, void *data, struct lfs_commit *commit), |         int (*cb)(lfs_t *lfs, void *data, struct lfs_commit *commit), | ||||||
|         void *data) { |         void *data) { | ||||||
| @@ -1195,7 +1458,7 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir, uint16_t *id) { | |||||||
|  |  | ||||||
| static int lfs_dir_delete(lfs_t *lfs, lfs_dir_t *dir, uint16_t id) { | static int lfs_dir_delete(lfs_t *lfs, lfs_dir_t *dir, uint16_t id) { | ||||||
|     dir->count -= 1; |     dir->count -= 1; | ||||||
|     return lfs_dir_commit(lfs, dir, &(lfs_entrylist_t){ |     return lfs_dir_commit_(lfs, dir, &(lfs_entrylist_t){ | ||||||
|             {lfs_mktag(LFS_TYPE_DELETE, id, 0)}}); |             {lfs_mktag(LFS_TYPE_DELETE, id, 0)}}); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1233,7 +1496,9 @@ static int lfs_dir_get(lfs_t *lfs, lfs_dir_t *dir, | |||||||
|         return LFS_ERR_NOENT; |         return LFS_ERR_NOENT; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (id == dir->moveid) { |     // TODO hmm, stop at commit? maybe we need to handle this elsewhere? | ||||||
|  |     // Should commit get be its own thing? commit traverse? | ||||||
|  |     if (id == dir->moveid && !dir->stop_at_commit) { | ||||||
|         int moved = lfs_moved(lfs, dir, dir->moveid); |         int moved = lfs_moved(lfs, dir, dir->moveid); | ||||||
|         if (moved < 0) { |         if (moved < 0) { | ||||||
|             return moved; |             return moved; | ||||||
| @@ -1409,6 +1674,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir, | |||||||
|  |  | ||||||
|         // find path |         // find path | ||||||
|         while (true) { |         while (true) { | ||||||
|  |             printf("checking %d %d for %s\n", entry.u.pair[0], entry.u.pair[1], *path); | ||||||
|             find.id = -1; |             find.id = -1; | ||||||
|             int err = lfs_dir_fetchwith(lfs, dir, entry.u.pair, |             int err = lfs_dir_fetchwith(lfs, dir, entry.u.pair, | ||||||
|                     lfs_dir_finder, &find); |                     lfs_dir_finder, &find); | ||||||
| @@ -2327,7 +2593,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { | |||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     err = lfs_dir_commit(lfs, &dir, NULL); |     err = lfs_dir_commit_(lfs, &dir, NULL); | ||||||
|     if (err) { |     if (err) { | ||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
| @@ -2341,7 +2607,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { | |||||||
|  |  | ||||||
|     cwd.tail[0] = dir.pair[0]; |     cwd.tail[0] = dir.pair[0]; | ||||||
|     cwd.tail[1] = dir.pair[1]; |     cwd.tail[1] = dir.pair[1]; | ||||||
|     err = lfs_dir_commit(lfs, &cwd, &(lfs_entrylist_t){ |     err = lfs_dir_commit_(lfs, &cwd, &(lfs_entrylist_t){ | ||||||
|             {lfs_mktag(LFS_TYPE_NAME, id, nlen), |             {lfs_mktag(LFS_TYPE_NAME, id, nlen), | ||||||
|                 .u.buffer=(void*)path}, &(lfs_entrylist_t){ |                 .u.buffer=(void*)path}, &(lfs_entrylist_t){ | ||||||
|             {lfs_mktag(LFS_TYPE_DIR | LFS_STRUCT_DIR, id, sizeof(dir.pair)), |             {lfs_mktag(LFS_TYPE_DIR | LFS_STRUCT_DIR, id, sizeof(dir.pair)), | ||||||
| @@ -2943,7 +3209,7 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, | |||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         err = lfs_dir_commit(lfs, &cwd, &(lfs_entrylist_t){ |         err = lfs_dir_commit_(lfs, &cwd, &(lfs_entrylist_t){ | ||||||
|                 {lfs_mktag(LFS_TYPE_NAME, id, nlen), |                 {lfs_mktag(LFS_TYPE_NAME, id, nlen), | ||||||
|                  .u.buffer=(void*)path}, &(lfs_entrylist_t){ |                  .u.buffer=(void*)path}, &(lfs_entrylist_t){ | ||||||
|                 {lfs_mktag(LFS_TYPE_REG | LFS_STRUCT_INLINE, id, 0)}}}); |                 {lfs_mktag(LFS_TYPE_REG | LFS_STRUCT_INLINE, id, 0)}}}); | ||||||
| @@ -3193,7 +3459,7 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) { | |||||||
|  |  | ||||||
|         // either update the references or inline the whole file |         // either update the references or inline the whole file | ||||||
|         if (!(file->flags & LFS_F_INLINE)) { |         if (!(file->flags & LFS_F_INLINE)) { | ||||||
|             int err = lfs_dir_commit(lfs, &cwd, &(lfs_entrylist_t){ |             int err = lfs_dir_commit_(lfs, &cwd, &(lfs_entrylist_t){ | ||||||
|                     {lfs_mktag(LFS_TYPE_REG | LFS_STRUCT_CTZ, file->id, |                     {lfs_mktag(LFS_TYPE_REG | LFS_STRUCT_CTZ, file->id, | ||||||
|                         2*sizeof(uint32_t)), .u.buffer=&file->head}, |                         2*sizeof(uint32_t)), .u.buffer=&file->head}, | ||||||
|                         file->attrs}); |                         file->attrs}); | ||||||
| @@ -3201,7 +3467,7 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) { | |||||||
|                 return err; |                 return err; | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             int err = lfs_dir_commit(lfs, &cwd, &(lfs_entrylist_t){ |             int err = lfs_dir_commit_(lfs, &cwd, &(lfs_entrylist_t){ | ||||||
|                     {lfs_mktag(LFS_TYPE_REG | LFS_STRUCT_INLINE, file->id, |                     {lfs_mktag(LFS_TYPE_REG | LFS_STRUCT_INLINE, file->id, | ||||||
|                         file->size), .u.buffer=file->cache.buffer}, |                         file->size), .u.buffer=file->cache.buffer}, | ||||||
|                         file->attrs}); |                         file->attrs}); | ||||||
| @@ -3746,7 +4012,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | |||||||
|  |  | ||||||
|     // mark as moving |     // mark as moving | ||||||
|     //printf("RENAME MOVE %d %d %d\n", oldcwd.pair[0], oldcwd.pair[1], oldid); |     //printf("RENAME MOVE %d %d %d\n", oldcwd.pair[0], oldcwd.pair[1], oldid); | ||||||
|     err = lfs_dir_commit(lfs, &oldcwd, &(lfs_entrylist_t){ |     err = lfs_dir_commit_(lfs, &oldcwd, &(lfs_entrylist_t){ | ||||||
|             {lfs_mktag(LFS_TYPE_MOVE, oldid, 0)}}); |             {lfs_mktag(LFS_TYPE_MOVE, oldid, 0)}}); | ||||||
|     if (err) { |     if (err) { | ||||||
|         return err; |         return err; | ||||||
| @@ -3757,20 +4023,30 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | |||||||
|         newcwd = oldcwd; |         newcwd = oldcwd; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // move to new location | // TODO check that all complaints are fixed | ||||||
|     // TODO NAME????? | //    // move to new location | ||||||
|     // TODO HAH, move doesn't want to override things (due | //    // TODO NAME????? | ||||||
|     // to its use in compaction), but that's _exactly_ what we want here | //    // TODO HAH, move doesn't want to override things (due | ||||||
|     err = lfs_dir_commitwith(lfs, &newcwd, lfs_commit_move, | //    // to its use in compaction), but that's _exactly_ what we want here | ||||||
|             &(struct lfs_commit_move){.dir=&oldcwd, .id={oldid, newid}}); | //    err = lfs_dir_commitwith(lfs, &newcwd, lfs_commit_move, | ||||||
|     if (err) { | //            &(struct lfs_commit_move){.dir=&oldcwd, .id={oldid, newid}}); | ||||||
|         return err; | //    if (err) { | ||||||
|     } | //        return err; | ||||||
|     // TODO NONONONONO | //    } | ||||||
|     // TODO also don't call strlen twice (see prev name check) | //    // TODO NONONONONO | ||||||
|     err = lfs_dir_commit(lfs, &newcwd, &(lfs_entrylist_t){ | //    // TODO also don't call strlen twice (see prev name check) | ||||||
|  | //    err = lfs_dir_commit_(lfs, &newcwd, &(lfs_entrylist_t){ | ||||||
|  | //            {lfs_mktag(LFS_TYPE_NAME, newid, strlen(newpath)), | ||||||
|  | //             .u.buffer=(void*)newpath}}); | ||||||
|  | //    if (err) { | ||||||
|  | //        return err; | ||||||
|  | //    } | ||||||
|  |  | ||||||
|  |     err = lfs_dir_commit_(lfs, &newcwd, &(lfs_entrylist_t){ | ||||||
|             {lfs_mktag(LFS_TYPE_NAME, newid, strlen(newpath)), |             {lfs_mktag(LFS_TYPE_NAME, newid, strlen(newpath)), | ||||||
|              .u.buffer=(void*)newpath}}); |              .u.buffer=(void*)newpath}, &(lfs_entrylist_t){ | ||||||
|  |             {lfs_mktag(LFS_FROM_MOVE, newid, oldid), | ||||||
|  |              .u.dir=&oldcwd}}}); | ||||||
|     if (err) { |     if (err) { | ||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
| @@ -3956,7 +4232,7 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { | |||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     err = lfs_dir_commit(lfs, &root, NULL); |     err = lfs_dir_commit_(lfs, &root, NULL); | ||||||
|     if (err) { |     if (err) { | ||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
| @@ -3981,7 +4257,7 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     dir.count += 1; |     dir.count += 1; | ||||||
|     err = lfs_dir_commit(lfs, &dir, &(lfs_entrylist_t){ |     err = lfs_dir_commit_(lfs, &dir, &(lfs_entrylist_t){ | ||||||
|             {lfs_mktag(LFS_TYPE_SUPERBLOCK | LFS_STRUCT_DIR, 0, |             {lfs_mktag(LFS_TYPE_SUPERBLOCK | LFS_STRUCT_DIR, 0, | ||||||
|                 sizeof(superblock)), .u.buffer=&superblock}}); |                 sizeof(superblock)), .u.buffer=&superblock}}); | ||||||
|     if (err) { |     if (err) { | ||||||
| @@ -4434,7 +4710,7 @@ static int lfs_relocate(lfs_t *lfs, | |||||||
|         // update disk, this creates a desync |         // update disk, this creates a desync | ||||||
|         entry.u.pair[0] = newpair[0]; |         entry.u.pair[0] = newpair[0]; | ||||||
|         entry.u.pair[1] = newpair[1]; |         entry.u.pair[1] = newpair[1]; | ||||||
|         int err = lfs_dir_commit(lfs, &parent, &(lfs_entrylist_t){entry}); |         int err = lfs_dir_commit_(lfs, &parent, &(lfs_entrylist_t){entry}); | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
| @@ -4460,9 +4736,9 @@ static int lfs_relocate(lfs_t *lfs, | |||||||
|         // just replace bad pair, no desync can occur |         // just replace bad pair, no desync can occur | ||||||
|         parent.tail[0] = newpair[0]; |         parent.tail[0] = newpair[0]; | ||||||
|         parent.tail[1] = newpair[1]; |         parent.tail[1] = newpair[1]; | ||||||
|         return lfs_dir_commit(lfs, &parent, &(lfs_entrylist_t){ |         return lfs_dir_commit_(lfs, &parent, &(lfs_entrylist_t){ | ||||||
|                 {lfs_mktag(LFS_TYPE_SOFTTAIL + parent.split*0x10, // TODO hm |                 {lfs_mktag(LFS_TYPE_SOFTTAIL + parent.split*0x10, // TODO hm | ||||||
|                     0x1ff, sizeof(newpair)), |                     0x1ff, sizeof(lfs_block_t[2])), | ||||||
|                     .u.pair[0]=newpair[0], .u.pair[1]=newpair[1]}}); |                     .u.pair[0]=newpair[0], .u.pair[1]=newpair[1]}}); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -4503,7 +4779,7 @@ int lfs_deorphan(lfs_t *lfs) { | |||||||
|  |  | ||||||
|                 pdir.tail[0] = dir.tail[0]; |                 pdir.tail[0] = dir.tail[0]; | ||||||
|                 pdir.tail[1] = dir.tail[1]; |                 pdir.tail[1] = dir.tail[1]; | ||||||
|                 err = lfs_dir_commit(lfs, &pdir, &(lfs_entrylist_t){ |                 err = lfs_dir_commit_(lfs, &pdir, &(lfs_entrylist_t){ | ||||||
|                         {lfs_mktag(LFS_TYPE_SOFTTAIL, 0x1ff, |                         {lfs_mktag(LFS_TYPE_SOFTTAIL, 0x1ff, | ||||||
|                             sizeof(pdir.tail)), .u.buffer=pdir.tail}}); |                             sizeof(pdir.tail)), .u.buffer=pdir.tail}}); | ||||||
|                 if (err) { |                 if (err) { | ||||||
| @@ -4520,7 +4796,7 @@ int lfs_deorphan(lfs_t *lfs) { | |||||||
|  |  | ||||||
|                 pdir.tail[0] = entry.u.pair[0]; |                 pdir.tail[0] = entry.u.pair[0]; | ||||||
|                 pdir.tail[1] = entry.u.pair[1]; |                 pdir.tail[1] = entry.u.pair[1]; | ||||||
|                 err = lfs_dir_commit(lfs, &pdir, &(lfs_entrylist_t){ |                 err = lfs_dir_commit_(lfs, &pdir, &(lfs_entrylist_t){ | ||||||
|                         {lfs_mktag(LFS_TYPE_SOFTTAIL, 0x1ff, |                         {lfs_mktag(LFS_TYPE_SOFTTAIL, 0x1ff, | ||||||
|                             sizeof(pdir.tail)), .u.buffer=pdir.tail}}); |                             sizeof(pdir.tail)), .u.buffer=pdir.tail}}); | ||||||
|                 if (err) { |                 if (err) { | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								lfs.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								lfs.h
									
									
									
									
									
								
							| @@ -117,8 +117,8 @@ enum lfs_type { | |||||||
|  |  | ||||||
|     // internal sources |     // internal sources | ||||||
|     LFS_FROM_REGION     = 0x000, |     LFS_FROM_REGION     = 0x000, | ||||||
|     LFS_FROM_DISK       = 0x001, |     LFS_FROM_DISK       = 0x200, | ||||||
|     LFS_FROM_MOVE       = 0x002, |     LFS_FROM_MOVE       = 0x001, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // File open flags | // File open flags | ||||||
| @@ -276,6 +276,7 @@ typedef struct lfs_entry { | |||||||
|             lfs_block_t block; |             lfs_block_t block; | ||||||
|             lfs_off_t off; |             lfs_off_t off; | ||||||
|         } d; |         } d; | ||||||
|  |         struct lfs_dir *dir; | ||||||
|     } u; |     } u; | ||||||
| } lfs_entry_t; | } lfs_entry_t; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -329,7 +329,7 @@ tests/test.py << TEST | |||||||
| TEST | TEST | ||||||
|  |  | ||||||
| echo "--- Multi-block remove ---" | echo "--- Multi-block remove ---" | ||||||
| tests/test.py << TEST | tests/test.py -s << TEST | ||||||
|     lfs_mount(&lfs, &cfg) => 0; |     lfs_mount(&lfs, &cfg) => 0; | ||||||
|     lfs_remove(&lfs, "cactus") => LFS_ERR_NOTEMPTY; |     lfs_remove(&lfs, "cactus") => LFS_ERR_NOTEMPTY; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user