mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 16:14:13 +01:00
WIP fixed corruption tests
This commit is contained in:
85
lfs.c
85
lfs.c
@@ -488,8 +488,7 @@ static int32_t lfs_commitget(lfs_t *lfs, lfs_block_t block, lfs_off_t off,
|
|||||||
uint32_t tag, uint32_t getmask, uint32_t gettag, int32_t getdiff,
|
uint32_t tag, uint32_t getmask, uint32_t gettag, int32_t getdiff,
|
||||||
void *buffer, bool stopatcommit) {
|
void *buffer, bool stopatcommit) {
|
||||||
// iterate over dir block backwards (for faster lookups)
|
// iterate over dir block backwards (for faster lookups)
|
||||||
while (off > sizeof(tag)) {
|
while (off >= 2*sizeof(tag)+lfs_tagsize(tag)) {
|
||||||
LFS_ASSERT(off > sizeof(tag)+lfs_tagsize(tag));
|
|
||||||
off -= sizeof(tag)+lfs_tagsize(tag);
|
off -= sizeof(tag)+lfs_tagsize(tag);
|
||||||
|
|
||||||
if (lfs_tagtype(tag) == LFS_TYPE_CRC && stopatcommit) {
|
if (lfs_tagtype(tag) == LFS_TYPE_CRC && stopatcommit) {
|
||||||
@@ -1133,23 +1132,22 @@ static int32_t lfs_dir_find(lfs_t *lfs,
|
|||||||
lfs_off_t off = sizeof(dir->rev);
|
lfs_off_t off = sizeof(dir->rev);
|
||||||
uint32_t ptag = 0;
|
uint32_t ptag = 0;
|
||||||
uint32_t crc = 0xffffffff;
|
uint32_t crc = 0xffffffff;
|
||||||
dir->tail[0] = 0xffffffff;
|
|
||||||
dir->tail[1] = 0xffffffff;
|
|
||||||
dir->count = 0;
|
|
||||||
dir->split = false;
|
|
||||||
dir->locals = (lfs_globals_t){0};
|
|
||||||
|
|
||||||
dir->rev = lfs_tole32(rev[0]);
|
dir->rev = lfs_tole32(rev[0]);
|
||||||
lfs_crc(&crc, &dir->rev, sizeof(dir->rev));
|
lfs_crc(&crc, &dir->rev, sizeof(dir->rev));
|
||||||
dir->rev = lfs_fromle32(dir->rev);
|
dir->rev = lfs_fromle32(dir->rev);
|
||||||
|
dir->off = 0;
|
||||||
|
|
||||||
lfs_mdir_t tempdir = *dir;
|
|
||||||
uint32_t tempfoundtag = foundtag;
|
uint32_t tempfoundtag = foundtag;
|
||||||
|
uint16_t tempcount = 0;
|
||||||
|
lfs_block_t temptail[2] = {0xffffffff, 0xffffffff};
|
||||||
|
bool tempsplit = false;
|
||||||
|
lfs_globals_t templocals = (lfs_globals_t){0};
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// extract next tag
|
// extract next tag
|
||||||
uint32_t tag;
|
uint32_t tag;
|
||||||
int err = lfs_bd_read(lfs, tempdir.pair[0],
|
int err = lfs_bd_read(lfs, dir->pair[0],
|
||||||
off, &tag, sizeof(tag));
|
off, &tag, sizeof(tag));
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
@@ -1161,67 +1159,66 @@ static int32_t lfs_dir_find(lfs_t *lfs,
|
|||||||
// next commit not yet programmed
|
// next commit not yet programmed
|
||||||
if (lfs_tagtype(ptag) == LFS_TYPE_CRC && !lfs_tagisvalid(tag)) {
|
if (lfs_tagtype(ptag) == LFS_TYPE_CRC && !lfs_tagisvalid(tag)) {
|
||||||
dir->erased = true;
|
dir->erased = true;
|
||||||
goto done;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check we're in valid range
|
// check we're in valid range
|
||||||
if (off + sizeof(tag)+lfs_tagsize(tag) > lfs->cfg->block_size) {
|
if (off + sizeof(tag)+lfs_tagsize(tag) > lfs->cfg->block_size) {
|
||||||
|
dir->erased = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lfs_tagtype(tag) == LFS_TYPE_CRC) {
|
if (lfs_tagtype(tag) == LFS_TYPE_CRC) {
|
||||||
// check the crc attr
|
// check the crc attr
|
||||||
uint32_t dcrc;
|
uint32_t dcrc;
|
||||||
int err = lfs_bd_read(lfs, tempdir.pair[0],
|
int err = lfs_bd_read(lfs, dir->pair[0],
|
||||||
off+sizeof(tag), &dcrc, sizeof(dcrc));
|
off+sizeof(tag), &dcrc, sizeof(dcrc));
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crc != lfs_fromle32(dcrc)) {
|
if (crc != lfs_fromle32(dcrc)) {
|
||||||
if (off == sizeof(tempdir.rev)) {
|
|
||||||
// try other block
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// consider what we have good enough
|
|
||||||
dir->erased = false;
|
dir->erased = false;
|
||||||
goto done;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tempdir.off = off + sizeof(tag)+lfs_tagsize(tag);
|
|
||||||
tempdir.etag = tag;
|
|
||||||
crc = 0xffffffff;
|
|
||||||
*dir = tempdir;
|
|
||||||
foundtag = tempfoundtag;
|
foundtag = tempfoundtag;
|
||||||
|
dir->off = off + sizeof(tag)+lfs_tagsize(tag);
|
||||||
|
dir->etag = tag;
|
||||||
|
dir->count = tempcount;
|
||||||
|
dir->tail[0] = temptail[0];
|
||||||
|
dir->tail[1] = temptail[1];
|
||||||
|
dir->split = tempsplit;
|
||||||
|
dir->locals = templocals;
|
||||||
|
crc = 0xffffffff;
|
||||||
} else {
|
} else {
|
||||||
err = lfs_bd_crc(lfs, tempdir.pair[0],
|
err = lfs_bd_crc(lfs, dir->pair[0],
|
||||||
off+sizeof(tag), lfs_tagsize(tag), &crc);
|
off+sizeof(tag), lfs_tagsize(tag), &crc);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lfs_tagid(tag) < 0x3ff &&
|
if (lfs_tagid(tag) < 0x3ff && lfs_tagid(tag) >= tempcount) {
|
||||||
lfs_tagid(tag) >= tempdir.count) {
|
tempcount = lfs_tagid(tag)+1;
|
||||||
tempdir.count = lfs_tagid(tag)+1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO use subtype accross all of these?
|
||||||
if (lfs_tagsubtype(tag) == LFS_TYPE_TAIL) {
|
if (lfs_tagsubtype(tag) == LFS_TYPE_TAIL) {
|
||||||
tempdir.split = (lfs_tagtype(tag) & 1);
|
tempsplit = (lfs_tagtype(tag) & 1);
|
||||||
err = lfs_bd_read(lfs, tempdir.pair[0], off+sizeof(tag),
|
err = lfs_bd_read(lfs, dir->pair[0], off+sizeof(tag),
|
||||||
tempdir.tail, sizeof(tempdir.tail));
|
temptail, sizeof(temptail));
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
} else if (lfs_tagtype(tag) == LFS_TYPE_GLOBALS) {
|
} else if (lfs_tagtype(tag) == LFS_TYPE_GLOBALS) {
|
||||||
err = lfs_bd_read(lfs, tempdir.pair[0], off+sizeof(tag),
|
err = lfs_bd_read(lfs, dir->pair[0], off+sizeof(tag),
|
||||||
&tempdir.locals, sizeof(tempdir.locals));
|
&templocals, sizeof(templocals));
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
} else if (lfs_tagtype(tag) == LFS_TYPE_DELETE) {
|
} else if (lfs_tagtype(tag) == LFS_TYPE_DELETE) {
|
||||||
LFS_ASSERT(tempdir.count > 0);
|
LFS_ASSERT(tempcount > 0);
|
||||||
tempdir.count -= 1;
|
tempcount -= 1;
|
||||||
|
|
||||||
if (lfs_tagid(tag) == lfs_tagid(tempfoundtag)) {
|
if (lfs_tagid(tag) == lfs_tagid(tempfoundtag)) {
|
||||||
tempfoundtag = LFS_ERR_NOENT;
|
tempfoundtag = LFS_ERR_NOENT;
|
||||||
@@ -1230,7 +1227,7 @@ static int32_t lfs_dir_find(lfs_t *lfs,
|
|||||||
tempfoundtag -= LFS_MKTAG(0, 1, 0);
|
tempfoundtag -= LFS_MKTAG(0, 1, 0);
|
||||||
}
|
}
|
||||||
} else if ((tag & findmask) == (findtag & findmask)) {
|
} else if ((tag & findmask) == (findtag & findmask)) {
|
||||||
int res = lfs_bd_cmp(lfs, tempdir.pair[0], off+sizeof(tag),
|
int res = lfs_bd_cmp(lfs, dir->pair[0], off+sizeof(tag),
|
||||||
findbuffer, lfs_tagsize(tag));
|
findbuffer, lfs_tagsize(tag));
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return res;
|
return res;
|
||||||
@@ -1247,15 +1244,8 @@ static int32_t lfs_dir_find(lfs_t *lfs,
|
|||||||
off += sizeof(tag)+lfs_tagsize(tag);
|
off += sizeof(tag)+lfs_tagsize(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// failed, try the other crc?
|
// consider what we have good enough
|
||||||
lfs_pairswap(dir->pair);
|
if (dir->off > 0) {
|
||||||
lfs_pairswap(rev);
|
|
||||||
}
|
|
||||||
|
|
||||||
LFS_ERROR("Corrupted dir pair at %d %d", dir->pair[0], dir->pair[1]);
|
|
||||||
return LFS_ERR_CORRUPT;
|
|
||||||
|
|
||||||
done:
|
|
||||||
// synthetic move
|
// synthetic move
|
||||||
if (lfs_paircmp(dir->pair, lfs->globals.move.pair) == 0) {
|
if (lfs_paircmp(dir->pair, lfs->globals.move.pair) == 0) {
|
||||||
if (lfs->globals.move.id == lfs_tagid(foundtag)) {
|
if (lfs->globals.move.id == lfs_tagid(foundtag)) {
|
||||||
@@ -1267,6 +1257,15 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
return foundtag;
|
return foundtag;
|
||||||
|
}
|
||||||
|
|
||||||
|
// failed, try the other crc?
|
||||||
|
lfs_pairswap(dir->pair);
|
||||||
|
lfs_pairswap(rev);
|
||||||
|
}
|
||||||
|
|
||||||
|
LFS_ERROR("Corrupted dir pair at %d %d", dir->pair[0], dir->pair[1]);
|
||||||
|
return LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lfs_dir_fetch(lfs_t *lfs,
|
static int lfs_dir_fetch(lfs_t *lfs,
|
||||||
|
|||||||
@@ -78,11 +78,8 @@ do
|
|||||||
rm -rf blocks
|
rm -rf blocks
|
||||||
mkdir blocks
|
mkdir blocks
|
||||||
ln -s /dev/zero blocks/$(printf '%x' $i)
|
ln -s /dev/zero blocks/$(printf '%x' $i)
|
||||||
echo $i 1i
|
|
||||||
lfs_mktree
|
lfs_mktree
|
||||||
echo $i 2i
|
|
||||||
lfs_chktree
|
lfs_chktree
|
||||||
echo $i 3i
|
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "--- Block persistance ---"
|
echo "--- Block persistance ---"
|
||||||
|
|||||||
Reference in New Issue
Block a user