mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	WIP so close
This commit is contained in:
		
							
								
								
									
										222
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										222
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -1186,27 +1186,34 @@ nextname: | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             // TODO compact npair -> dir->tail? |             // TODO compact npair -> dir->tail? | ||||||
|             lfs_stag_t ttag = 0; |             if (lfs_pair_isnull(dir->branch)) { | ||||||
|             npair[0] = dir->tail[0]; |  | ||||||
|             npair[1] = dir->tail[1]; |  | ||||||
|             if (!dir->split) { |  | ||||||
| //                npair[0] = dir->branch[0]; |  | ||||||
| //                npair[1] = dir->branch[1]; |  | ||||||
|                 ttag = lfs_dir_get(lfs, dir, |  | ||||||
|                         LFS_MKTAG(0x7ff, 0, 0), |  | ||||||
|                         LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)), |  | ||||||
|                         npair); |  | ||||||
|                 if (ttag < 0 && ttag != LFS_ERR_NOENT) { |  | ||||||
|                     return ttag; |  | ||||||
|                 } |  | ||||||
|                 lfs_pair_fromle32(npair); |  | ||||||
|                 assert(ttag == LFS_ERR_NOENT || lfs_pair_cmp(npair, dir->branch) == 0); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             // ttag may be NOENT or may be marked null explicitly |  | ||||||
|             if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) { |  | ||||||
|                 return LFS_ERR_NOENT; |                 return LFS_ERR_NOENT; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             npair[0] = dir->branch[0]; | ||||||
|  |             npair[1] = dir->branch[1]; | ||||||
|  |  | ||||||
|  | //            lfs_stag_t ttag = 0; | ||||||
|  | //            npair[0] = dir->tail[0]; | ||||||
|  | //            npair[1] = dir->tail[1]; | ||||||
|  | //            if (!dir->split) { | ||||||
|  | ////                npair[0] = dir->branch[0]; | ||||||
|  | ////                npair[1] = dir->branch[1]; | ||||||
|  | //                ttag = lfs_dir_get(lfs, dir, | ||||||
|  | //                        LFS_MKTAG(0x7ff, 0, 0), | ||||||
|  | //                        LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)), | ||||||
|  | //                        npair); | ||||||
|  | //                if (ttag < 0 && ttag != LFS_ERR_NOENT) { | ||||||
|  | //                    return ttag; | ||||||
|  | //                } | ||||||
|  | //                lfs_pair_fromle32(npair); | ||||||
|  | //                assert(ttag == LFS_ERR_NOENT || lfs_pair_cmp(npair, dir->branch) == 0); | ||||||
|  | //            } | ||||||
|  | // | ||||||
|  | //            // ttag may be NOENT or may be marked null explicitly | ||||||
|  | //            if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) { | ||||||
|  | //                return LFS_ERR_NOENT; | ||||||
|  | //            } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // to next name |         // to next name | ||||||
| @@ -1418,29 +1425,29 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) { | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int lfs_dir_drop(lfs_t *lfs, lfs_mdir_t *dir, lfs_mdir_t *tail) { | static int lfs_dir_droptail(lfs_t *lfs, lfs_mdir_t *dir, lfs_mdir_t *tail) { | ||||||
|     // steal state |     // steal state | ||||||
|     int err = lfs_dir_getgstate(lfs, tail, &lfs->gdelta); |     int err = lfs_dir_getgstate(lfs, tail, &lfs->gdelta); | ||||||
|     if (err) { |     if (err) { | ||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // steal tail's branch | //    // steal tail's branch | ||||||
|     lfs_block_t tbpair[2]; | //    lfs_block_t tbpair[2]; | ||||||
|     lfs_stag_t tbtag = lfs_dir_get(lfs, tail, | //    lfs_stag_t tbtag = lfs_dir_get(lfs, tail, | ||||||
|             LFS_MKTAG(0x7ff, 0, 0), | //            LFS_MKTAG(0x7ff, 0, 0), | ||||||
|             LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), tbpair); | //            LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), tbpair); | ||||||
|     if (tbtag < 0 && tbtag != LFS_ERR_NOENT) { | //    if (tbtag < 0 && tbtag != LFS_ERR_NOENT) { | ||||||
|         return tbtag; | //        return tbtag; | ||||||
|     } | //    } | ||||||
|  |  | ||||||
|     // steal tail's tail |     // steal tail's tail | ||||||
|     lfs_pair_tole32(tail->tail); |     lfs_pair_tole32(tail->tail); | ||||||
|     err = lfs_dir_commit(lfs, dir, LFS_MKATTRS( |     err = lfs_dir_commit(lfs, dir, LFS_MKATTRS( | ||||||
|             {LFS_MKTAG(LFS_TYPE_TAIL + tail->split, 0x3ff, 8), tail->tail}, |             {LFS_MKTAG(LFS_TYPE_TAIL + tail->split, 0x3ff, 8), tail->tail})); | ||||||
|             {LFS_MKTAG_IF_ELSE(tbtag != LFS_ERR_NOENT, | //            {LFS_MKTAG_IF_ELSE(tbtag != LFS_ERR_NOENT, | ||||||
|                 LFS_TYPE_BRANCH, 0x3ff, sizeof(tbpair), | //                LFS_TYPE_BRANCH, 0x3ff, sizeof(tbpair), | ||||||
|                 LFS_TYPE_BRANCH, 0x3ff, 0x3ff), tbpair})); | //                LFS_TYPE_BRANCH, 0x3ff, 0x3ff), tbpair})); | ||||||
|     lfs_pair_fromle32(tail->tail); |     lfs_pair_fromle32(tail->tail); | ||||||
|     if (err) { |     if (err) { | ||||||
|         return err; |         return err; | ||||||
| @@ -1459,13 +1466,15 @@ static int lfs_dir_dropbranch(lfs_t *lfs, | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // steal branch's branch |     // steal branch's branch | ||||||
|     lfs_block_t bbpair[2]; |     dir->branch[0] = branch->branch[0]; | ||||||
|     lfs_stag_t bbtag = lfs_dir_get(lfs, branch, |     dir->branch[1] = branch->branch[1]; | ||||||
|             LFS_MKTAG(0x7ff, 0, 0), | //    lfs_block_t bbpair[2]; | ||||||
|             LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), bbpair); | //    lfs_stag_t bbtag = lfs_dir_get(lfs, branch, | ||||||
|     if (bbtag < 0 && bbtag != LFS_ERR_NOENT) { | //            LFS_MKTAG(0x7ff, 0, 0), | ||||||
|         return bbtag; | //            LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), bbpair); | ||||||
|     } | //    if (bbtag < 0 && bbtag != LFS_ERR_NOENT) { | ||||||
|  | //        return bbtag; | ||||||
|  | //    } | ||||||
|  |  | ||||||
|     // TODO need mlist? |     // TODO need mlist? | ||||||
|     // TODO endianness? |     // TODO endianness? | ||||||
| @@ -1473,11 +1482,12 @@ static int lfs_dir_dropbranch(lfs_t *lfs, | |||||||
|     lfs_fs_preporphans(lfs, +1); |     lfs_fs_preporphans(lfs, +1); | ||||||
|  |  | ||||||
|     // delete branch |     // delete branch | ||||||
|  |     lfs_block_t branch_[2] = {dir->branch[0], dir->branch[1]}; // TODO need this? | ||||||
|     err = lfs_dir_commit(lfs, dir, LFS_MKATTRS( |     err = lfs_dir_commit(lfs, dir, LFS_MKATTRS( | ||||||
|             //{LFS_MKTAG(LFS_TYPE_TAIL + branch->split, 0x3ff, 8), branch->tail}, |             //{LFS_MKTAG(LFS_TYPE_TAIL + branch->split, 0x3ff, 8), branch->tail}, | ||||||
|             {LFS_MKTAG_IF_ELSE(bbtag != LFS_ERR_NOENT, |             {LFS_MKTAG_IF_ELSE(!lfs_pair_isnull(branch_), // bbtag != LFS_ERR_NOENT, | ||||||
|                 LFS_TYPE_BRANCH, 0x3ff, sizeof(bbpair), |                 LFS_TYPE_BRANCH, 0x3ff, sizeof(branch_), | ||||||
|                 LFS_TYPE_BRANCH, 0x3ff, 0x3ff), bbpair})); |                 LFS_TYPE_BRANCH, 0x3ff, 0x3ff), branch_})); | ||||||
|     if (err) { |     if (err) { | ||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
| @@ -1488,8 +1498,9 @@ static int lfs_dir_dropbranch(lfs_t *lfs, | |||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // TODO move this out? | ||||||
|     lfs_fs_preporphans(lfs, -1); |     lfs_fs_preporphans(lfs, -1); | ||||||
|     err = lfs_dir_drop(lfs, dir, branch); |     err = lfs_dir_droptail(lfs, dir, branch); | ||||||
|     if (err) { |     if (err) { | ||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
| @@ -2007,7 +2018,7 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, | |||||||
|         // TODO should this actually be handled in _lfs_remove_?? |         // TODO should this actually be handled in _lfs_remove_?? | ||||||
|         //printf("hmm1 %d %d\n", err, pdir.split); |         //printf("hmm1 %d %d\n", err, pdir.split); | ||||||
|         if (err != LFS_ERR_NOENT && pdir.split) { |         if (err != LFS_ERR_NOENT && pdir.split) { | ||||||
|             err = lfs_dir_drop(lfs, &pdir, dir); // TODO drop needs to handle branches |             err = lfs_dir_droptail(lfs, &pdir, dir); // TODO drop needs to handle branches | ||||||
|             if (err) { |             if (err) { | ||||||
|                 *dir = olddir; |                 *dir = olddir; | ||||||
|                 return err; |                 return err; | ||||||
| @@ -2386,28 +2397,33 @@ int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) { | |||||||
|  |  | ||||||
|     while (true) { |     while (true) { | ||||||
|         if (dir->id == dir->m.count) { |         if (dir->id == dir->m.count) { | ||||||
|             lfs_stag_t ttag = 0; |              | ||||||
|             lfs_block_t npair[2] = {dir->m.tail[0], dir->m.tail[1]}; |  | ||||||
|             // TODO remove mlist from mkdir! | //            lfs_stag_t ttag = 0; | ||||||
|             if (!dir->m.split) { | //            lfs_block_t npair[2] = {dir->m.tail[0], dir->m.tail[1]}; | ||||||
|                 ttag = lfs_dir_get(lfs, &dir->m, | //            // TODO remove mlist from mkdir! | ||||||
|                         LFS_MKTAG(0x7ff, 0, 0), | //            if (!dir->m.split) { | ||||||
|                         LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)), | //                ttag = lfs_dir_get(lfs, &dir->m, | ||||||
|                         npair); | //                        LFS_MKTAG(0x7ff, 0, 0), | ||||||
|                 if (ttag < 0 && ttag != LFS_ERR_NOENT) { | //                        LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)), | ||||||
|                     return ttag; | //                        npair); | ||||||
|                 } | //                if (ttag < 0 && ttag != LFS_ERR_NOENT) { | ||||||
|                 lfs_pair_fromle32(npair); | //                    return ttag; | ||||||
|             } | //                } | ||||||
|  | //                lfs_pair_fromle32(npair); | ||||||
|  | //            } | ||||||
|  |  | ||||||
|             // ttag may be NOENT or may be marked null explicitly |             // ttag may be NOENT or may be marked null explicitly | ||||||
|             if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) { |             //if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) { // TODO rm me | ||||||
|  |             if (lfs_pair_isnull(dir->m.branch)) { | ||||||
|                 LFS_TRACE("lfs_dir_read -> %d", false); |                 LFS_TRACE("lfs_dir_read -> %d", false); | ||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             // fetch next dir |             // fetch next dir | ||||||
|             int err = lfs_dir_fetch(lfs, &dir->m, npair); |             // TODO copy out branch in lfs_dir_fetch? | ||||||
|  |             lfs_block_t branch[2] = {dir->m.branch[0], dir->m.branch[1]}; | ||||||
|  |             int err = lfs_dir_fetch(lfs, &dir->m, branch); | ||||||
|             if (err) { |             if (err) { | ||||||
|                 LFS_TRACE("lfs_dir_read -> %d", err); |                 LFS_TRACE("lfs_dir_read -> %d", err); | ||||||
|                 return err; |                 return err; | ||||||
| @@ -2457,26 +2473,28 @@ int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) { | |||||||
|         off -= diff; |         off -= diff; | ||||||
|  |  | ||||||
|         if (dir->id == dir->m.count) { |         if (dir->id == dir->m.count) { | ||||||
|             lfs_stag_t ttag = 0; | //            lfs_stag_t ttag = 0; | ||||||
|             lfs_block_t npair[2] = {dir->m.tail[0], dir->m.tail[1]}; // TODO reuse dir tail? | //            lfs_block_t npair[2] = {dir->m.tail[0], dir->m.tail[1]}; // TODO reuse dir tail? | ||||||
|             if (!dir->m.split) { | //            if (!dir->m.split) { | ||||||
|                 ttag = lfs_dir_get(lfs, &dir->m, | //                ttag = lfs_dir_get(lfs, &dir->m, | ||||||
|                         LFS_MKTAG(0x7ff, 0, 0), | //                        LFS_MKTAG(0x7ff, 0, 0), | ||||||
|                         LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)), | //                        LFS_MKTAG(LFS_TYPE_BRANCH, 0, sizeof(npair)), | ||||||
|                         npair); | //                        npair); | ||||||
|                 if (ttag < 0 && ttag != LFS_ERR_NOENT) { | //                if (ttag < 0 && ttag != LFS_ERR_NOENT) { | ||||||
|                     return ttag; | //                    return ttag; | ||||||
|                 } | //                } | ||||||
|                 lfs_pair_fromle32(npair); | //                lfs_pair_fromle32(npair); | ||||||
|             } | //            } | ||||||
|  |  | ||||||
|             // ttag may be NOENT or may be marked null explicitly |             // ttag may be NOENT or may be marked null explicitly | ||||||
|             if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) { |             //if (ttag == LFS_ERR_NOENT || lfs_pair_isnull(npair)) { // TODO rm me | ||||||
|  |             if (lfs_pair_isnull(dir->m.branch)) { | ||||||
|                 LFS_TRACE("lfs_dir_seek -> %d", LFS_ERR_INVAL); |                 LFS_TRACE("lfs_dir_seek -> %d", LFS_ERR_INVAL); | ||||||
|                 return LFS_ERR_INVAL; |                 return LFS_ERR_INVAL; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             err = lfs_dir_fetch(lfs, &dir->m, npair); |             lfs_block_t branch[2] = {dir->m.branch[0], dir->m.branch[1]}; | ||||||
|  |             err = lfs_dir_fetch(lfs, &dir->m, branch); | ||||||
|             if (err) { |             if (err) { | ||||||
|                 LFS_TRACE("lfs_dir_seek -> %d", err); |                 LFS_TRACE("lfs_dir_seek -> %d", err); | ||||||
|                 return err; |                 return err; | ||||||
| @@ -3542,7 +3560,7 @@ int lfs_remove(lfs_t *lfs, const char *path) { | |||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         err = lfs_dir_drop(lfs, &cwd, &dir.m); |         err = lfs_dir_droptail(lfs, &cwd, &dir.m); | ||||||
|         if (err) { |         if (err) { | ||||||
|             LFS_TRACE("lfs_remove -> %d", err); |             LFS_TRACE("lfs_remove -> %d", err); | ||||||
|             return err; |             return err; | ||||||
| @@ -3687,7 +3705,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | |||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         err = lfs_dir_drop(lfs, &newcwd, &prevdir.m); |         err = lfs_dir_droptail(lfs, &newcwd, &prevdir.m); | ||||||
|         if (err) { |         if (err) { | ||||||
|             LFS_TRACE("lfs_rename -> %d", err); |             LFS_TRACE("lfs_rename -> %d", err); | ||||||
|             return err; |             return err; | ||||||
| @@ -4516,7 +4534,7 @@ static int lfs_fs_deorphan(lfs_t *lfs) { | |||||||
|                 LFS_DEBUG("Fixing orphan %"PRIx32" %"PRIx32, |                 LFS_DEBUG("Fixing orphan %"PRIx32" %"PRIx32, | ||||||
|                         pdir.tail[0], pdir.tail[1]); |                         pdir.tail[0], pdir.tail[1]); | ||||||
|  |  | ||||||
|                 err = lfs_dir_drop(lfs, &pdir, &dir); |                 err = lfs_dir_droptail(lfs, &pdir, &dir); | ||||||
|                 if (err) { |                 if (err) { | ||||||
|                     return err; |                     return err; | ||||||
|                 } |                 } | ||||||
| @@ -4525,32 +4543,32 @@ static int lfs_fs_deorphan(lfs_t *lfs) { | |||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             lfs_block_t pair[2]; | //            lfs_block_t pair[2]; | ||||||
|             lfs_stag_t res = lfs_dir_get(lfs, &parent, | //            lfs_stag_t res = lfs_dir_get(lfs, &parent, | ||||||
|                     LFS_MKTAG(0x7ff, 0x3ff, 0), tag, pair); | //                    LFS_MKTAG(0x7ff, 0x3ff, 0), tag, pair); | ||||||
|             if (res < 0) { | //            if (res < 0) { | ||||||
|                 return res; | //                return res; | ||||||
|             } | //            } | ||||||
|             lfs_pair_fromle32(pair); | //            lfs_pair_fromle32(pair); | ||||||
|  | // | ||||||
|             if (!lfs_pair_sync(pair, pdir.tail)) { | //            if (!lfs_pair_sync(pair, pdir.tail)) { | ||||||
|                 assert(false); | //                assert(false); | ||||||
|                 // we have desynced | //                // we have desynced | ||||||
|                 LFS_DEBUG("Fixing half-orphan " | //                LFS_DEBUG("Fixing half-orphan " | ||||||
|                         "%"PRIx32" %"PRIx32" -> %"PRIx32" %"PRIx32, | //                        "%"PRIx32" %"PRIx32" -> %"PRIx32" %"PRIx32, | ||||||
|                         pdir.tail[0], pdir.tail[1], pair[0], pair[1]); | //                        pdir.tail[0], pdir.tail[1], pair[0], pair[1]); | ||||||
|  | // | ||||||
|                 lfs_pair_tole32(pair); | //                lfs_pair_tole32(pair); | ||||||
|                 err = lfs_dir_commit(lfs, &pdir, LFS_MKATTRS( | //                err = lfs_dir_commit(lfs, &pdir, LFS_MKATTRS( | ||||||
|                         {LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 8), pair})); | //                        {LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 8), pair})); | ||||||
|                 lfs_pair_fromle32(pair); | //                lfs_pair_fromle32(pair); | ||||||
|                 if (err) { | //                if (err) { | ||||||
|                     return err; | //                    return err; | ||||||
|                 } | //                } | ||||||
|  | // | ||||||
|                 // refetch tail | //                // refetch tail | ||||||
|                 continue; | //                continue; | ||||||
|             } | //            } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         pdir = dir; |         pdir = dir; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user