@@ -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