WIP fixed corruption tests

This commit is contained in:
Christopher Haster
2018-07-30 14:23:51 -05:00
parent 868099836d
commit c74bcec184
2 changed files with 47 additions and 51 deletions

95
lfs.c
View File

@@ -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,
void *buffer, bool stopatcommit) {
// iterate over dir block backwards (for faster lookups)
while (off > sizeof(tag)) {
LFS_ASSERT(off > sizeof(tag)+lfs_tagsize(tag));
while (off >= 2*sizeof(tag)+lfs_tagsize(tag)) {
off -= sizeof(tag)+lfs_tagsize(tag);
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);
uint32_t ptag = 0;
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]);
lfs_crc(&crc, &dir->rev, sizeof(dir->rev));
dir->rev = lfs_fromle32(dir->rev);
dir->off = 0;
lfs_mdir_t tempdir = *dir;
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) {
// extract next 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));
if (err) {
return err;
@@ -1161,67 +1159,66 @@ static int32_t lfs_dir_find(lfs_t *lfs,
// next commit not yet programmed
if (lfs_tagtype(ptag) == LFS_TYPE_CRC && !lfs_tagisvalid(tag)) {
dir->erased = true;
goto done;
break;
}
// check we're in valid range
if (off + sizeof(tag)+lfs_tagsize(tag) > lfs->cfg->block_size) {
dir->erased = false;
break;
}
if (lfs_tagtype(tag) == LFS_TYPE_CRC) {
// check the crc attr
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));
if (err) {
return err;
}
if (crc != lfs_fromle32(dcrc)) {
if (off == sizeof(tempdir.rev)) {
// try other block
break;
} else {
// consider what we have good enough
dir->erased = false;
goto done;
}
dir->erased = false;
break;
}
tempdir.off = off + sizeof(tag)+lfs_tagsize(tag);
tempdir.etag = tag;
crc = 0xffffffff;
*dir = tempdir;
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 {
err = lfs_bd_crc(lfs, tempdir.pair[0],
err = lfs_bd_crc(lfs, dir->pair[0],
off+sizeof(tag), lfs_tagsize(tag), &crc);
if (err) {
return err;
}
if (lfs_tagid(tag) < 0x3ff &&
lfs_tagid(tag) >= tempdir.count) {
tempdir.count = lfs_tagid(tag)+1;
if (lfs_tagid(tag) < 0x3ff && lfs_tagid(tag) >= tempcount) {
tempcount = lfs_tagid(tag)+1;
}
// TODO use subtype accross all of these?
if (lfs_tagsubtype(tag) == LFS_TYPE_TAIL) {
tempdir.split = (lfs_tagtype(tag) & 1);
err = lfs_bd_read(lfs, tempdir.pair[0], off+sizeof(tag),
tempdir.tail, sizeof(tempdir.tail));
tempsplit = (lfs_tagtype(tag) & 1);
err = lfs_bd_read(lfs, dir->pair[0], off+sizeof(tag),
temptail, sizeof(temptail));
if (err) {
return err;
}
} else if (lfs_tagtype(tag) == LFS_TYPE_GLOBALS) {
err = lfs_bd_read(lfs, tempdir.pair[0], off+sizeof(tag),
&tempdir.locals, sizeof(tempdir.locals));
err = lfs_bd_read(lfs, dir->pair[0], off+sizeof(tag),
&templocals, sizeof(templocals));
if (err) {
return err;
}
} else if (lfs_tagtype(tag) == LFS_TYPE_DELETE) {
LFS_ASSERT(tempdir.count > 0);
tempdir.count -= 1;
LFS_ASSERT(tempcount > 0);
tempcount -= 1;
if (lfs_tagid(tag) == lfs_tagid(tempfoundtag)) {
tempfoundtag = LFS_ERR_NOENT;
@@ -1230,7 +1227,7 @@ static int32_t lfs_dir_find(lfs_t *lfs,
tempfoundtag -= LFS_MKTAG(0, 1, 0);
}
} 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));
if (res < 0) {
return res;
@@ -1247,6 +1244,21 @@ static int32_t lfs_dir_find(lfs_t *lfs,
off += sizeof(tag)+lfs_tagsize(tag);
}
// 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)) {
foundtag = LFS_ERR_NOENT;
} else if (lfs_tagisvalid(foundtag) &&
lfs->globals.move.id < lfs_tagid(foundtag)) {
foundtag -= LFS_MKTAG(0, 1, 0);
}
}
return foundtag;
}
// failed, try the other crc?
lfs_pairswap(dir->pair);
lfs_pairswap(rev);
@@ -1254,19 +1266,6 @@ static int32_t lfs_dir_find(lfs_t *lfs,
LFS_ERROR("Corrupted dir pair at %d %d", dir->pair[0], dir->pair[1]);
return LFS_ERR_CORRUPT;
done:
// synthetic move
if (lfs_paircmp(dir->pair, lfs->globals.move.pair) == 0) {
if (lfs->globals.move.id == lfs_tagid(foundtag)) {
foundtag = LFS_ERR_NOENT;
} else if (lfs_tagisvalid(foundtag) &&
lfs->globals.move.id < lfs_tagid(foundtag)) {
foundtag -= LFS_MKTAG(0, 1, 0);
}
}
return foundtag;
}
static int lfs_dir_fetch(lfs_t *lfs,

View File

@@ -78,11 +78,8 @@ do
rm -rf blocks
mkdir blocks
ln -s /dev/zero blocks/$(printf '%x' $i)
echo $i 1i
lfs_mktree
echo $i 2i
lfs_chktree
echo $i 3i
done
echo "--- Block persistance ---"