Skip to content

Commit 9270114

Browse files
do direct write if file data doesn't fit in cache
1 parent 30da07f commit 9270114

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

lfs.c

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,15 @@ static int lfs_bd_crc(lfs_t *lfs,
250250
}
251251

252252
#ifndef LFS_READONLY
253-
static int lfs_bd_flush(lfs_t *lfs,
254-
lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) {
255-
if (pcache->block != LFS_BLOCK_NULL && pcache->block != LFS_BLOCK_INLINE) {
256-
LFS_ASSERT(pcache->block < lfs->block_count);
257-
lfs_size_t diff = lfs_alignup(pcache->size, lfs->cfg->prog_size);
258-
int err = lfs->cfg->prog(lfs->cfg, pcache->block,
259-
pcache->off, pcache->buffer, diff);
253+
static int lfs_bd_flush_direct(lfs_t *lfs,
254+
lfs_cache_t *rcache, lfs_block_t block,
255+
lfs_off_t off, const void *buffer, lfs_size_t diff, bool validate) {
256+
if (block != LFS_BLOCK_NULL && block != LFS_BLOCK_INLINE) {
257+
LFS_ASSERT(block < lfs->block_count);
258+
LFS_ASSERT(diff % lfs->cfg->prog_size == 0);
259+
LFS_ASSERT(off % lfs->cfg->prog_size == 0);
260+
int err = lfs->cfg->prog(lfs->cfg, block,
261+
off, buffer, diff);
260262
LFS_ASSERT(err <= 0);
261263
if (err) {
262264
return err;
@@ -267,7 +269,7 @@ static int lfs_bd_flush(lfs_t *lfs,
267269
lfs_cache_drop(lfs, rcache);
268270
int res = lfs_bd_cmp(lfs,
269271
NULL, rcache, diff,
270-
pcache->block, pcache->off, pcache->buffer, diff);
272+
block, off, buffer, diff);
271273
if (res < 0) {
272274
return res;
273275
}
@@ -277,11 +279,24 @@ static int lfs_bd_flush(lfs_t *lfs,
277279
}
278280
}
279281

280-
lfs_cache_zero(lfs, pcache);
281282
}
282283

283284
return 0;
284285
}
286+
287+
static int lfs_bd_flush(lfs_t *lfs,
288+
lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) {
289+
int ret = 0;
290+
if (pcache->block != LFS_BLOCK_NULL && pcache->block != LFS_BLOCK_INLINE) {
291+
lfs_size_t diff = lfs_alignup(pcache->size, lfs->cfg->prog_size);
292+
ret = lfs_bd_flush_direct(lfs, rcache, pcache->block, pcache->off,
293+
pcache->buffer, diff, validate);
294+
if (ret == 0)
295+
lfs_cache_zero(lfs, pcache);
296+
}
297+
return ret;
298+
}
299+
285300
#endif
286301

287302
#ifndef LFS_READONLY
@@ -338,6 +353,23 @@ static int lfs_bd_prog(lfs_t *lfs,
338353
// entire block or manually flushing the pcache
339354
LFS_ASSERT(pcache->block == LFS_BLOCK_NULL);
340355

356+
if (size >= lfs->cfg->cache_size) {
357+
// data do not fit in cache, direct write
358+
// XXX align on cache_size : the file flush logic between
359+
// block is triggered by "pcache->size == lfs->cfg->cache_size"
360+
// could be prog_size in theory
361+
lfs_size_t diff = lfs_aligndown(size, lfs->cfg->cache_size);
362+
int err = lfs_bd_flush_direct(lfs, rcache, block, off,
363+
data, diff, validate);
364+
if (err) {
365+
return err;
366+
}
367+
data += diff;
368+
off += diff;
369+
size -= diff;
370+
continue;
371+
}
372+
341373
// prepare pcache, first condition can no longer fail
342374
pcache->block = block;
343375
pcache->off = lfs_aligndown(off, lfs->cfg->prog_size);

0 commit comments

Comments
 (0)