diff --git a/lfs.c b/lfs.c index 3664e801..dafe0805 100644 --- a/lfs.c +++ b/lfs.c @@ -622,6 +622,26 @@ static void lfs_alloc_drop(lfs_t *lfs) { lfs_alloc_ack(lfs); } +#ifndef LFS_READONLY +static int lfs_fs_rawfindfreeblocks(lfs_t *lfs) { + // Move free offset at the first unused block (lfs->free.i) + // lfs->free.i is equal lfs->free.size when all blocks are used + lfs->free.off = (lfs->free.off + lfs->free.i) % lfs->block_count; + lfs->free.size = lfs_min(8*lfs->cfg->lookahead_size, lfs->free.ack); + lfs->free.i = 0; + + // find mask of free blocks from tree + memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size); + int err = lfs_fs_rawtraverse(lfs, lfs_alloc_lookahead, lfs, true); + if (err) { + lfs_alloc_drop(lfs); + return err; + } + + return 0; +} +#endif + #ifndef LFS_READONLY static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { while (true) { @@ -654,29 +674,12 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { return LFS_ERR_NOSPC; } - int err = lfs_find_free_blocks(lfs); + int err = lfs_fs_rawfindfreeblocks(lfs); if(err) { return err; } } } - -int lfs_find_free_blocks(lfs_t *lfs){ - // Move free offset at the first unused block (lfs->free.i) - // lfs->free.i is equal lfs->free.size when all blocks are used - lfs->free.off = (lfs->free.off + lfs->free.i) - % lfs->block_count; - lfs->free.size = lfs_min(8*lfs->cfg->lookahead_size, lfs->free.ack); - lfs->free.i = 0; - - // find mask of free blocks from tree - memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size); - int const err = lfs_fs_rawtraverse(lfs, lfs_alloc_lookahead, lfs, true); - if (err) { - lfs_alloc_drop(lfs); - } - return err; -} #endif /// Metadata pair and directory operations /// @@ -6247,6 +6250,22 @@ int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void *, lfs_block_t), void *data) { return err; } +#ifndef LFS_READONLY +int lfs_fs_findfreeblocks(lfs_t *lfs) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_fs_findfreeblocks(%p)", (void*)lfs); + + err = lfs_fs_rawfindfreeblocks(lfs); + + LFS_TRACE("lfs_fs_findfreeblocks -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + #ifndef LFS_READONLY int lfs_fs_mkconsistent(lfs_t *lfs) { int err = LFS_LOCK(lfs->cfg); diff --git a/lfs.h b/lfs.h index f574b317..a0dce9d8 100644 --- a/lfs.h +++ b/lfs.h @@ -712,9 +712,12 @@ lfs_ssize_t lfs_fs_size(lfs_t *lfs); // Returns a negative error code on failure. int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data); -// Use Traverse function and try to find free blocks. LittleFS free blocks search is unpredictable. -// Search is costly operation which may delay write. In realtime write scenarios can be better to find them before a write. -int lfs_find_free_blocks(lfs_t *lfs); +// Use Traverse function and try to find free blocks. LittleFS free blocks +// search is unpredictable. +// +// Search is costly operation which may delay write. In realtime write +// scenarios can be better to find them before a write. +int lfs_fs_findfreeblocks(lfs_t *lfs); #ifndef LFS_READONLY // Attempt to make the filesystem consistent and ready for writing