Introduced cache_size as alternative to hardware read/write sizes

The introduction of an explicit cache_size configuration allows
customization of the cache buffers independently from the hardware
read/write sizes.

This has been one of littlefs's main handicaps. Without a distinction
between cache units and hardware limitations, littlefs isn't able to
read or program _less_ than the cache size. This leads to the
counter-intuitive case where larger cache sizes can actually be harmful,
since larger read/prog sizes require sending more data over the bus if
we're only accessing a small set of data (for example the CTZ skip-list
traversal).

This is compounded with metadata logging, since a large program size
limits the number of commits we can write out in a single metadata
block. It really doesn't make sense to link program size + cache
size here.

With a separate cache_size configuration, we can be much smarter about
what we actually read/write from disk.

This also simplifies cache handling a bit. Before there were two
possible cache sizes, but these were rarely used. Note that the
cache_size is NOT written to the superblock and can be freely changed
without breaking backwards compatibility.
This commit is contained in:
Christopher Haster
2018-08-04 14:48:27 -05:00
parent 97f35c3e05
commit 3cfa08602a
5 changed files with 108 additions and 108 deletions

20
lfs.h
View File

@@ -177,21 +177,24 @@ struct lfs_config {
// are propogated to the user.
int (*sync)(const struct lfs_config *c);
// Minimum size of a block read. This determines the size of read buffers.
// This may be larger than the physical read size to improve performance
// by caching more of the block device.
// Minimum size of a block read. All read operations will be a
// multiple of this value.
lfs_size_t read_size;
// Minimum size of a block program. This determines the size of program
// buffers. This may be larger than the physical program size to improve
// performance by caching more of the block device.
// Must be a multiple of the read size.
// Minimum size of a block program. All program operations will be a
// multiple of this value.
lfs_size_t prog_size;
// Size of block caches. Each cache buffers a portion of a block in RAM.
// This determines the size of the read cache, the program cache, and a
// cache per file. Larger caches can improve performance by storing more
// data. Must be a multiple of the read and program sizes.
lfs_size_t cache_size;
// Size of an erasable block. This does not impact ram consumption and
// may be larger than the physical erase size. However, this should be
// kept small as each file currently takes up an entire block.
// Must be a multiple of the program size.
// Must be a multiple of the read, program, and cache sizes.
lfs_size_t block_size;
// Number of erasable blocks on the device.
@@ -283,6 +286,7 @@ typedef struct lfs_mattr {
typedef struct lfs_cache {
lfs_block_t block;
lfs_off_t off;
lfs_size_t size;
uint8_t *buffer;
} lfs_cache_t;