From a7038596157cf473fe9371dc8ee0a6da6679e807 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 31 Jul 2018 08:07:36 -0500 Subject: [PATCH] WIP added deorphan bit to globals --- lfs.c | 365 +++++++++++++++++++++++++++++++++------------------------- lfs.h | 29 ++--- 2 files changed, 221 insertions(+), 173 deletions(-) diff --git a/lfs.c b/lfs.c index cbafda0..25c9a57 100644 --- a/lfs.c +++ b/lfs.c @@ -267,7 +267,7 @@ static int lfs_relocate(lfs_t *lfs, const lfs_block_t oldpair[2], const lfs_block_t newpair[2]); int lfs_scan(lfs_t *lfs); int lfs_fixmove(lfs_t *lfs); -int lfs_deorphan(lfs_t *lfs); +int lfs_forceconsistency(lfs_t *lfs); /// Block allocator /// @@ -456,15 +456,68 @@ static inline lfs_size_t lfs_tagsize(uint32_t tag) { return tag & 0x00000fff; } -// operations on globals -static void lfs_globalsxor(lfs_globals_t *a, const lfs_globals_t *b) { - a->move.pair[0] ^= b->move.pair[0]; - a->move.pair[1] ^= b->move.pair[1]; - a->move.id ^= b->move.id; +// operations on set of globals +static inline void lfs_globalxor(lfs_global_t *a, const lfs_global_t *b) { + for (int i = 0; i < sizeof(lfs_global_t)/2; i++) { + a->u16[i] ^= b->u16[i]; + } } -static bool lfs_globalsiszero(const lfs_globals_t *a) { - return (a->move.pair[0] == 0 && a->move.pair[1] == 0 && a->move.id == 0); +static inline bool lfs_globaliszero(const lfs_global_t *a) { + for (int i = 0; i < sizeof(lfs_global_t)/2; i++) { + if (a->u16[i] != 0) { + return false; + } + } + return true; +} + +static inline void lfs_globalzero(lfs_global_t *a) { + memset(a->u16, 0x00, sizeof(lfs_global_t)); +} + +static inline void lfs_globalones(lfs_global_t *a) { + memset(a->u16, 0xff, sizeof(lfs_global_t)); +} + +static inline void lfs_globalxormove(lfs_global_t *a, + const lfs_block_t pair[2], uint16_t id) { + a->u16[0] ^= id; + for (int i = 0; i < sizeof(lfs_block_t[2])/2; i++) { + a->u16[1+i] ^= ((uint16_t*)pair)[i]; + } +} + +static inline void lfs_globalxordeorphaned(lfs_global_t *a, bool deorphaned) { + a->u16[0] ^= deorphaned << 15; +} + +static inline const lfs_block_t *lfs_globalmovepair(const lfs_t *lfs) { + return (const lfs_block_t*)&lfs->globals.u16[1]; +} + +static inline uint16_t lfs_globalmoveid(const lfs_t *lfs) { + return 0x3ff & lfs->globals.u16[0]; +} + +static inline bool lfs_globalisdeorphaned(const lfs_t *lfs) { + return 0x8000 & lfs->globals.u16[0]; +} + +static inline void lfs_globalmove(lfs_t *lfs, + const lfs_block_t pair[2], uint16_t id) { + lfs_global_t diff; + lfs_globalzero(&diff); + lfs_globalxormove(&diff, lfs_globalmovepair(lfs), lfs_globalmoveid(lfs)); + lfs_globalxormove(&diff, pair, id); + lfs_globalxor(&lfs->locals, &diff); + lfs_globalxor(&lfs->globals, &diff); +} + +static inline void lfs_globaldeorphaned(lfs_t *lfs, bool deorphaned) { + deorphaned ^= lfs_globalisdeorphaned(lfs); + lfs_globalxordeorphaned(&lfs->locals, deorphaned); + lfs_globalxordeorphaned(&lfs->globals, deorphaned); } @@ -670,15 +723,15 @@ static int lfs_commitmove(lfs_t *lfs, struct lfs_commit *commit, } static int lfs_commitglobals(lfs_t *lfs, struct lfs_commit *commit, - lfs_globals_t *locals) { - if (lfs_globalsiszero(&lfs->diff)) { + lfs_global_t *locals) { + if (lfs_globaliszero(&lfs->locals)) { return 0; } - lfs_globalsxor(locals, &lfs->diff); + lfs_globalxor(locals, &lfs->locals); int err = lfs_commitattr(lfs, commit, - LFS_MKTAG(LFS_TYPE_GLOBALS, 0x3ff, sizeof(*locals)), locals); - lfs_globalsxor(locals, &lfs->diff); + LFS_MKTAG(LFS_TYPE_GLOBALS, 0x3ff, sizeof(lfs_global_t)), locals); + lfs_globalxor(locals, &lfs->locals); return err; } @@ -759,7 +812,7 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir, dir->tail[1] = tail[1]; dir->erased = false; dir->split = split; - dir->locals = (lfs_globals_t){{{0}}}; + lfs_globalzero(&dir->locals); // don't write out yet, let caller take care of that return 0; @@ -774,8 +827,8 @@ static int lfs_dir_compact(lfs_t *lfs, // There's nothing special about our global delta, so feed it back // into the global global delta - lfs_globalsxor(&lfs->diff, &dir->locals); - dir->locals = (lfs_globals_t){{{0}}}; + lfs_globalxor(&lfs->locals, &dir->locals); + lfs_globalzero(&dir->locals); // increment revision count dir->rev += 1; @@ -933,8 +986,8 @@ relocate: if (!relocated) { // successful commit, update globals - lfs_globalsxor(&dir->locals, &lfs->diff); - lfs->diff = (lfs_globals_t){{{0}}}; + lfs_globalxor(&dir->locals, &lfs->locals); + lfs_globalzero(&lfs->locals); } else { // update references if we relocated LFS_DEBUG("Relocating %d %d to %d %d", @@ -962,18 +1015,21 @@ relocate: static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, const lfs_mattr_t *attrs) { - bool canceling = (lfs_paircmp(dir->pair, lfs->globals.move.pair) == 0); - lfs_mattr_t cancel; - if (canceling) { + lfs_mattr_t cancelattr; + lfs_global_t canceldiff; + lfs_globalzero(&canceldiff); + if (lfs_paircmp(dir->pair, lfs_globalmovepair(lfs)) == 0) { // Wait, we have the move? Just cancel this out here // We need to, or else the move can become outdated - lfs->diff.move.pair[0] ^= 0xffffffff ^ lfs->globals.move.pair[0]; - lfs->diff.move.pair[1] ^= 0xffffffff ^ lfs->globals.move.pair[1]; - lfs->diff.move.id ^= 0x3ff ^ lfs->globals.move.id; + lfs_globalxormove(&canceldiff, + lfs_globalmovepair(lfs), lfs_globalmoveid(lfs)); + lfs_globalxormove(&canceldiff, + (lfs_block_t[2]){0xffffffff, 0xffffffff}, 0x3ff); + lfs_globalxor(&lfs->locals, &canceldiff); - cancel.tag = LFS_MKTAG(LFS_TYPE_DELETE, lfs->globals.move.id, 0); - cancel.next = attrs; - attrs = &cancel; + cancelattr.tag = LFS_MKTAG(LFS_TYPE_DELETE, lfs_globalmoveid(lfs), 0); + cancelattr.next = attrs; + attrs = &cancelattr; } // calculate new directory size @@ -1001,7 +1057,7 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, pdir.split = dir->split; pdir.tail[0] = dir->tail[0]; pdir.tail[1] = dir->tail[1]; - lfs_globalsxor(&lfs->diff, &dir->locals); + lfs_globalxor(&lfs->locals, &dir->locals); return lfs_dir_commit(lfs, &pdir, LFS_MKATTR(LFS_TYPE_TAIL + pdir.split, 0x3ff, pdir.tail, sizeof(pdir.tail), @@ -1074,16 +1130,12 @@ compact: dir->off = commit.off; dir->etag = commit.ptag; // successful commit, update globals - lfs_globalsxor(&dir->locals, &lfs->diff); - lfs->diff = (lfs_globals_t){{{0}}}; + lfs_globalxor(&dir->locals, &lfs->locals); + lfs_globalzero(&lfs->locals); } // update globals that are affected - if (canceling) { - lfs->globals.move.pair[0] = 0xffffffff; - lfs->globals.move.pair[1] = 0xffffffff; - lfs->globals.move.id = 0x3ff; - } + lfs_globalxor(&lfs->globals, &canceldiff); // update any directories that are affected for (lfs_dir_t *d = lfs->dirs; d; d = d->next) { @@ -1147,7 +1199,8 @@ static int32_t lfs_dir_find(lfs_t *lfs, uint16_t tempcount = 0; lfs_block_t temptail[2] = {0xffffffff, 0xffffffff}; bool tempsplit = false; - lfs_globals_t templocals = (lfs_globals_t){{{0}}}; + lfs_global_t templocals; + lfs_globalzero(&templocals); while (true) { // extract next tag @@ -1252,11 +1305,11 @@ static int32_t lfs_dir_find(lfs_t *lfs, // consider what we have good enough if (dir->off > 0) { // synthetic move - if (lfs_paircmp(dir->pair, lfs->globals.move.pair) == 0) { - if (lfs->globals.move.id == lfs_tagid(foundtag)) { + if (lfs_paircmp(dir->pair, lfs_globalmovepair(lfs)) == 0) { + if (lfs_globalmoveid(lfs) == lfs_tagid(foundtag)) { foundtag = LFS_ERR_NOENT; } else if (lfs_tagisvalid(foundtag) && - lfs->globals.move.id < lfs_tagid(foundtag)) { + lfs_globalmoveid(lfs) < lfs_tagid(foundtag)) { foundtag -= LFS_MKTAG(0, 1, 0); } } @@ -1286,8 +1339,8 @@ static int lfs_dir_fetch(lfs_t *lfs, static int32_t lfs_dir_get(lfs_t *lfs, lfs_mdir_t *dir, uint32_t getmask, uint32_t gettag, void *buffer) { int32_t getdiff = 0; - if (lfs_paircmp(dir->pair, lfs->globals.move.pair) == 0 && - lfs_tagid(gettag) <= lfs->globals.move.id) { + if (lfs_paircmp(dir->pair, lfs_globalmovepair(lfs)) == 0 && + lfs_tagid(gettag) <= lfs_globalmoveid(lfs)) { // synthetic moves getdiff = LFS_MKTAG(0, 1, 0); } @@ -1422,11 +1475,9 @@ static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir, /// Top level directory operations /// int lfs_mkdir(lfs_t *lfs, const char *path) { // deorphan if we haven't yet, needed at most once after poweron - if (!lfs->deorphaned) { - int err = lfs_deorphan(lfs); - if (err) { - return err; - } + int err = lfs_forceconsistency(lfs); + if (err) { + return err; } lfs_mdir_t cwd; @@ -1445,7 +1496,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { lfs_alloc_ack(lfs); lfs_mdir_t dir; - int err = lfs_dir_alloc(lfs, &dir, false, cwd.tail); + err = lfs_dir_alloc(lfs, &dir, false, cwd.tail); if (err) { return err; } @@ -1817,8 +1868,8 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, const char *path, int flags, const struct lfs_file_config *cfg) { // deorphan if we haven't yet, needed at most once after poweron - if ((flags & 3) != LFS_O_RDONLY && !lfs->deorphaned) { - int err = lfs_deorphan(lfs); + if ((flags & 3) != LFS_O_RDONLY) { + int err = lfs_forceconsistency(lfs); if (err) { return err; } @@ -2543,15 +2594,13 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) { int lfs_remove(lfs_t *lfs, const char *path) { // deorphan if we haven't yet, needed at most once after poweron - if (!lfs->deorphaned) { - int err = lfs_deorphan(lfs); - if (err) { - return err; - } + int err = lfs_forceconsistency(lfs); + if (err) { + return err; } lfs_mdir_t cwd; - int err = lfs_dir_fetch(lfs, &cwd, lfs->root); + err = lfs_dir_fetch(lfs, &cwd, lfs->root); if (err) { return err; } @@ -2580,6 +2629,9 @@ int lfs_remove(lfs_t *lfs, const char *path) { if (dir.count > 0 || dir.split) { return LFS_ERR_NOTEMPTY; } + + // mark fs as orphaned + lfs_globaldeorphaned(lfs, false); } // delete the entry @@ -2596,11 +2648,14 @@ int lfs_remove(lfs_t *lfs, const char *path) { return err; } + // fix orphan + lfs_globaldeorphaned(lfs, true); + // steal state // TODO test for global state stealing? cwd.tail[0] = dir.tail[0]; cwd.tail[1] = dir.tail[1]; - lfs_globalsxor(&lfs->diff, &dir.locals); + lfs_globalxor(&lfs->locals, &dir.locals); err = lfs_dir_commit(lfs, &cwd, LFS_MKATTR(LFS_TYPE_SOFTTAIL, 0x3ff, cwd.tail, sizeof(cwd.tail), @@ -2615,11 +2670,9 @@ int lfs_remove(lfs_t *lfs, const char *path) { int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { // deorphan if we haven't yet, needed at most once after poweron - if (!lfs->deorphaned) { - int err = lfs_deorphan(lfs); - if (err) { - return err; - } + int err = lfs_forceconsistency(lfs); + if (err) { + return err; } // find old entry @@ -2665,6 +2718,9 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { if (prevdir.count > 0 || prevdir.split) { return LFS_ERR_NOTEMPTY; } + + // mark fs as orphaned + lfs_globaldeorphaned(lfs, false); } } else { // check that name fits @@ -2678,15 +2734,10 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { } // create move to fix later - lfs->diff.move.pair[0] = oldcwd.pair[0] ^ lfs->globals.move.pair[0]; - lfs->diff.move.pair[1] = oldcwd.pair[1] ^ lfs->globals.move.pair[1]; - lfs->diff.move.id = lfs_tagid(oldtag) ^ lfs->globals.move.id; - lfs->globals.move.pair[0] = oldcwd.pair[0]; - lfs->globals.move.pair[1] = oldcwd.pair[1]; - lfs->globals.move.id = lfs_tagid(oldtag); + lfs_globalmove(lfs, oldcwd.pair, lfs_tagid(oldtag)); // move over all attributes - int err = lfs_dir_commit(lfs, &newcwd, + err = lfs_dir_commit(lfs, &newcwd, LFS_MKATTR(lfs_tagtype(oldtag), newid, newpath, strlen(newpath), LFS_MKATTR(LFS_FROM_MOVE, newid, &oldcwd, lfs_tagid(oldtag), NULL))); @@ -2709,11 +2760,14 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { return err; } + // fix orphan + lfs_globaldeorphaned(lfs, true); + // steal state // TODO test for global state stealing? newcwd.tail[0] = prevdir.tail[0]; newcwd.tail[1] = prevdir.tail[1]; - lfs_globalsxor(&lfs->diff, &prevdir.locals); + lfs_globalxor(&lfs->locals, &prevdir.locals); err = lfs_dir_commit(lfs, &newcwd, LFS_MKATTR(LFS_TYPE_SOFTTAIL, 0x3ff, newcwd.tail, sizeof(newcwd.tail), @@ -2743,7 +2797,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { // // if we were a directory, find pred, replace tail // // TODO can this just deorphan? // if (prevexists && lfs_tagsubtype(prevattr.tag) == LFS_TYPE_DIR) { -// err = lfs_deorphan(lfs); +// err = lfs_forceconsistency(lfs); // if (err) { // return err; // } @@ -2936,10 +2990,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { lfs->root[1] = 0xffffffff; lfs->files = NULL; lfs->dirs = NULL; - lfs->deorphaned = false; - lfs->globals.move.pair[0] = 0xffffffff; - lfs->globals.move.pair[1] = 0xffffffff; - lfs->globals.move.id = 0x3ff; + lfs_globalones(&lfs->globals); // scan for any global updates // TODO rm me? need to grab any inits @@ -3348,7 +3399,7 @@ static int lfs_relocate(lfs_t *lfs, } // clean up bad block, which should now be a desync - return lfs_deorphan(lfs); + return lfs_forceconsistency(lfs); } // find pred @@ -3380,7 +3431,7 @@ int lfs_scan(lfs_t *lfs) { } lfs_mdir_t dir = {.tail = {0, 1}}; - lfs->diff = (lfs_globals_t){{{0}}}; + lfs_globalzero(&lfs->locals); // iterate over all directory directory entries while (!lfs_pairisnull(dir.tail)) { @@ -3390,40 +3441,105 @@ int lfs_scan(lfs_t *lfs) { } // xor together indirect deletes - lfs_globalsxor(&lfs->diff, &dir.locals); + lfs_globalxor(&lfs->locals, &dir.locals); } // update littlefs with globals // TODO does this only run once? // TODO Should we inline this into init?? - lfs_globalsxor(&lfs->globals, &lfs->diff); - lfs->diff = (lfs_globals_t){{{0}}}; - if (!lfs_pairisnull(lfs->globals.move.pair)) { + lfs_globalxor(&lfs->globals, &lfs->locals); + lfs_globalzero(&lfs->locals); + if (!lfs_pairisnull(lfs_globalmovepair(lfs))) { LFS_DEBUG("Found move %d %d %d", - lfs->globals.move.pair[0], - lfs->globals.move.pair[1], - lfs->globals.move.id); + lfs_globalmovepair(lfs)[0], + lfs_globalmovepair(lfs)[1], + lfs_globalmoveid(lfs)); } return 0; } -int lfs_deorphan(lfs_t *lfs) { - lfs->deorphaned = true; - if (lfs_pairisnull(lfs->root)) { // TODO rm me? - return 0; +int lfs_forceconsistency(lfs_t *lfs) { + if (!lfs_globalisdeorphaned(lfs)) { + // Fix any orphans + lfs_mdir_t pdir = {.split = true}; + lfs_mdir_t dir = {.tail = {0, 1}}; + + // iterate over all directory directory entries + while (!lfs_pairisnull(dir.tail)) { + int err = lfs_dir_fetch(lfs, &dir, dir.tail); + if (err) { + return err; + } + + // check head blocks for orphans + if (!pdir.split) { + // check if we have a parent + lfs_mdir_t parent; + int32_t tag = lfs_parent(lfs, pdir.tail, &parent); + if (tag < 0 && tag != LFS_ERR_NOENT) { + return tag; + } + + if (tag == LFS_ERR_NOENT) { + // we are an orphan + LFS_DEBUG("Found orphan %d %d", + pdir.tail[0], pdir.tail[1]); + + pdir.tail[0] = dir.tail[0]; + pdir.tail[1] = dir.tail[1]; + err = lfs_dir_commit(lfs, &pdir, + LFS_MKATTR(LFS_TYPE_SOFTTAIL, 0x3ff, + pdir.tail, sizeof(pdir.tail), + NULL)); + if (err) { + return err; + } + + break; + } + + lfs_block_t pair[2]; + int32_t res = lfs_dir_get(lfs, &parent, 0x7ffff000, tag, pair); + if (res < 0) { + return res; + } + + if (!lfs_pairsync(pair, pdir.tail)) { + // we have desynced + LFS_DEBUG("Found half-orphan %d %d", pair[0], pair[1]); + + pdir.tail[0] = pair[0]; + pdir.tail[1] = pair[1]; + err = lfs_dir_commit(lfs, &pdir, + LFS_MKATTR(LFS_TYPE_SOFTTAIL, 0x3ff, + pdir.tail, sizeof(pdir.tail), + NULL)); + if (err) { + return err; + } + + break; + } + } + + memcpy(&pdir, &dir, sizeof(pdir)); + } + + // mark orphan as fixed + lfs_globaldeorphaned(lfs, false); } - // Fix bad moves - if (!lfs_pairisnull(lfs->globals.move.pair)) { + if (lfs_globalmoveid(lfs) != 0x3ff) { + // Fix bad moves LFS_DEBUG("Fixing move %d %d %d", // TODO move to just deorphan? - lfs->globals.move.pair[0], - lfs->globals.move.pair[1], - lfs->globals.move.id); + lfs_globalmovepair(lfs)[0], + lfs_globalmovepair(lfs)[1], + lfs_globalmoveid(lfs)); // fetch and delete the moved entry lfs_mdir_t movedir; - int err = lfs_dir_fetch(lfs, &movedir, lfs->globals.move.pair); + int err = lfs_dir_fetch(lfs, &movedir, lfs_globalmovepair(lfs)); if (err) { return err; } @@ -3435,69 +3551,6 @@ int lfs_deorphan(lfs_t *lfs) { } } - lfs_mdir_t pdir = {.split = true}; - lfs_mdir_t dir = {.tail = {0, 1}}; - - // iterate over all directory directory entries - while (!lfs_pairisnull(dir.tail)) { - int err = lfs_dir_fetch(lfs, &dir, dir.tail); - if (err) { - return err; - } - - // check head blocks for orphans - if (!pdir.split) { - // check if we have a parent - lfs_mdir_t parent; - int32_t tag = lfs_parent(lfs, pdir.tail, &parent); - if (tag < 0 && tag != LFS_ERR_NOENT) { - return tag; - } - - if (tag == LFS_ERR_NOENT) { - // we are an orphan - LFS_DEBUG("Found orphan %d %d", pdir.tail[0], pdir.tail[1]); - - pdir.tail[0] = dir.tail[0]; - pdir.tail[1] = dir.tail[1]; - err = lfs_dir_commit(lfs, &pdir, - LFS_MKATTR(LFS_TYPE_SOFTTAIL, 0x3ff, - pdir.tail, sizeof(pdir.tail), - NULL)); - if (err) { - return err; - } - - break; - } - - lfs_block_t pair[2]; - int32_t res = lfs_dir_get(lfs, &parent, 0x7ffff000, tag, pair); - if (res < 0) { - return res; - } - - if (!lfs_pairsync(pair, pdir.tail)) { - // we have desynced - LFS_DEBUG("Found half-orphan %d %d", pair[0], pair[1]); - - pdir.tail[0] = pair[0]; - pdir.tail[1] = pair[1]; - err = lfs_dir_commit(lfs, &pdir, - LFS_MKATTR(LFS_TYPE_SOFTTAIL, 0x3ff, - pdir.tail, sizeof(pdir.tail), - NULL)); - if (err) { - return err; - } - - break; - } - } - - memcpy(&pdir, &dir, sizeof(pdir)); - } - return 0; } diff --git a/lfs.h b/lfs.h index 62d170d..092161e 100644 --- a/lfs.h +++ b/lfs.h @@ -110,7 +110,7 @@ enum lfs_type { LFS_TYPE_TAIL = 0x0c0, LFS_TYPE_SOFTTAIL = 0x0c0, LFS_TYPE_HARDTAIL = 0x0c1, - LFS_TYPE_CRC = 0x0ff, + LFS_TYPE_CRC = 0x0ff, // TODO are trailing ones useful? LFS_TYPE_INLINESTRUCT = 0x040, LFS_TYPE_CTZSTRUCT = 0x041, @@ -280,12 +280,9 @@ typedef struct lfs_mattr { const struct lfs_mattr *next; } lfs_mattr_t; -typedef struct lfs_globals { - struct lfs_move { - lfs_block_t pair[2]; - uint16_t id; - } move; -} lfs_globals_t; +typedef union lfs_global { + uint16_t u16[5]; +} lfs_global_t; typedef struct lfs_mdir { lfs_block_t pair[2]; @@ -296,7 +293,7 @@ typedef struct lfs_mdir { uint16_t count; bool erased; bool split; - lfs_globals_t locals; + lfs_global_t locals; } lfs_mdir_t; typedef struct lfs_cache { @@ -314,12 +311,13 @@ typedef struct lfs_file { lfs_size_t size; } ctz; - const struct lfs_file_config *cfg; uint32_t flags; lfs_off_t pos; lfs_block_t block; lfs_off_t off; lfs_cache_t cache; + + const struct lfs_file_config *cfg; } lfs_file_t; typedef struct lfs_dir { @@ -353,21 +351,18 @@ typedef struct lfs_free { // The littlefs type typedef struct lfs { - const struct lfs_config *cfg; + lfs_cache_t rcache; + lfs_cache_t pcache; lfs_block_t root[2]; lfs_file_t *files; lfs_dir_t *dirs; - lfs_cache_t rcache; - lfs_cache_t pcache; - + lfs_global_t globals; + lfs_global_t locals; lfs_free_t free; - bool deorphaned; - lfs_globals_t globals2; - lfs_globals_t globals; - lfs_globals_t diff; + const struct lfs_config *cfg; lfs_size_t inline_size; lfs_size_t attr_size; lfs_size_t name_size;