mirror of https://github.com/ARMmbed/mbed-os.git
Fixed issue with aggressively rounding down lookahead configuration
The littlefs allows buffers to be passed statically in the case that a system does not have a heap. Unfortunately, this means we can't round up in the case of an unaligned lookahead buffer. Double unfortunately, rounding down after clamping to the block device size could result in a lookahead of zero for block devices < 32 blocks large. The assert in littlefs does catch this case, but rounding down prevents support for < 32 block devices. The solution is to simply require a 32-bit aligned buffer with an assert. This avoids runtime problems while allowing a user to pass in the correct buffer for < 32 block devices. Rounding up can be handled at higher API levels.pull/5538/head
parent
71b429ba66
commit
785b0b4bc4
|
@ -23,7 +23,7 @@ script:
|
|||
make -Clittlefs test
|
||||
- CFLAGS="-Wno-error=format -DLFS_BLOCK_COUNT=1023"
|
||||
make -Clittlefs test
|
||||
- CFLAGS="-Wno-error=format -DLFS_LOOKAHEAD=2047"
|
||||
- CFLAGS="-Wno-error=format -DLFS_LOOKAHEAD=2048"
|
||||
make -Clittlefs test
|
||||
|
||||
# Self-host with littlefs-fuse for fuzz test
|
||||
|
|
|
@ -156,7 +156,7 @@ int LittleFileSystem::mount(BlockDevice *bd) {
|
|||
_config.block_size = _block_size;
|
||||
}
|
||||
_config.block_count = bd->size() / _config.block_size;
|
||||
_config.lookahead = _config.block_count - _config.block_count % 32;
|
||||
_config.lookahead = 32 * ((_config.block_count+31)/32);
|
||||
if (_config.lookahead > _lookahead) {
|
||||
_config.lookahead = _lookahead;
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ int LittleFileSystem::format(BlockDevice *bd,
|
|||
_config.block_size = block_size;
|
||||
}
|
||||
_config.block_count = bd->size() / _config.block_size;
|
||||
_config.lookahead = _config.block_count - _config.block_count % 32;
|
||||
_config.lookahead = 32 * ((_config.block_count+31)/32);
|
||||
if (_config.lookahead > lookahead) {
|
||||
_config.lookahead = lookahead;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ script:
|
|||
- CFLAGS="-DLFS_READ_SIZE=1 -DLFS_PROG_SIZE=1" make test
|
||||
- CFLAGS="-DLFS_READ_SIZE=512 -DLFS_PROG_SIZE=512" make test
|
||||
- CFLAGS="-DLFS_BLOCK_COUNT=1023" make test
|
||||
- CFLAGS="-DLFS_LOOKAHEAD=2047" make test
|
||||
- CFLAGS="-DLFS_LOOKAHEAD=2048" make test
|
||||
|
||||
# self-host with littlefs-fuse for fuzz test
|
||||
- make -C littlefs-fuse
|
||||
|
|
|
@ -278,7 +278,7 @@ static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
|
|||
% (lfs_soff_t)(lfs->cfg->block_count))
|
||||
+ lfs->cfg->block_count) % lfs->cfg->block_count;
|
||||
|
||||
if (off < lfs->free.lookahead) {
|
||||
if (off < lfs->cfg->lookahead) {
|
||||
lfs->free.buffer[off / 32] |= 1U << (off % 32);
|
||||
}
|
||||
|
||||
|
@ -294,7 +294,8 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
|||
return LFS_ERR_NOSPC;
|
||||
}
|
||||
|
||||
if (lfs->free.off >= lfs->free.lookahead) {
|
||||
if (lfs->free.off >= lfs_min(
|
||||
lfs->cfg->lookahead, lfs->cfg->block_count)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -308,11 +309,11 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
|||
}
|
||||
}
|
||||
|
||||
lfs->free.begin += lfs->free.lookahead;
|
||||
lfs->free.begin += lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
|
||||
lfs->free.off = 0;
|
||||
|
||||
// find mask of free blocks from tree
|
||||
memset(lfs->free.buffer, 0, lfs->free.lookahead/8);
|
||||
memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8);
|
||||
int err = lfs_traverse(lfs, lfs_alloc_lookahead, lfs);
|
||||
if (err) {
|
||||
return err;
|
||||
|
@ -1870,13 +1871,12 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||
}
|
||||
|
||||
// setup lookahead, round down to nearest 32-bits
|
||||
lfs->free.lookahead = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
|
||||
lfs->free.lookahead = 32 * (lfs->free.lookahead / 32);
|
||||
assert(lfs->free.lookahead > 0);
|
||||
assert(lfs->cfg->lookahead % 32 == 0);
|
||||
assert(lfs->cfg->lookahead > 0);
|
||||
if (lfs->cfg->lookahead_buffer) {
|
||||
lfs->free.buffer = lfs->cfg->lookahead_buffer;
|
||||
} else {
|
||||
lfs->free.buffer = malloc(lfs->free.lookahead/8);
|
||||
lfs->free.buffer = malloc(lfs->cfg->lookahead/8);
|
||||
if (!lfs->free.buffer) {
|
||||
return LFS_ERR_NOMEM;
|
||||
}
|
||||
|
@ -1919,7 +1919,7 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||
}
|
||||
|
||||
// create free lookahead
|
||||
memset(lfs->free.buffer, 0, lfs->free.lookahead/8);
|
||||
memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8);
|
||||
lfs->free.begin = 0;
|
||||
lfs->free.off = 0;
|
||||
lfs->free.end = lfs->free.begin + lfs->cfg->block_count;
|
||||
|
@ -1998,8 +1998,8 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||
}
|
||||
|
||||
// setup free lookahead
|
||||
lfs->free.begin = -lfs->free.lookahead;
|
||||
lfs->free.off = lfs->free.lookahead;
|
||||
lfs->free.begin = -lfs->cfg->lookahead;
|
||||
lfs->free.off = lfs->cfg->lookahead;
|
||||
lfs->free.end = lfs->free.begin + lfs->cfg->block_count;
|
||||
|
||||
// load superblock
|
||||
|
|
|
@ -236,7 +236,6 @@ typedef struct lfs_superblock {
|
|||
} lfs_superblock_t;
|
||||
|
||||
typedef struct lfs_free {
|
||||
lfs_size_t lookahead;
|
||||
lfs_block_t begin;
|
||||
lfs_block_t end;
|
||||
lfs_block_t off;
|
||||
|
|
Loading…
Reference in New Issue