Fixed workaround for erase sizes >1024 B

Introduced in 0b76635, the workaround for erases sizes >1024 is to
commit with an unaligned CRC tag. Upon reading an unaligned CRC,
littlefs should treat the metadata pair as "requires erased". While
necessary for portability, this also lets us workaround the lack of
handling of erases sizes >1024.

Unfortunately, this workaround wasn't implemented correctly (by me)
in the case that the metadata-pair does not immediately compact. This
is solved here by added the erase check to lfs_dir_commit.

Note this is still only a part of a workaround which should be replaced.
One potential solution is to pad the commit with multiple smaller CRC
tags until we reach the next prog_size boundary.

found by kazink
This commit is contained in:
Christopher Haster
2019-05-31 06:42:15 -05:00
parent abd90cb84c
commit 649640c605

4
lfs.c
View File

@@ -1247,7 +1247,7 @@ static int lfs_dir_commitcrc(lfs_t *lfs, struct lfs_commit *commit) {
// build crc tag // build crc tag
bool reset = ~lfs_frombe32(tag) >> 31; bool reset = ~lfs_frombe32(tag) >> 31;
tag = LFS_MKTAG(LFS_TYPE_CRC + reset, 0x3ff, tag = LFS_MKTAG(LFS_TYPE_CRC + reset, 0x3ff,
off - (commit->off+sizeof(lfs_tag_t))); lfs_min(off - (commit->off+sizeof(lfs_tag_t)), 0x3fe));
// write out crc // write out crc
uint32_t footer[2]; uint32_t footer[2];
@@ -1760,6 +1760,8 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
// successful commit, update dir // successful commit, update dir
dir->off = commit.off; dir->off = commit.off;
dir->etag = commit.ptag; dir->etag = commit.ptag;
// workaround to handle prog_size >1024
dir->erased = (dir->off % lfs->cfg->prog_size == 0);
// note we able to have already handled move here // note we able to have already handled move here
if (lfs_gstate_hasmovehere(&lfs->gpending, dir->pair)) { if (lfs_gstate_hasmovehere(&lfs->gpending, dir->pair)) {