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? | ||||
|             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)) { | ||||
|             if (lfs_pair_isnull(dir->branch)) { | ||||
|                 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 | ||||
| @@ -1418,29 +1425,29 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) { | ||||
|     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 | ||||
|     int err = lfs_dir_getgstate(lfs, tail, &lfs->gdelta); | ||||
|     if (err) { | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     // steal tail's branch | ||||
|     lfs_block_t tbpair[2]; | ||||
|     lfs_stag_t tbtag = lfs_dir_get(lfs, tail, | ||||
|             LFS_MKTAG(0x7ff, 0, 0), | ||||
|             LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), tbpair); | ||||
|     if (tbtag < 0 && tbtag != LFS_ERR_NOENT) { | ||||
|         return tbtag; | ||||
|     } | ||||
| //    // steal tail's branch | ||||
| //    lfs_block_t tbpair[2]; | ||||
| //    lfs_stag_t tbtag = lfs_dir_get(lfs, tail, | ||||
| //            LFS_MKTAG(0x7ff, 0, 0), | ||||
| //            LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), tbpair); | ||||
| //    if (tbtag < 0 && tbtag != LFS_ERR_NOENT) { | ||||
| //        return tbtag; | ||||
| //    } | ||||
|  | ||||
|     // steal tail's tail | ||||
|     lfs_pair_tole32(tail->tail); | ||||
|     err = lfs_dir_commit(lfs, dir, LFS_MKATTRS( | ||||
|             {LFS_MKTAG(LFS_TYPE_TAIL + tail->split, 0x3ff, 8), tail->tail}, | ||||
|             {LFS_MKTAG_IF_ELSE(tbtag != LFS_ERR_NOENT, | ||||
|                 LFS_TYPE_BRANCH, 0x3ff, sizeof(tbpair), | ||||
|                 LFS_TYPE_BRANCH, 0x3ff, 0x3ff), tbpair})); | ||||
|             {LFS_MKTAG(LFS_TYPE_TAIL + tail->split, 0x3ff, 8), tail->tail})); | ||||
| //            {LFS_MKTAG_IF_ELSE(tbtag != LFS_ERR_NOENT, | ||||
| //                LFS_TYPE_BRANCH, 0x3ff, sizeof(tbpair), | ||||
| //                LFS_TYPE_BRANCH, 0x3ff, 0x3ff), tbpair})); | ||||
|     lfs_pair_fromle32(tail->tail); | ||||
|     if (err) { | ||||
|         return err; | ||||
| @@ -1459,13 +1466,15 @@ static int lfs_dir_dropbranch(lfs_t *lfs, | ||||
|     } | ||||
|  | ||||
|     // steal branch's branch | ||||
|     lfs_block_t bbpair[2]; | ||||
|     lfs_stag_t bbtag = lfs_dir_get(lfs, branch, | ||||
|             LFS_MKTAG(0x7ff, 0, 0), | ||||
|             LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), bbpair); | ||||
|     if (bbtag < 0 && bbtag != LFS_ERR_NOENT) { | ||||
|         return bbtag; | ||||
|     } | ||||
|     dir->branch[0] = branch->branch[0]; | ||||
|     dir->branch[1] = branch->branch[1]; | ||||
| //    lfs_block_t bbpair[2]; | ||||
| //    lfs_stag_t bbtag = lfs_dir_get(lfs, branch, | ||||
| //            LFS_MKTAG(0x7ff, 0, 0), | ||||
| //            LFS_MKTAG(LFS_TYPE_BRANCH, 0, 8), bbpair); | ||||
| //    if (bbtag < 0 && bbtag != LFS_ERR_NOENT) { | ||||
| //        return bbtag; | ||||
| //    } | ||||
|  | ||||
|     // TODO need mlist? | ||||
|     // TODO endianness? | ||||
| @@ -1473,11 +1482,12 @@ static int lfs_dir_dropbranch(lfs_t *lfs, | ||||
|     lfs_fs_preporphans(lfs, +1); | ||||
|  | ||||
|     // delete branch | ||||
|     lfs_block_t branch_[2] = {dir->branch[0], dir->branch[1]}; // TODO need this? | ||||
|     err = lfs_dir_commit(lfs, dir, LFS_MKATTRS( | ||||
|             //{LFS_MKTAG(LFS_TYPE_TAIL + branch->split, 0x3ff, 8), branch->tail}, | ||||
|             {LFS_MKTAG_IF_ELSE(bbtag != LFS_ERR_NOENT, | ||||
|                 LFS_TYPE_BRANCH, 0x3ff, sizeof(bbpair), | ||||
|                 LFS_TYPE_BRANCH, 0x3ff, 0x3ff), bbpair})); | ||||
|             {LFS_MKTAG_IF_ELSE(!lfs_pair_isnull(branch_), // bbtag != LFS_ERR_NOENT, | ||||
|                 LFS_TYPE_BRANCH, 0x3ff, sizeof(branch_), | ||||
|                 LFS_TYPE_BRANCH, 0x3ff, 0x3ff), branch_})); | ||||
|     if (err) { | ||||
|         return err; | ||||
|     } | ||||
| @@ -1488,8 +1498,9 @@ static int lfs_dir_dropbranch(lfs_t *lfs, | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     // TODO move this out? | ||||
|     lfs_fs_preporphans(lfs, -1); | ||||
|     err = lfs_dir_drop(lfs, dir, branch); | ||||
|     err = lfs_dir_droptail(lfs, dir, branch); | ||||
|     if (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_?? | ||||
|         //printf("hmm1 %d %d\n", err, 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) { | ||||
|                 *dir = olddir; | ||||
|                 return err; | ||||
| @@ -2386,28 +2397,33 @@ int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) { | ||||
|  | ||||
|     while (true) { | ||||
|         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! | ||||
|             if (!dir->m.split) { | ||||
|                 ttag = lfs_dir_get(lfs, &dir->m, | ||||
|                         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); | ||||
|             } | ||||
|              | ||||
|  | ||||
| //            lfs_stag_t ttag = 0; | ||||
| //            lfs_block_t npair[2] = {dir->m.tail[0], dir->m.tail[1]}; | ||||
| //            // TODO remove mlist from mkdir! | ||||
| //            if (!dir->m.split) { | ||||
| //                ttag = lfs_dir_get(lfs, &dir->m, | ||||
| //                        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); | ||||
| //            } | ||||
|  | ||||
|             // 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); | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             // 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) { | ||||
|                 LFS_TRACE("lfs_dir_read -> %d", err); | ||||
|                 return err; | ||||
| @@ -2457,26 +2473,28 @@ int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) { | ||||
|         off -= diff; | ||||
|  | ||||
|         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 reuse dir tail? | ||||
|             if (!dir->m.split) { | ||||
|                 ttag = lfs_dir_get(lfs, &dir->m, | ||||
|                         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); | ||||
|             } | ||||
| //            lfs_stag_t ttag = 0; | ||||
| //            lfs_block_t npair[2] = {dir->m.tail[0], dir->m.tail[1]}; // TODO reuse dir tail? | ||||
| //            if (!dir->m.split) { | ||||
| //                ttag = lfs_dir_get(lfs, &dir->m, | ||||
| //                        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); | ||||
| //            } | ||||
|  | ||||
|             // 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); | ||||
|                 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) { | ||||
|                 LFS_TRACE("lfs_dir_seek -> %d", err); | ||||
|                 return err; | ||||
| @@ -3542,7 +3560,7 @@ int lfs_remove(lfs_t *lfs, const char *path) { | ||||
|             return err; | ||||
|         } | ||||
|  | ||||
|         err = lfs_dir_drop(lfs, &cwd, &dir.m); | ||||
|         err = lfs_dir_droptail(lfs, &cwd, &dir.m); | ||||
|         if (err) { | ||||
|             LFS_TRACE("lfs_remove -> %d", err); | ||||
|             return err; | ||||
| @@ -3687,7 +3705,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | ||||
|             return err; | ||||
|         } | ||||
|  | ||||
|         err = lfs_dir_drop(lfs, &newcwd, &prevdir.m); | ||||
|         err = lfs_dir_droptail(lfs, &newcwd, &prevdir.m); | ||||
|         if (err) { | ||||
|             LFS_TRACE("lfs_rename -> %d", err); | ||||
|             return err; | ||||
| @@ -4516,7 +4534,7 @@ static int lfs_fs_deorphan(lfs_t *lfs) { | ||||
|                 LFS_DEBUG("Fixing orphan %"PRIx32" %"PRIx32, | ||||
|                         pdir.tail[0], pdir.tail[1]); | ||||
|  | ||||
|                 err = lfs_dir_drop(lfs, &pdir, &dir); | ||||
|                 err = lfs_dir_droptail(lfs, &pdir, &dir); | ||||
|                 if (err) { | ||||
|                     return err; | ||||
|                 } | ||||
| @@ -4525,32 +4543,32 @@ static int lfs_fs_deorphan(lfs_t *lfs) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             lfs_block_t pair[2]; | ||||
|             lfs_stag_t res = lfs_dir_get(lfs, &parent, | ||||
|                     LFS_MKTAG(0x7ff, 0x3ff, 0), tag, pair); | ||||
|             if (res < 0) { | ||||
|                 return res; | ||||
|             } | ||||
|             lfs_pair_fromle32(pair); | ||||
|  | ||||
|             if (!lfs_pair_sync(pair, pdir.tail)) { | ||||
|                 assert(false); | ||||
|                 // we have desynced | ||||
|                 LFS_DEBUG("Fixing half-orphan " | ||||
|                         "%"PRIx32" %"PRIx32" -> %"PRIx32" %"PRIx32, | ||||
|                         pdir.tail[0], pdir.tail[1], pair[0], pair[1]); | ||||
|  | ||||
|                 lfs_pair_tole32(pair); | ||||
|                 err = lfs_dir_commit(lfs, &pdir, LFS_MKATTRS( | ||||
|                         {LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 8), pair})); | ||||
|                 lfs_pair_fromle32(pair); | ||||
|                 if (err) { | ||||
|                     return err; | ||||
|                 } | ||||
|  | ||||
|                 // refetch tail | ||||
|                 continue; | ||||
|             } | ||||
| //            lfs_block_t pair[2]; | ||||
| //            lfs_stag_t res = lfs_dir_get(lfs, &parent, | ||||
| //                    LFS_MKTAG(0x7ff, 0x3ff, 0), tag, pair); | ||||
| //            if (res < 0) { | ||||
| //                return res; | ||||
| //            } | ||||
| //            lfs_pair_fromle32(pair); | ||||
| // | ||||
| //            if (!lfs_pair_sync(pair, pdir.tail)) { | ||||
| //                assert(false); | ||||
| //                // we have desynced | ||||
| //                LFS_DEBUG("Fixing half-orphan " | ||||
| //                        "%"PRIx32" %"PRIx32" -> %"PRIx32" %"PRIx32, | ||||
| //                        pdir.tail[0], pdir.tail[1], pair[0], pair[1]); | ||||
| // | ||||
| //                lfs_pair_tole32(pair); | ||||
| //                err = lfs_dir_commit(lfs, &pdir, LFS_MKATTRS( | ||||
| //                        {LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 8), pair})); | ||||
| //                lfs_pair_fromle32(pair); | ||||
| //                if (err) { | ||||
| //                    return err; | ||||
| //                } | ||||
| // | ||||
| //                // refetch tail | ||||
| //                continue; | ||||
| //            } | ||||
|         } | ||||
|  | ||||
|         pdir = dir; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user