mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 08:48:31 +01:00
WIP Fixed issues around wrong ids after bad commits
This commit is contained in:
80
lfs.c
80
lfs.c
@@ -721,16 +721,18 @@ static int lfs_commit_move(lfs_t *lfs, struct lfs_commit *commit,
|
|||||||
|
|
||||||
static int lfs_commit_globals(lfs_t *lfs, struct lfs_commit *commit,
|
static int lfs_commit_globals(lfs_t *lfs, struct lfs_commit *commit,
|
||||||
const lfs_globals_t *source, const lfs_globals_t *diff) {
|
const lfs_globals_t *source, const lfs_globals_t *diff) {
|
||||||
lfs_globals_t res = lfs_globals_xor(source, diff);
|
if (lfs_globals_iszero(diff)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!lfs_globals_iszero(&res)) {
|
// TODO check performance/complexity of different strategies here
|
||||||
int err = lfs_commit_commit(lfs, commit, (lfs_mattr_t){
|
lfs_globals_t res = lfs_globals_xor(source, diff);
|
||||||
lfs_mktag(LFS_TYPE_IDELETE,
|
int err = lfs_commit_commit(lfs, commit, (lfs_mattr_t){
|
||||||
res.move.id, sizeof(res.move.pair)),
|
lfs_mktag(LFS_TYPE_IDELETE,
|
||||||
.u.buffer=res.move.pair});
|
res.move.id, sizeof(res.move.pair)),
|
||||||
if (err) {
|
.u.buffer=res.move.pair});
|
||||||
return err;
|
if (err) {
|
||||||
}
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -878,6 +880,17 @@ static int lfs_dir_fetchwith(lfs_t *lfs,
|
|||||||
temp.etag = tag;
|
temp.etag = tag;
|
||||||
crc = 0xffffffff;
|
crc = 0xffffffff;
|
||||||
*dir = temp;
|
*dir = temp;
|
||||||
|
|
||||||
|
// TODO simplify this?
|
||||||
|
if (cb) {
|
||||||
|
err = cb(lfs, data, (lfs_mattr_t){
|
||||||
|
(tag | 0x80000000),
|
||||||
|
.u.d.block=temp.pair[0],
|
||||||
|
.u.d.off=off+sizeof(tag)});
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO crc before callback???
|
// TODO crc before callback???
|
||||||
err = lfs_bd_crc(lfs, temp.pair[0],
|
err = lfs_bd_crc(lfs, temp.pair[0],
|
||||||
@@ -1008,6 +1021,11 @@ static int lfs_dir_compact(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list,
|
|||||||
const lfs_block_t oldpair[2] = {dir->pair[1], dir->pair[0]};
|
const lfs_block_t oldpair[2] = {dir->pair[1], dir->pair[0]};
|
||||||
bool relocated = false;
|
bool relocated = false;
|
||||||
|
|
||||||
|
// There's nothing special about our global delta, so feed it back
|
||||||
|
// into the global global delta
|
||||||
|
lfs->diff = lfs_globals_xor(&lfs->diff, &dir->globals);
|
||||||
|
dir->globals = (lfs_globals_t){0};
|
||||||
|
|
||||||
// increment revision count
|
// increment revision count
|
||||||
dir->rev += 1;
|
dir->rev += 1;
|
||||||
|
|
||||||
@@ -1207,14 +1225,12 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lfs_globals_iszero(&lfs->diff)) {
|
err = lfs_commit_globals(lfs, &commit, &dir->globals, &lfs->diff);
|
||||||
err = lfs_commit_globals(lfs, &commit, &dir->globals, &lfs->diff);
|
if (err) {
|
||||||
if (err) {
|
if (err == LFS_ERR_NOSPC || err == LFS_ERR_CORRUPT) {
|
||||||
if (err == LFS_ERR_NOSPC || err == LFS_ERR_CORRUPT) {
|
goto compact;
|
||||||
goto compact;
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lfs_commit_crc(lfs, &commit);
|
err = lfs_commit_crc(lfs, &commit);
|
||||||
@@ -1242,6 +1258,7 @@ compact:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update any directories that are affected
|
// update any directories that are affected
|
||||||
|
// TODO what about pairs? what if we're splitting??
|
||||||
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) {
|
||||||
d->m = *dir;
|
d->m = *dir;
|
||||||
@@ -1441,6 +1458,7 @@ struct lfs_dir_find {
|
|||||||
const char *name;
|
const char *name;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
int16_t id;
|
int16_t id;
|
||||||
|
int16_t tempid;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
||||||
@@ -1456,14 +1474,16 @@ static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
|||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
// found a match
|
// found a match
|
||||||
find->id = lfs_tag_id(attr.tag);
|
find->tempid = lfs_tag_id(attr.tag);
|
||||||
}
|
}
|
||||||
} else if (lfs_tag_type(attr.tag) == LFS_STRUCT_DELETE) {
|
} else if (lfs_tag_type(attr.tag) == LFS_STRUCT_DELETE) {
|
||||||
if (lfs_tag_id(attr.tag) == find->id) {
|
if (lfs_tag_id(attr.tag) == find->tempid) {
|
||||||
find->id = -1;
|
find->tempid = -1;
|
||||||
} else if (lfs_tag_id(attr.tag) < find->id) {
|
} else if (lfs_tag_id(attr.tag) < find->tempid) {
|
||||||
find->id -= 1;
|
find->tempid -= 1;
|
||||||
}
|
}
|
||||||
|
} else if (lfs_tag_type(attr.tag) == LFS_TYPE_CRC) {
|
||||||
|
find->id = find->tempid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1531,6 +1551,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
|
|||||||
while (true) {
|
while (true) {
|
||||||
//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;
|
||||||
|
find.tempid = -1;
|
||||||
int err = lfs_dir_fetchwith(lfs, dir, attr.u.pair,
|
int err = lfs_dir_fetchwith(lfs, dir, attr.u.pair,
|
||||||
lfs_dir_findscan, &find);
|
lfs_dir_findscan, &find);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -3451,9 +3472,11 @@ static int lfs_pred(lfs_t *lfs, const lfs_block_t dir[2], lfs_mdir_t *pdir) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// TODO combine parentscan and findscan?
|
||||||
struct lfs_dir_parentscan {
|
struct lfs_dir_parentscan {
|
||||||
lfs_block_t pair[2];
|
lfs_block_t pair[2];
|
||||||
int16_t id;
|
int16_t id;
|
||||||
|
int16_t tempid;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int lfs_parentscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
static int lfs_parentscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
||||||
@@ -3468,14 +3491,16 @@ static int lfs_parentscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
|
|||||||
|
|
||||||
if (lfs_paircmp(attr.u.pair, parentscan->pair) == 0) {
|
if (lfs_paircmp(attr.u.pair, parentscan->pair) == 0) {
|
||||||
// found a match
|
// found a match
|
||||||
parentscan->id = lfs_tag_id(attr.tag);
|
parentscan->tempid = lfs_tag_id(attr.tag);
|
||||||
}
|
}
|
||||||
} else if (lfs_tag_struct(attr.tag) == LFS_STRUCT_DELETE) {
|
} else if (lfs_tag_struct(attr.tag) == LFS_STRUCT_DELETE) {
|
||||||
if (lfs_tag_id(attr.tag) == parentscan->id) {
|
if (lfs_tag_id(attr.tag) == parentscan->tempid) {
|
||||||
parentscan->id = -1;
|
parentscan->tempid = -1;
|
||||||
} else if (lfs_tag_id(attr.tag) < parentscan->id) {
|
} else if (lfs_tag_id(attr.tag) < parentscan->tempid) {
|
||||||
parentscan->id -= 1;
|
parentscan->tempid -= 1;
|
||||||
}
|
}
|
||||||
|
} else if (lfs_tag_type(attr.tag) == LFS_TYPE_CRC) {
|
||||||
|
parentscan->id = parentscan->tempid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3490,7 +3515,8 @@ static int lfs_parent(lfs_t *lfs, const lfs_block_t pair[2],
|
|||||||
struct lfs_dir_parentscan parentscan = {
|
struct lfs_dir_parentscan parentscan = {
|
||||||
.pair[0] = pair[0],
|
.pair[0] = pair[0],
|
||||||
.pair[1] = pair[1],
|
.pair[1] = pair[1],
|
||||||
.id = -1
|
.id = -1,
|
||||||
|
.tempid = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
int err = lfs_dir_fetchwith(lfs, parent, parent->tail,
|
int err = lfs_dir_fetchwith(lfs, parent, parent->tail,
|
||||||
|
|||||||
@@ -152,8 +152,6 @@ tests/test.py << TEST
|
|||||||
strcmp(info.name, "..") => 0;
|
strcmp(info.name, "..") => 0;
|
||||||
info.type => LFS_TYPE_DIR;
|
info.type => LFS_TYPE_DIR;
|
||||||
lfs_dir_read(&lfs, &dir[0], &info) => 1;
|
lfs_dir_read(&lfs, &dir[0], &info) => 1;
|
||||||
printf("nameee \"%s\"\n", info.name);
|
|
||||||
printf("expect \"%s\"\n", "burito");
|
|
||||||
strcmp(info.name, "burito") => 0;
|
strcmp(info.name, "burito") => 0;
|
||||||
info.type => LFS_TYPE_REG;
|
info.type => LFS_TYPE_REG;
|
||||||
lfs_dir_read(&lfs, &dir[0], &info) => 1;
|
lfs_dir_read(&lfs, &dir[0], &info) => 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user