mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 00:38:29 +01:00
WIP TEMP move work
This commit is contained in:
206
lfs.c
206
lfs.c
@@ -624,7 +624,7 @@ struct lfs_commit_move {
|
|||||||
|
|
||||||
|
|
||||||
// TODO redeclare
|
// TODO redeclare
|
||||||
static int lfs_mdir_traverse(lfs_t *lfs, lfs_mdir_t *dir,
|
static int lfs_dir_traverse(lfs_t *lfs, lfs_mdir_t *dir,
|
||||||
int (*cb)(lfs_t *lfs, void *data, lfs_mattr_t attr),
|
int (*cb)(lfs_t *lfs, void *data, lfs_mattr_t attr),
|
||||||
void *data);
|
void *data);
|
||||||
static int lfs_dir_get(lfs_t *lfs, lfs_mdir_t *dir,
|
static int lfs_dir_get(lfs_t *lfs, lfs_mdir_t *dir,
|
||||||
@@ -692,7 +692,7 @@ static int lfs_commit_move(lfs_t *lfs, struct lfs_commit *commit,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int err = lfs_mdir_traverse(lfs, dir, lfs_commit_movescan, &move);
|
int err = lfs_dir_traverse(lfs, dir, lfs_commit_movescan, &move);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -726,6 +726,7 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir,
|
|||||||
dir->tail[1] = tail[1];
|
dir->tail[1] = tail[1];
|
||||||
dir->erased = false;
|
dir->erased = false;
|
||||||
dir->split = split;
|
dir->split = split;
|
||||||
|
dir->idelete = (lfs_entry_t){{0, 0}, 0};
|
||||||
|
|
||||||
// don't write out yet, let caller take care of that
|
// don't write out yet, let caller take care of that
|
||||||
return 0;
|
return 0;
|
||||||
@@ -762,6 +763,7 @@ static int lfs_dir_fetchwith(lfs_t *lfs,
|
|||||||
dir->tail[1] = 0xffffffff;
|
dir->tail[1] = 0xffffffff;
|
||||||
dir->count = 0;
|
dir->count = 0;
|
||||||
dir->split = false;
|
dir->split = false;
|
||||||
|
dir->idelete = (lfs_entry_t){{0, 0}, 0};
|
||||||
dir->moveid = -1;
|
dir->moveid = -1;
|
||||||
|
|
||||||
dir->rev = lfs_tole32(rev[0]);
|
dir->rev = lfs_tole32(rev[0]);
|
||||||
@@ -783,6 +785,14 @@ static int lfs_dir_fetchwith(lfs_t *lfs,
|
|||||||
|
|
||||||
// next commit not yet programmed
|
// next commit not yet programmed
|
||||||
if (lfs_tag_type(ptag) == LFS_TYPE_CRC && !lfs_tag_valid(tag)) {
|
if (lfs_tag_type(ptag) == LFS_TYPE_CRC && !lfs_tag_valid(tag)) {
|
||||||
|
if (lfs_paircmp(dir->pair, lfs->idelete.pair) == 0 && cb) {
|
||||||
|
int err = cb(lfs, data, (lfs_mattr_t){
|
||||||
|
lfs_mktag(LFS_TYPE_DELETE, lfs->idelete.id, 0)});
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dir->erased = true;
|
dir->erased = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -807,6 +817,17 @@ static int lfs_dir_fetchwith(lfs_t *lfs,
|
|||||||
// try other block
|
// try other block
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
// TODO combine with above?
|
||||||
|
if (lfs_paircmp(dir->pair, lfs->idelete.pair) == 0
|
||||||
|
&& cb) {
|
||||||
|
int err = cb(lfs, data, (lfs_mattr_t){
|
||||||
|
lfs_mktag(LFS_TYPE_DELETE,
|
||||||
|
lfs->idelete.id, 0)});
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// consider what we have good enough
|
// consider what we have good enough
|
||||||
dir->erased = false;
|
dir->erased = false;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -818,6 +839,7 @@ static int lfs_dir_fetchwith(lfs_t *lfs,
|
|||||||
crc = 0xffffffff;
|
crc = 0xffffffff;
|
||||||
*dir = temp;
|
*dir = temp;
|
||||||
} else {
|
} else {
|
||||||
|
// TODO crc before callback???
|
||||||
err = lfs_bd_crc(lfs, temp.pair[0],
|
err = lfs_bd_crc(lfs, temp.pair[0],
|
||||||
off+sizeof(tag), lfs_tag_size(tag), &crc);
|
off+sizeof(tag), lfs_tag_size(tag), &crc);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -832,6 +854,12 @@ static int lfs_dir_fetchwith(lfs_t *lfs,
|
|||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
} else if (lfs_tag_type(tag) == LFS_TYPE_IDELETE) {
|
||||||
|
err = lfs_bd_read(lfs, temp.pair[0], off+sizeof(tag),
|
||||||
|
&temp.idelete, sizeof(temp.idelete));
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
} else if (lfs_tag_type(tag) == LFS_TYPE_MOVE) {
|
} else if (lfs_tag_type(tag) == LFS_TYPE_MOVE) {
|
||||||
// TODO handle moves correctly?
|
// TODO handle moves correctly?
|
||||||
temp.moveid = lfs_tag_id(tag);
|
temp.moveid = lfs_tag_id(tag);
|
||||||
@@ -883,35 +911,45 @@ static int lfs_dir_fetch(lfs_t *lfs,
|
|||||||
return lfs_dir_fetchwith(lfs, dir, pair, NULL, NULL);
|
return lfs_dir_fetchwith(lfs, dir, pair, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lfs_mdir_traverse(lfs_t *lfs, lfs_mdir_t *dir,
|
static int lfs_dir_traverse(lfs_t *lfs, lfs_mdir_t *dir,
|
||||||
int (*cb)(lfs_t *lfs, void *data, lfs_mattr_t attr), void *data) {
|
int (*cb)(lfs_t *lfs, void *data, lfs_mattr_t attr), void *data) {
|
||||||
// iterate over dir block backwards (for faster lookups)
|
// iterate over dir block backwards (for faster lookups)
|
||||||
lfs_block_t block = dir->pair[0];
|
lfs_block_t block = dir->pair[0];
|
||||||
lfs_off_t off = dir->off;
|
lfs_off_t off = dir->off;
|
||||||
lfs_tag_t tag = dir->etag;
|
lfs_tag_t tag = dir->etag;
|
||||||
|
|
||||||
|
if (lfs_paircmp(dir->pair, lfs->idelete.pair) == 0) {
|
||||||
|
int err = cb(lfs, data, (lfs_mattr_t){
|
||||||
|
lfs_mktag(LFS_TYPE_DELETE, lfs->idelete.id, 0)});
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (off != sizeof(uint32_t)) {
|
while (off != sizeof(uint32_t)) {
|
||||||
// TODO rm me
|
// TODO rm me
|
||||||
//printf("tag r %#010x (%x:%x %03x %03x %03x)\n", tag, block, off-lfs_tag_size(tag), lfs_tag_type(tag), lfs_tag_id(tag), lfs_tag_size(tag));
|
//printf("tag r %#010x (%x:%x %03x %03x %03x)\n", tag, block, off-lfs_tag_size(tag), lfs_tag_type(tag), lfs_tag_id(tag), lfs_tag_size(tag));
|
||||||
|
|
||||||
// TODO hmm
|
// TODO hmm
|
||||||
if (dir->stop_at_commit && lfs_tag_type(tag) == LFS_TYPE_CRC) {
|
if (lfs_tag_type(tag) == LFS_TYPE_CRC) {
|
||||||
break;
|
if (dir->stop_at_commit) {
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
int err = cb(lfs, data, (lfs_mattr_t){
|
} else {
|
||||||
(0x80000000 | tag),
|
int err = cb(lfs, data, (lfs_mattr_t){
|
||||||
.u.d.block=block,
|
(0x80000000 | tag),
|
||||||
.u.d.off=off-lfs_tag_size(tag)});
|
.u.d.block=block,
|
||||||
if (err) {
|
.u.d.off=off-lfs_tag_size(tag)});
|
||||||
return err;
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LFS_ASSERT(off > sizeof(tag)+lfs_tag_size(tag));
|
LFS_ASSERT(off > sizeof(tag)+lfs_tag_size(tag));
|
||||||
off -= sizeof(tag)+lfs_tag_size(tag);
|
off -= sizeof(tag)+lfs_tag_size(tag);
|
||||||
|
|
||||||
lfs_tag_t ntag;
|
lfs_tag_t ntag;
|
||||||
err = lfs_bd_read(lfs, block, off, &ntag, sizeof(ntag));
|
int err = lfs_bd_read(lfs, block, off, &ntag, sizeof(ntag));
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -963,7 +1001,7 @@ static int lfs_dir_compact(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list,
|
|||||||
.block = dir->pair[1],
|
.block = dir->pair[1],
|
||||||
.off = sizeof(dir->rev),
|
.off = sizeof(dir->rev),
|
||||||
|
|
||||||
// space is complicated, we need room for tail, crc,
|
// space is complicated, we need room for tail, crc, idelete,
|
||||||
// and we keep cap at around half a block
|
// and we keep cap at around half a block
|
||||||
.begin = 0,
|
.begin = 0,
|
||||||
.end = lfs_min(
|
.end = lfs_min(
|
||||||
@@ -1008,6 +1046,22 @@ static int lfs_dir_compact(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(dir->idelete.pair[0] == 0 &&
|
||||||
|
dir->idelete.pair[0] == 0 &&
|
||||||
|
dir->idelete.id == 0)) {
|
||||||
|
// TODO le32
|
||||||
|
err = lfs_commit_commit(lfs, &commit, (lfs_mattr_t){
|
||||||
|
lfs_mktag(LFS_TYPE_IDELETE,
|
||||||
|
0x1ff, sizeof(dir->idelete)),
|
||||||
|
.u.buffer=&dir->idelete});
|
||||||
|
if (err) {
|
||||||
|
if (err == LFS_ERR_CORRUPT) {
|
||||||
|
goto relocate;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = lfs_commit_crc(lfs, &commit);
|
err = lfs_commit_crc(lfs, &commit);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err == LFS_ERR_CORRUPT) {
|
if (err == LFS_ERR_CORRUPT) {
|
||||||
@@ -1130,7 +1184,6 @@ compact:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO combine with above?
|
|
||||||
// update any directories that are affected
|
// update any directories that are affected
|
||||||
for (lfs_dir_t *d = lfs->dirs; d; d = d->next) {
|
for (lfs_dir_t *d = lfs->dirs; d; d = d->next) {
|
||||||
if (lfs_paircmp(d->m.pair, dir->pair) == 0) {
|
if (lfs_paircmp(d->m.pair, dir->pair) == 0) {
|
||||||
@@ -1176,9 +1229,7 @@ static int lfs_dir_delete(lfs_t *lfs, lfs_mdir_t *dir, uint16_t id) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// shift over any files that are affected
|
// shift over any dirs/files that are affected
|
||||||
// TODO move this to dir_commit?
|
|
||||||
// TODO use entries???
|
|
||||||
for (lfs_dir_t *d = lfs->dirs; d; d = d->next) {
|
for (lfs_dir_t *d = lfs->dirs; d; d = d->next) {
|
||||||
if (lfs_paircmp(d->m.pair, dir->pair) == 0) {
|
if (lfs_paircmp(d->m.pair, dir->pair) == 0) {
|
||||||
if (d->id > id) {
|
if (d->id > id) {
|
||||||
@@ -1202,14 +1253,14 @@ static int lfs_dir_delete(lfs_t *lfs, lfs_mdir_t *dir, uint16_t id) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lfs_dir_getter {
|
struct lfs_dir_get {
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
lfs_tag_t tag;
|
lfs_tag_t tag;
|
||||||
lfs_mattr_t *attr;
|
lfs_mattr_t *attr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int lfs_dir_getter(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
static int lfs_dir_getscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
||||||
struct lfs_dir_getter *get = p;
|
struct lfs_dir_get *get = p;
|
||||||
|
|
||||||
if ((attr.tag & get->mask) == (get->tag & get->mask)) {
|
if ((attr.tag & get->mask) == (get->tag & get->mask)) {
|
||||||
*get->attr = attr;
|
*get->attr = attr;
|
||||||
@@ -1226,8 +1277,8 @@ static int lfs_dir_getter(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
|||||||
static int lfs_dir_get(lfs_t *lfs, lfs_mdir_t *dir,
|
static int lfs_dir_get(lfs_t *lfs, lfs_mdir_t *dir,
|
||||||
uint32_t mask, lfs_mattr_t *attr) {
|
uint32_t mask, lfs_mattr_t *attr) {
|
||||||
uint16_t id = lfs_tag_id(attr->tag);
|
uint16_t id = lfs_tag_id(attr->tag);
|
||||||
int res = lfs_mdir_traverse(lfs, dir, lfs_dir_getter,
|
int res = lfs_dir_traverse(lfs, dir, lfs_dir_getscan,
|
||||||
&(struct lfs_dir_getter){mask, attr->tag, attr});
|
&(struct lfs_dir_get){mask, attr->tag, attr});
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -1325,14 +1376,14 @@ static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lfs_dir_finder {
|
struct lfs_dir_find {
|
||||||
const char *name;
|
const char *name;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
int16_t id;
|
int16_t id;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int lfs_dir_finder(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
||||||
struct lfs_dir_finder *find = p;
|
struct lfs_dir_find *find = p;
|
||||||
|
|
||||||
if (lfs_tag_type(attr.tag) == LFS_TYPE_NAME &&
|
if (lfs_tag_type(attr.tag) == LFS_TYPE_NAME &&
|
||||||
lfs_tag_size(attr.tag) == find->len) {
|
lfs_tag_size(attr.tag) == find->len) {
|
||||||
@@ -1365,7 +1416,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
|
|||||||
.u.pair[1] = lfs->root[1],
|
.u.pair[1] = lfs->root[1],
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lfs_dir_finder find = {
|
struct lfs_dir_find find = {
|
||||||
.name = *path,
|
.name = *path,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1420,7 +1471,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
|
|||||||
//printf("checking %d %d for %s\n", attr.u.pair[0], attr.u.pair[1], *path);
|
//printf("checking %d %d for %s\n", attr.u.pair[0], attr.u.pair[1], *path);
|
||||||
find.id = -1;
|
find.id = -1;
|
||||||
int err = lfs_dir_fetchwith(lfs, dir, attr.u.pair,
|
int err = lfs_dir_fetchwith(lfs, dir, attr.u.pair,
|
||||||
lfs_dir_finder, &find);
|
lfs_dir_findscan, &find);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -2903,6 +2954,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
lfs->files = NULL;
|
lfs->files = NULL;
|
||||||
lfs->dirs = NULL;
|
lfs->dirs = NULL;
|
||||||
lfs->deorphaned = false;
|
lfs->deorphaned = false;
|
||||||
|
lfs->idelete = (lfs_entry_t){{0xffffffff, 0xffffffff}, 0xffff};
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -3260,36 +3312,100 @@ static int lfs_pred(lfs_t *lfs, const lfs_block_t dir[2], lfs_mdir_t *pdir) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
struct lfs_dir_parentscan {
|
||||||
|
lfs_block_t pair[2];
|
||||||
|
int16_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int lfs_parentscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
||||||
|
struct lfs_dir_parentscan *parentscan = p;
|
||||||
|
|
||||||
|
if ((lfs_tag_type(attr.tag) & 0x10f) == LFS_STRUCT_DIR) {
|
||||||
|
int err = lfs_bd_read(lfs, attr.u.d.block, attr.u.d.off,
|
||||||
|
&attr.u, sizeof(attr.u));
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lfs_paircmp(attr.u.pair, parentscan->pair) == 0) {
|
||||||
|
// found a match
|
||||||
|
parentscan->id = lfs_tag_id(attr.tag);
|
||||||
|
}
|
||||||
|
} else if (lfs_tag_type(attr.tag) == LFS_TYPE_DELETE) {
|
||||||
|
if (lfs_tag_id(attr.tag) == parentscan->id) {
|
||||||
|
parentscan->id = -1;
|
||||||
|
} else if (lfs_tag_id(attr.tag) < parentscan->id) {
|
||||||
|
parentscan->id -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int lfs_parent(lfs_t *lfs, const lfs_block_t pair[2],
|
static int lfs_parent(lfs_t *lfs, const lfs_block_t pair[2],
|
||||||
lfs_mdir_t *parent, lfs_mattr_t *attr) {
|
lfs_mdir_t *parent, lfs_mattr_t *attr) {
|
||||||
// iterate over all directory directory entries
|
// iterate over all directory directory entries
|
||||||
parent->tail[0] = 0;
|
parent->tail[0] = 0;
|
||||||
parent->tail[1] = 1;
|
parent->tail[1] = 1;
|
||||||
while (!lfs_pairisnull(parent->tail)) {
|
while (!lfs_pairisnull(parent->tail)) {
|
||||||
int err = lfs_dir_fetch(lfs, parent, parent->tail);
|
struct lfs_dir_parentscan parentscan = {
|
||||||
|
.pair[0] = pair[0],
|
||||||
|
.pair[1] = pair[1],
|
||||||
|
.id = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
int err = lfs_dir_fetchwith(lfs, parent, parent->tail,
|
||||||
|
lfs_parentscan, &parentscan);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO make this O(n) by using fetchwith to match the pointers
|
if (parentscan.id != -1) {
|
||||||
for (uint16_t id = 0; id < parent->count; id++) {
|
|
||||||
int err = lfs_dir_getentry(lfs, parent, 0x43dff000,
|
int err = lfs_dir_getentry(lfs, parent, 0x43dff000,
|
||||||
lfs_mktag(LFS_STRUCT_DIR, id, 0), attr);
|
lfs_mktag(LFS_STRUCT_DIR, parentscan.id, 0), attr);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err == LFS_ERR_NOENT) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lfs_paircmp(attr->u.pair, pair) == 0) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
//static int lfs_parent(lfs_t *lfs, const lfs_block_t pair[2],
|
||||||
|
// lfs_mdir_t *parent, lfs_mattr_t *attr) {
|
||||||
|
// // iterate over all directory directory entries
|
||||||
|
// parent->tail[0] = 0;
|
||||||
|
// parent->tail[1] = 1;
|
||||||
|
// while (!lfs_pairisnull(parent->tail)) {
|
||||||
|
// int err = lfs_dir_fetch(lfs, parent, parent->tail);
|
||||||
|
// if (err) {
|
||||||
|
// return err;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // TODO make this O(n) by using fetchwith to match the pointers
|
||||||
|
// for (uint16_t id = 0; id < parent->count; id++) {
|
||||||
|
// int err = lfs_dir_getentry(lfs, parent, 0x43dff000,
|
||||||
|
// lfs_mktag(LFS_STRUCT_DIR, id, 0), attr);
|
||||||
|
// if (err) {
|
||||||
|
// if (err == LFS_ERR_NOENT) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// return err;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (lfs_paircmp(attr->u.pair, pair) == 0) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
/*
|
/*
|
||||||
static int lfs_parent(lfs_t *lfs, const lfs_block_t dir[2],
|
static int lfs_parent(lfs_t *lfs, const lfs_block_t dir[2],
|
||||||
lfs_mdir_t *parent, lfs_mattr_t *attr) {
|
lfs_mdir_t *parent, lfs_mattr_t *attr) {
|
||||||
@@ -3494,6 +3610,7 @@ int lfs_deorphan(lfs_t *lfs) {
|
|||||||
|
|
||||||
lfs_mdir_t pdir = {.split = true};
|
lfs_mdir_t pdir = {.split = true};
|
||||||
lfs_mdir_t dir = {.tail = {0, 1}};
|
lfs_mdir_t dir = {.tail = {0, 1}};
|
||||||
|
lfs_entry_t idelete = {{0xffffffff, 0xffffffff}, 0xffff};
|
||||||
|
|
||||||
// iterate over all directory directory entries
|
// iterate over all directory directory entries
|
||||||
while (!lfs_pairisnull(dir.tail)) {
|
while (!lfs_pairisnull(dir.tail)) {
|
||||||
@@ -3502,6 +3619,11 @@ int lfs_deorphan(lfs_t *lfs) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// xor together indirect deletes
|
||||||
|
idelete.pair[0] ^= dir.idelete.pair[0];
|
||||||
|
idelete.pair[1] ^= dir.idelete.pair[1];
|
||||||
|
idelete.id ^= dir.idelete.id;
|
||||||
|
|
||||||
// check head blocks for orphans
|
// check head blocks for orphans
|
||||||
if (!pdir.split) {
|
if (!pdir.split) {
|
||||||
// check if we have a parent
|
// check if we have a parent
|
||||||
@@ -3531,7 +3653,7 @@ int lfs_deorphan(lfs_t *lfs) {
|
|||||||
|
|
||||||
if (!lfs_pairsync(attr.u.pair, pdir.tail)) {
|
if (!lfs_pairsync(attr.u.pair, pdir.tail)) {
|
||||||
// we have desynced
|
// we have desynced
|
||||||
LFS_DEBUG("Found desync %d %d",
|
LFS_DEBUG("Found half-orphan %d %d",
|
||||||
attr.u.pair[0], attr.u.pair[1]);
|
attr.u.pair[0], attr.u.pair[1]);
|
||||||
|
|
||||||
pdir.tail[0] = attr.u.pair[0];
|
pdir.tail[0] = attr.u.pair[0];
|
||||||
@@ -3580,6 +3702,10 @@ int lfs_deorphan(lfs_t *lfs) {
|
|||||||
memcpy(&pdir, &dir, sizeof(pdir));
|
memcpy(&pdir, &dir, sizeof(pdir));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update littlefs with current move
|
||||||
|
// TODO do this here? needs to be before reads also
|
||||||
|
lfs->idelete = idelete;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|||||||
39
lfs.h
39
lfs.h
@@ -102,9 +102,10 @@ enum lfs_type {
|
|||||||
// internally used types
|
// internally used types
|
||||||
LFS_TYPE_NAME = 0x010,
|
LFS_TYPE_NAME = 0x010,
|
||||||
LFS_TYPE_MOVE = 0x080,
|
LFS_TYPE_MOVE = 0x080,
|
||||||
LFS_TYPE_DELETE = 0x090,
|
LFS_TYPE_DELETE = 0x020,
|
||||||
|
|
||||||
LFS_TYPE_SUPERBLOCK = 0x0a0,
|
LFS_TYPE_SUPERBLOCK = 0x030,
|
||||||
|
LFS_TYPE_IDELETE = 0x0b0,
|
||||||
LFS_TYPE_SOFTTAIL = 0x0c0,
|
LFS_TYPE_SOFTTAIL = 0x0c0,
|
||||||
LFS_TYPE_HARDTAIL = 0x0d0,
|
LFS_TYPE_HARDTAIL = 0x0d0,
|
||||||
LFS_TYPE_CRC = 0x0e0,
|
LFS_TYPE_CRC = 0x0e0,
|
||||||
@@ -285,6 +286,25 @@ typedef struct lfs_mattrlist {
|
|||||||
struct lfs_mattrlist *next;
|
struct lfs_mattrlist *next;
|
||||||
} lfs_mattrlist_t;
|
} lfs_mattrlist_t;
|
||||||
|
|
||||||
|
typedef struct lfs_entry {
|
||||||
|
lfs_block_t pair[2];
|
||||||
|
uint16_t id;
|
||||||
|
} lfs_entry_t;
|
||||||
|
|
||||||
|
typedef struct lfs_mdir {
|
||||||
|
lfs_block_t pair[2];
|
||||||
|
lfs_block_t tail[2];
|
||||||
|
uint32_t rev;
|
||||||
|
lfs_off_t off;
|
||||||
|
uint32_t etag;
|
||||||
|
uint16_t count;
|
||||||
|
bool erased;
|
||||||
|
bool split;
|
||||||
|
lfs_entry_t idelete;
|
||||||
|
bool stop_at_commit; // TODO hmmm
|
||||||
|
uint16_t moveid; // TODO rm me
|
||||||
|
} lfs_mdir_t;
|
||||||
|
|
||||||
typedef struct lfs_cache {
|
typedef struct lfs_cache {
|
||||||
lfs_block_t block;
|
lfs_block_t block;
|
||||||
lfs_off_t off;
|
lfs_off_t off;
|
||||||
@@ -307,19 +327,6 @@ typedef struct lfs_file {
|
|||||||
lfs_mattrlist_t *attrs;
|
lfs_mattrlist_t *attrs;
|
||||||
} lfs_file_t;
|
} lfs_file_t;
|
||||||
|
|
||||||
typedef struct lfs_mdir {
|
|
||||||
lfs_block_t pair[2];
|
|
||||||
lfs_block_t tail[2];
|
|
||||||
uint32_t rev;
|
|
||||||
lfs_off_t off;
|
|
||||||
uint32_t etag;
|
|
||||||
uint16_t count;
|
|
||||||
bool erased;
|
|
||||||
bool split;
|
|
||||||
bool stop_at_commit; // TODO hmmm
|
|
||||||
int16_t moveid;
|
|
||||||
} lfs_mdir_t;
|
|
||||||
|
|
||||||
typedef struct lfs_dir {
|
typedef struct lfs_dir {
|
||||||
struct lfs_dir *next;
|
struct lfs_dir *next;
|
||||||
struct lfs_mdir m;
|
struct lfs_mdir m;
|
||||||
@@ -363,6 +370,8 @@ typedef struct lfs {
|
|||||||
|
|
||||||
lfs_free_t free;
|
lfs_free_t free;
|
||||||
bool deorphaned;
|
bool deorphaned;
|
||||||
|
lfs_entry_t idelete;
|
||||||
|
lfs_entry_t diff;
|
||||||
|
|
||||||
lfs_size_t inline_size;
|
lfs_size_t inline_size;
|
||||||
lfs_size_t attrs_size;
|
lfs_size_t attrs_size;
|
||||||
|
|||||||
Reference in New Issue
Block a user