@@ -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 );
260262LFS_ASSERT (err <=0 );
261263if (err ) {
262264return err ;
@@ -267,7 +269,7 @@ static int lfs_bd_flush(lfs_t *lfs,
267269lfs_cache_drop (lfs ,rcache );
268270int res = lfs_bd_cmp (lfs ,
269271NULL ,rcache ,diff ,
270- pcache -> block ,pcache -> off ,pcache -> buffer ,diff );
272+ block ,off ,buffer ,diff );
271273if (res < 0 ) {
272274return 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
283284return 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
339354LFS_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
342374pcache -> block = block ;
343375pcache -> off = lfs_aligndown (off ,lfs -> cfg -> prog_size );