mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 00:38:29 +01:00
WIP Revisited caching rules to optimize size of reads
This commit is contained in:
300
lfs.c
300
lfs.c
@@ -20,8 +20,21 @@
|
||||
|
||||
|
||||
/// Caching block device operations ///
|
||||
static int lfs_cache_read(lfs_t *lfs,
|
||||
const lfs_cache_t *pcache, lfs_cache_t *rcache, bool store,
|
||||
static inline void lfs_cache_drop(lfs_t *lfs, lfs_cache_t *rcache) {
|
||||
// do not zero, cheaper if cache is readonly or only going to be
|
||||
// written with identical data (during relocates)
|
||||
(void)lfs;
|
||||
rcache->block = 0xffffffff;
|
||||
}
|
||||
|
||||
static inline void lfs_cache_zero(lfs_t *lfs, lfs_cache_t *pcache) {
|
||||
// zero to avoid information leak
|
||||
memset(pcache->buffer, 0xff, lfs->cfg->prog_size);
|
||||
pcache->block = 0xffffffff;
|
||||
}
|
||||
|
||||
static int lfs_bd_read(lfs_t *lfs,
|
||||
const lfs_cache_t *pcache, lfs_cache_t *rcache, lfs_size_t hint,
|
||||
lfs_block_t block, lfs_off_t off,
|
||||
void *buffer, lfs_size_t size) {
|
||||
uint8_t *data = buffer;
|
||||
@@ -57,7 +70,7 @@ static int lfs_cache_read(lfs_t *lfs,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!store && off % lfs->cfg->read_size == 0 &&
|
||||
if (size >= hint && off % lfs->cfg->read_size == 0 &&
|
||||
size >= lfs->cfg->read_size) {
|
||||
// bypass cache?
|
||||
lfs_size_t diff = size - (size % lfs->cfg->read_size);
|
||||
@@ -74,12 +87,13 @@ static int lfs_cache_read(lfs_t *lfs,
|
||||
|
||||
// load to cache, first condition can no longer fail
|
||||
LFS_ASSERT(block < lfs->cfg->block_count);
|
||||
lfs_size_t nsize = store ? lfs->cfg->cache_size : lfs->cfg->prog_size;
|
||||
rcache->block = block;
|
||||
rcache->off = lfs_aligndown(off, nsize);
|
||||
rcache->size = nsize;
|
||||
rcache->off = lfs_aligndown(off, lfs->cfg->prog_size);
|
||||
rcache->size = lfs_min(lfs_min(
|
||||
lfs_alignup(off+hint, lfs->cfg->prog_size),
|
||||
lfs->cfg->block_size) - rcache->off, lfs->cfg->cache_size);
|
||||
int err = lfs->cfg->read(lfs->cfg, rcache->block,
|
||||
rcache->off, rcache->buffer, nsize);
|
||||
rcache->off, rcache->buffer, rcache->size);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -88,21 +102,22 @@ static int lfs_cache_read(lfs_t *lfs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lfs_cache_cmp(lfs_t *lfs,
|
||||
const lfs_cache_t *pcache, lfs_cache_t *rcache,
|
||||
static int lfs_bd_cmp(lfs_t *lfs,
|
||||
const lfs_cache_t *pcache, lfs_cache_t *rcache, lfs_size_t hint,
|
||||
lfs_block_t block, lfs_off_t off,
|
||||
const void *buffer, lfs_size_t size) {
|
||||
const uint8_t *data = buffer;
|
||||
|
||||
for (lfs_off_t i = 0; i < size; i++) {
|
||||
uint8_t c;
|
||||
int err = lfs_cache_read(lfs, pcache, rcache, true,
|
||||
block, off+i, &c, 1);
|
||||
uint8_t dat;
|
||||
int err = lfs_bd_read(lfs,
|
||||
pcache, rcache, hint-i,
|
||||
block, off+i, &dat, 1);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (c != data[i]) {
|
||||
if (dat != data[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -110,37 +125,7 @@ static int lfs_cache_cmp(lfs_t *lfs,
|
||||
return true;
|
||||
}
|
||||
|
||||
static int lfs_cache_crc(lfs_t *lfs,
|
||||
const lfs_cache_t *pcache, lfs_cache_t *rcache,
|
||||
lfs_block_t block, lfs_off_t off, lfs_size_t size, uint32_t *crc) {
|
||||
for (lfs_off_t i = 0; i < size; i++) {
|
||||
uint8_t c;
|
||||
int err = lfs_cache_read(lfs, pcache, rcache, true,
|
||||
block, off+i, &c, 1);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
*crc = lfs_crc32(*crc, &c, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void lfs_cache_drop(lfs_t *lfs, lfs_cache_t *rcache) {
|
||||
// do not zero, cheaper if cache is readonly or only going to be
|
||||
// written with identical data (during relocates)
|
||||
(void)lfs;
|
||||
rcache->block = 0xffffffff;
|
||||
}
|
||||
|
||||
static inline void lfs_cache_zero(lfs_t *lfs, lfs_cache_t *pcache) {
|
||||
// zero to avoid information leak
|
||||
memset(pcache->buffer, 0xff, lfs->cfg->prog_size);
|
||||
pcache->block = 0xffffffff;
|
||||
}
|
||||
|
||||
static int lfs_cache_flush(lfs_t *lfs,
|
||||
static int lfs_bd_flush(lfs_t *lfs,
|
||||
lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) {
|
||||
if (pcache->block != 0xffffffff && pcache->block != 0xfffffffe) {
|
||||
LFS_ASSERT(pcache->block < lfs->cfg->block_count);
|
||||
@@ -154,8 +139,9 @@ static int lfs_cache_flush(lfs_t *lfs,
|
||||
if (validate) {
|
||||
// check data on disk
|
||||
lfs_cache_drop(lfs, rcache);
|
||||
int res = lfs_cache_cmp(lfs, NULL, rcache, pcache->block,
|
||||
pcache->off, pcache->buffer, diff);
|
||||
int res = lfs_bd_cmp(lfs,
|
||||
NULL, rcache, diff,
|
||||
pcache->block, pcache->off, pcache->buffer, diff);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
@@ -171,7 +157,19 @@ static int lfs_cache_flush(lfs_t *lfs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lfs_cache_prog(lfs_t *lfs,
|
||||
static int lfs_bd_sync(lfs_t *lfs,
|
||||
lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) {
|
||||
lfs_cache_drop(lfs, rcache);
|
||||
|
||||
int err = lfs_bd_flush(lfs, pcache, rcache, validate);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return lfs->cfg->sync(lfs->cfg);
|
||||
}
|
||||
|
||||
static int lfs_bd_prog(lfs_t *lfs,
|
||||
lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate,
|
||||
lfs_block_t block, lfs_off_t off,
|
||||
const void *buffer, lfs_size_t size) {
|
||||
@@ -195,7 +193,7 @@ static int lfs_cache_prog(lfs_t *lfs,
|
||||
pcache->size = off - pcache->off;
|
||||
if (pcache->size == lfs->cfg->cache_size) {
|
||||
// eagerly flush out pcache if we fill up
|
||||
int err = lfs_cache_flush(lfs, pcache, rcache, validate);
|
||||
int err = lfs_bd_flush(lfs, pcache, rcache, validate);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -217,46 +215,11 @@ static int lfs_cache_prog(lfs_t *lfs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// General lfs block device operations ///
|
||||
static int lfs_bd_read(lfs_t *lfs, lfs_block_t block,
|
||||
lfs_off_t off, void *buffer, lfs_size_t size) {
|
||||
return lfs_cache_read(lfs, &lfs->pcache, &lfs->rcache, true,
|
||||
block, off, buffer, size);
|
||||
}
|
||||
|
||||
static int lfs_bd_prog(lfs_t *lfs, lfs_block_t block,
|
||||
lfs_off_t off, const void *buffer, lfs_size_t size) {
|
||||
return lfs_cache_prog(lfs, &lfs->pcache, &lfs->rcache, false,
|
||||
block, off, buffer, size);
|
||||
}
|
||||
|
||||
static int lfs_bd_cmp(lfs_t *lfs, lfs_block_t block,
|
||||
lfs_off_t off, const void *buffer, lfs_size_t size) {
|
||||
return lfs_cache_cmp(lfs, NULL, &lfs->rcache, block, off, buffer, size);
|
||||
}
|
||||
|
||||
static int lfs_bd_crc32(lfs_t *lfs, lfs_block_t block,
|
||||
lfs_off_t off, lfs_size_t size, uint32_t *crc) {
|
||||
return lfs_cache_crc(lfs, NULL, &lfs->rcache, block, off, size, crc);
|
||||
}
|
||||
|
||||
static int lfs_bd_erase(lfs_t *lfs, lfs_block_t block) {
|
||||
LFS_ASSERT(block < lfs->cfg->block_count);
|
||||
return lfs->cfg->erase(lfs->cfg, block);
|
||||
}
|
||||
|
||||
static int lfs_bd_sync(lfs_t *lfs) {
|
||||
lfs_cache_drop(lfs, &lfs->rcache);
|
||||
|
||||
int err = lfs_cache_flush(lfs, &lfs->pcache, &lfs->rcache, false);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return lfs->cfg->sync(lfs->cfg);
|
||||
}
|
||||
|
||||
|
||||
/// Internal operations predeclared here ///
|
||||
static int lfs_fs_pred(lfs_t *lfs, const lfs_block_t dir[2],
|
||||
@@ -513,8 +476,9 @@ static int32_t lfs_commit_get(lfs_t *lfs, lfs_block_t block, lfs_off_t off,
|
||||
if (buffer) {
|
||||
lfs_size_t diff = lfs_min(
|
||||
lfs_tag_size(gettag), lfs_tag_size(tag));
|
||||
int err = lfs_bd_read(lfs, block,
|
||||
off+sizeof(tag), buffer, diff);
|
||||
int err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache, diff,
|
||||
block, off+sizeof(tag), buffer, diff);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -527,7 +491,9 @@ static int32_t lfs_commit_get(lfs_t *lfs, lfs_block_t block, lfs_off_t off,
|
||||
}
|
||||
|
||||
uint32_t ntag;
|
||||
int err = lfs_bd_read(lfs, block, off, &ntag, sizeof(ntag));
|
||||
int err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache, sizeof(ntag),
|
||||
block, off, &ntag, sizeof(ntag));
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -567,8 +533,9 @@ static int lfs_commit_attr(lfs_t *lfs, struct lfs_commit *commit,
|
||||
// write out tag
|
||||
uint32_t ntag = lfs_tole32((tag & 0x7fffffff) ^ commit->ptag);
|
||||
commit->crc = lfs_crc32(commit->crc, &ntag, sizeof(ntag));
|
||||
int err = lfs_bd_prog(lfs, commit->block, commit->off,
|
||||
&ntag, sizeof(ntag));
|
||||
int err = lfs_bd_prog(lfs,
|
||||
&lfs->pcache, &lfs->rcache, false,
|
||||
commit->block, commit->off, &ntag, sizeof(ntag));
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -577,7 +544,9 @@ static int lfs_commit_attr(lfs_t *lfs, struct lfs_commit *commit,
|
||||
if (!(tag & 0x80000000)) {
|
||||
// from memory
|
||||
commit->crc = lfs_crc32(commit->crc, buffer, size);
|
||||
err = lfs_bd_prog(lfs, commit->block, commit->off, buffer, size);
|
||||
err = lfs_bd_prog(lfs,
|
||||
&lfs->pcache, &lfs->rcache, false,
|
||||
commit->block, commit->off, buffer, size);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -587,13 +556,17 @@ static int lfs_commit_attr(lfs_t *lfs, struct lfs_commit *commit,
|
||||
for (lfs_off_t i = 0; i < size; i++) {
|
||||
// rely on caching to make this efficient
|
||||
uint8_t dat;
|
||||
err = lfs_bd_read(lfs, disk->block, disk->off+i, &dat, 1);
|
||||
err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache, size-i,
|
||||
disk->block, disk->off+i, &dat, 1);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
commit->crc = lfs_crc32(commit->crc, &dat, 1);
|
||||
err = lfs_bd_prog(lfs, commit->block, commit->off+i, &dat, 1);
|
||||
err = lfs_bd_prog(lfs,
|
||||
&lfs->pcache, &lfs->rcache, false,
|
||||
commit->block, commit->off+i, &dat, 1);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -641,7 +614,9 @@ static int lfs_commit_move(lfs_t *lfs, struct lfs_commit *commit,
|
||||
disk.block = dir->pair[0];
|
||||
disk.off = off + sizeof(tag);
|
||||
|
||||
int err = lfs_bd_read(lfs, dir->pair[0], off, &ntag, sizeof(ntag));
|
||||
int err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache, sizeof(ntag),
|
||||
dir->pair[0], off, &ntag, sizeof(ntag));
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -701,10 +676,14 @@ static int lfs_commit_crc(lfs_t *lfs, struct lfs_commit *commit) {
|
||||
lfs->cfg->prog_size);
|
||||
|
||||
// read erased state from next program unit
|
||||
uint32_t tag;
|
||||
int err = lfs_bd_read(lfs, commit->block, off, &tag, sizeof(tag));
|
||||
if (err) {
|
||||
return err;
|
||||
uint32_t tag = 0;
|
||||
if (off < lfs->cfg->block_size) {
|
||||
int err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache, lfs->cfg->block_size,
|
||||
commit->block, off, &tag, sizeof(tag));
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// build crc tag
|
||||
@@ -718,7 +697,9 @@ static int lfs_commit_crc(lfs_t *lfs, struct lfs_commit *commit) {
|
||||
footer[0] = lfs_tole32(tag ^ commit->ptag);
|
||||
commit->crc = lfs_crc32(commit->crc, &footer[0], sizeof(footer[0]));
|
||||
footer[1] = lfs_tole32(commit->crc);
|
||||
err = lfs_bd_prog(lfs, commit->block, commit->off, footer, sizeof(footer));
|
||||
int err = lfs_bd_prog(lfs,
|
||||
&lfs->pcache, &lfs->rcache, false,
|
||||
commit->block, commit->off, &footer, sizeof(footer));
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -726,15 +707,27 @@ static int lfs_commit_crc(lfs_t *lfs, struct lfs_commit *commit) {
|
||||
commit->ptag = tag;
|
||||
|
||||
// flush buffers
|
||||
err = lfs_bd_sync(lfs);
|
||||
err = lfs_bd_sync(lfs, &lfs->pcache, &lfs->rcache, false);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// successful commit, check checksum to make sure
|
||||
uint32_t crc = 0xffffffff;
|
||||
err = lfs_bd_crc32(lfs, commit->block, commit->begin,
|
||||
commit->off-lfs_tag_size(tag)-commit->begin, &crc);
|
||||
lfs_size_t size = commit->off - lfs_tag_size(tag) - commit->begin;
|
||||
for (lfs_off_t i = 0; i < size; i++) {
|
||||
// leave it up to caching to make this efficient
|
||||
uint8_t dat;
|
||||
err = lfs_bd_read(lfs,
|
||||
NULL, &lfs->rcache, size-i,
|
||||
commit->block, commit->begin+i, &dat, 1);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
crc = lfs_crc32(crc, &dat, 1);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -758,7 +751,13 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) {
|
||||
|
||||
// rather than clobbering one of the blocks we just pretend
|
||||
// the revision may be valid
|
||||
int err = lfs_bd_read(lfs, dir->pair[0], 0, &dir->rev, 4);
|
||||
int err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache, sizeof(dir->rev),
|
||||
dir->pair[0], 0, &dir->rev, sizeof(dir->rev));
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
dir->rev = lfs_fromle32(dir->rev);
|
||||
if (err && err != LFS_ERR_CORRUPT) {
|
||||
return err;
|
||||
@@ -788,7 +787,8 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs,
|
||||
// find the block with the most recent revision
|
||||
uint32_t rev[2];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int err = lfs_cache_read(lfs, &lfs->pcache, &lfs->rcache, false,
|
||||
int err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache, sizeof(rev[i]),
|
||||
dir->pair[i], 0, &rev[i], sizeof(rev[i]));
|
||||
rev[i] = lfs_fromle32(rev[i]);
|
||||
if (err && err != LFS_ERR_CORRUPT) {
|
||||
@@ -824,10 +824,17 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs,
|
||||
lfs_global_zero(&templocals);
|
||||
|
||||
while (true) {
|
||||
// reached end of block
|
||||
if (off+sizeof(uint32_t) >= lfs->cfg->block_size) {
|
||||
dir->erased = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// extract next tag
|
||||
uint32_t tag;
|
||||
int err = lfs_bd_read(lfs, dir->pair[0],
|
||||
off, &tag, sizeof(tag));
|
||||
int err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache, lfs->cfg->block_size,
|
||||
dir->pair[0], off, &tag, sizeof(tag));
|
||||
if (err) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
// can't continue?
|
||||
@@ -855,8 +862,9 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs,
|
||||
if (lfs_tag_type(tag) == LFS_TYPE_CRC) {
|
||||
// check the crc attr
|
||||
uint32_t dcrc;
|
||||
err = lfs_bd_read(lfs, dir->pair[0],
|
||||
off+sizeof(tag), &dcrc, sizeof(dcrc));
|
||||
err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache, lfs->cfg->block_size,
|
||||
dir->pair[0], off+sizeof(tag), &dcrc, sizeof(dcrc));
|
||||
if (err) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
dir->erased = false;
|
||||
@@ -883,23 +891,35 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs,
|
||||
lfs->seed ^= crc;
|
||||
crc = 0xffffffff;
|
||||
} else {
|
||||
err = lfs_bd_crc32(lfs, dir->pair[0],
|
||||
off+sizeof(tag), lfs_tag_size(tag), &crc);
|
||||
if (err) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
dir->erased = false;
|
||||
break;
|
||||
// crc the entry first, leaving it in the cache
|
||||
for (lfs_off_t j = 0; j < lfs_tag_size(tag); j++) {
|
||||
uint8_t dat;
|
||||
err = lfs_bd_read(lfs,
|
||||
NULL, &lfs->rcache, lfs->cfg->block_size,
|
||||
dir->pair[0], off+sizeof(tag)+j, &dat, 1);
|
||||
if (err) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
dir->erased = false;
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
crc = lfs_crc32(crc, &dat, 1);
|
||||
}
|
||||
|
||||
// keep track of id count
|
||||
if (lfs_tag_id(tag) < 0x3ff && lfs_tag_id(tag) >= tempcount) {
|
||||
tempcount = lfs_tag_id(tag)+1;
|
||||
}
|
||||
|
||||
// check for special tags
|
||||
if (lfs_tag_subtype(tag) == LFS_TYPE_TAIL) {
|
||||
tempsplit = (lfs_tag_type(tag) & 1);
|
||||
err = lfs_bd_read(lfs, dir->pair[0], off+sizeof(tag),
|
||||
temptail, sizeof(temptail));
|
||||
err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache, lfs->cfg->block_size,
|
||||
dir->pair[0], off+sizeof(tag),
|
||||
&temptail, sizeof(temptail));
|
||||
if (err) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
dir->erased = false;
|
||||
@@ -909,7 +929,9 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs,
|
||||
lfs_pair_fromle32(temptail);
|
||||
} else if (lfs_tag_subtype(tag) == LFS_TYPE_GLOBALS) {
|
||||
templocals.l.deorphaned = (lfs_tag_type(tag) & 1);
|
||||
err = lfs_bd_read(lfs, dir->pair[0], off+sizeof(tag),
|
||||
err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache, lfs->cfg->block_size,
|
||||
dir->pair[0], off+sizeof(tag),
|
||||
&templocals, 10);
|
||||
if (err) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
@@ -931,8 +953,11 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs,
|
||||
// found a match?
|
||||
if (lfs_tag_type(findtag) == LFS_TYPE_DIRSTRUCT) {
|
||||
lfs_block_t child[2];
|
||||
err = lfs_bd_read(lfs, dir->pair[0], off+sizeof(tag),
|
||||
child, sizeof(child));
|
||||
err = lfs_bd_read(lfs,
|
||||
&lfs->pcache, &lfs->rcache,
|
||||
lfs->cfg->block_size,
|
||||
dir->pair[0], off+sizeof(tag),
|
||||
&child, sizeof(child));
|
||||
if (err < 0) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
dir->erased = false;
|
||||
@@ -948,6 +973,7 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs,
|
||||
}
|
||||
} else if (lfs_tag_type(findtag) == LFS_TYPE_NAME) {
|
||||
int res = lfs_bd_cmp(lfs,
|
||||
NULL, &lfs->rcache, lfs_tag_size(findtag),
|
||||
dir->pair[0], off+sizeof(tag),
|
||||
findbuffer, lfs_tag_size(findtag));
|
||||
if (res < 0) {
|
||||
@@ -1091,7 +1117,9 @@ static int lfs_dir_compact(lfs_t *lfs,
|
||||
uint32_t crc = 0xffffffff;
|
||||
uint32_t rev = lfs_tole32(dir->rev);
|
||||
crc = lfs_crc32(crc, &rev, sizeof(rev));
|
||||
err = lfs_bd_prog(lfs, dir->pair[1], 0, &rev, sizeof(rev));
|
||||
err = lfs_bd_prog(lfs,
|
||||
&lfs->pcache, &lfs->rcache, false,
|
||||
dir->pair[1], 0, &rev, sizeof(rev));
|
||||
if (err) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
goto relocate;
|
||||
@@ -1788,8 +1816,9 @@ static int lfs_ctz_find(lfs_t *lfs,
|
||||
lfs_npw2(current-target+1) - 1,
|
||||
lfs_ctz(current));
|
||||
|
||||
int err = lfs_cache_read(lfs, pcache, rcache, false,
|
||||
head, 4*skip, &head, 4);
|
||||
int err = lfs_bd_read(lfs,
|
||||
pcache, rcache, sizeof(head),
|
||||
head, 4*skip, &head, sizeof(head));
|
||||
head = lfs_fromle32(head);
|
||||
if (err) {
|
||||
return err;
|
||||
@@ -1839,13 +1868,15 @@ static int lfs_ctz_extend(lfs_t *lfs,
|
||||
if (size != lfs->cfg->block_size) {
|
||||
for (lfs_off_t i = 0; i < size; i++) {
|
||||
uint8_t data;
|
||||
err = lfs_cache_read(lfs, NULL, rcache, true,
|
||||
err = lfs_bd_read(lfs,
|
||||
NULL, rcache, size-i,
|
||||
head, i, &data, 1);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = lfs_cache_prog(lfs, pcache, rcache, true,
|
||||
err = lfs_bd_prog(lfs,
|
||||
pcache, rcache, true,
|
||||
nblock, i, &data, 1);
|
||||
if (err) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
@@ -1866,7 +1897,7 @@ static int lfs_ctz_extend(lfs_t *lfs,
|
||||
|
||||
for (lfs_off_t i = 0; i < skips; i++) {
|
||||
head = lfs_tole32(head);
|
||||
err = lfs_cache_prog(lfs, pcache, rcache, true,
|
||||
err = lfs_bd_prog(lfs, pcache, rcache, true,
|
||||
nblock, 4*i, &head, 4);
|
||||
head = lfs_fromle32(head);
|
||||
if (err) {
|
||||
@@ -1877,8 +1908,9 @@ static int lfs_ctz_extend(lfs_t *lfs,
|
||||
}
|
||||
|
||||
if (i != skips-1) {
|
||||
err = lfs_cache_read(lfs, NULL, rcache, false,
|
||||
head, 4*i, &head, 4);
|
||||
err = lfs_bd_read(lfs,
|
||||
NULL, rcache, sizeof(head),
|
||||
head, 4*i, &head, sizeof(head));
|
||||
head = lfs_fromle32(head);
|
||||
if (err) {
|
||||
return err;
|
||||
@@ -1922,8 +1954,9 @@ static int lfs_ctz_traverse(lfs_t *lfs,
|
||||
|
||||
lfs_block_t heads[2];
|
||||
int count = 2 - (index & 1);
|
||||
err = lfs_cache_read(lfs, pcache, rcache, false,
|
||||
head, 0, &heads, count*4);
|
||||
err = lfs_bd_read(lfs,
|
||||
pcache, rcache, count*sizeof(head),
|
||||
head, 0, &heads, count*sizeof(head));
|
||||
heads[0] = lfs_fromle32(heads[0]);
|
||||
heads[1] = lfs_fromle32(heads[1]);
|
||||
if (err) {
|
||||
@@ -2131,13 +2164,15 @@ static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) {
|
||||
// either read from dirty cache or disk
|
||||
for (lfs_off_t i = 0; i < file->off; i++) {
|
||||
uint8_t data;
|
||||
err = lfs_cache_read(lfs, &file->cache, &lfs->rcache, true,
|
||||
err = lfs_bd_read(lfs,
|
||||
&file->cache, &lfs->rcache, file->off-i,
|
||||
file->block, i, &data, 1);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = lfs_cache_prog(lfs, &lfs->pcache, &lfs->rcache, true,
|
||||
err = lfs_bd_prog(lfs,
|
||||
&lfs->pcache, &lfs->rcache, true,
|
||||
nblock, i, &data, 1);
|
||||
if (err) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
@@ -2207,7 +2242,7 @@ static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
|
||||
|
||||
// write out what we have
|
||||
while (true) {
|
||||
int err = lfs_cache_flush(lfs,
|
||||
int err = lfs_bd_flush(lfs,
|
||||
&file->cache, &lfs->rcache, true);
|
||||
if (err) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
@@ -2350,7 +2385,8 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
||||
|
||||
// read as much as we can in current block
|
||||
lfs_size_t diff = lfs_min(nsize, lfs->cfg->block_size - file->off);
|
||||
int err = lfs_cache_read(lfs, NULL, &file->cache, true,
|
||||
int err = lfs_bd_read(lfs,
|
||||
NULL, &file->cache, lfs->cfg->block_size,
|
||||
file->block, file->off, data, diff);
|
||||
if (err) {
|
||||
return err;
|
||||
@@ -2455,7 +2491,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
|
||||
// program as much as we can in current block
|
||||
lfs_size_t diff = lfs_min(nsize, lfs->cfg->block_size - file->off);
|
||||
while (true) {
|
||||
int err = lfs_cache_prog(lfs, &file->cache, &lfs->rcache, true,
|
||||
int err = lfs_bd_prog(lfs, &file->cache, &lfs->rcache, true,
|
||||
file->block, file->off, data, diff);
|
||||
if (err) {
|
||||
if (err == LFS_ERR_CORRUPT) {
|
||||
|
||||
Reference in New Issue
Block a user