mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #6046 from geky/fix-lookahead-noack-pop
littlefs: Fix incorrect lookahead population before ackpull/6162/head
commit
e66cc74b8f
|
@ -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->cfg->lookahead) {
|
||||
if (off < lfs->free.size) {
|
||||
lfs->free.buffer[off / 32] |= 1U << (off % 32);
|
||||
}
|
||||
|
||||
|
@ -287,18 +287,7 @@ static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
|
|||
|
||||
static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
||||
while (true) {
|
||||
while (true) {
|
||||
// check if we have looked at all blocks since last ack
|
||||
if (lfs->free.begin + lfs->free.off == lfs->free.end) {
|
||||
LFS_WARN("No more free space %ld", lfs->free.end);
|
||||
return LFS_ERR_NOSPC;
|
||||
}
|
||||
|
||||
if (lfs->free.off >= lfs_min(
|
||||
lfs->cfg->lookahead, lfs->cfg->block_count)) {
|
||||
break;
|
||||
}
|
||||
|
||||
while (lfs->free.off != lfs->free.size) {
|
||||
lfs_block_t off = lfs->free.off;
|
||||
lfs->free.off += 1;
|
||||
|
||||
|
@ -309,7 +298,15 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
|||
}
|
||||
}
|
||||
|
||||
lfs->free.begin += lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
|
||||
// check if we have looked at all blocks since last ack
|
||||
if (lfs->free.off == lfs->free.ack - lfs->free.begin) {
|
||||
LFS_WARN("No more free space %ld", lfs->free.off + lfs->free.begin);
|
||||
return LFS_ERR_NOSPC;
|
||||
}
|
||||
|
||||
lfs->free.begin += lfs->free.size;
|
||||
lfs->free.size = lfs_min(lfs->cfg->lookahead,
|
||||
lfs->free.ack - lfs->free.begin);
|
||||
lfs->free.off = 0;
|
||||
|
||||
// find mask of free blocks from tree
|
||||
|
@ -322,7 +319,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
|||
}
|
||||
|
||||
static void lfs_alloc_ack(lfs_t *lfs) {
|
||||
lfs->free.end = lfs->free.begin + lfs->free.off + lfs->cfg->block_count;
|
||||
lfs->free.ack = lfs->free.off-1 + lfs->free.begin + lfs->cfg->block_count;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1966,11 +1963,11 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||
// create free lookahead
|
||||
memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8);
|
||||
lfs->free.begin = 0;
|
||||
lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
|
||||
lfs->free.off = 0;
|
||||
lfs->free.end = lfs->free.begin + lfs->free.off + lfs->cfg->block_count;
|
||||
lfs_alloc_ack(lfs);
|
||||
|
||||
// create superblock dir
|
||||
lfs_alloc_ack(lfs);
|
||||
lfs_dir_t superdir;
|
||||
err = lfs_dir_alloc(lfs, &superdir);
|
||||
if (err) {
|
||||
|
@ -2042,10 +2039,11 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||
return err;
|
||||
}
|
||||
|
||||
// setup free lookahead, rewind so first allocation triggers a scan
|
||||
lfs->free.begin = -lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
|
||||
lfs->free.off = -lfs->free.begin;
|
||||
lfs->free.end = lfs->free.begin + lfs->free.off + lfs->cfg->block_count;
|
||||
// setup free lookahead
|
||||
lfs->free.begin = 0;
|
||||
lfs->free.size = 0;
|
||||
lfs->free.off = 0;
|
||||
lfs_alloc_ack(lfs);
|
||||
|
||||
// load superblock
|
||||
lfs_dir_t dir;
|
||||
|
|
|
@ -239,8 +239,9 @@ typedef struct lfs_superblock {
|
|||
|
||||
typedef struct lfs_free {
|
||||
lfs_block_t begin;
|
||||
lfs_block_t end;
|
||||
lfs_block_t size;
|
||||
lfs_block_t off;
|
||||
lfs_block_t ack;
|
||||
uint32_t *buffer;
|
||||
} lfs_free_t;
|
||||
|
||||
|
|
|
@ -266,6 +266,40 @@ tests/test.py << TEST
|
|||
lfs_mkdir(&lfs, "exhaustiondir2") => LFS_ERR_NOSPC;
|
||||
TEST
|
||||
|
||||
echo "--- Split dir test ---"
|
||||
rm -rf blocks
|
||||
tests/test.py << TEST
|
||||
lfs_format(&lfs, &cfg) => 0;
|
||||
TEST
|
||||
tests/test.py << TEST
|
||||
lfs_mount(&lfs, &cfg) => 0;
|
||||
|
||||
// create one block whole for half a directory
|
||||
lfs_file_open(&lfs, &file[0], "bump", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||
lfs_file_write(&lfs, &file[0], (void*)"hi", 2) => 2;
|
||||
lfs_file_close(&lfs, &file[0]) => 0;
|
||||
|
||||
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
|
||||
size = strlen("blahblahblahblah");
|
||||
memcpy(buffer, "blahblahblahblah", size);
|
||||
for (lfs_size_t i = 0;
|
||||
i < (cfg.block_count-6)*(cfg.block_size-8);
|
||||
i += size) {
|
||||
lfs_file_write(&lfs, &file[0], buffer, size) => size;
|
||||
}
|
||||
lfs_file_close(&lfs, &file[0]) => 0;
|
||||
|
||||
// open whole
|
||||
lfs_remove(&lfs, "bump") => 0;
|
||||
|
||||
lfs_mkdir(&lfs, "splitdir") => 0;
|
||||
lfs_file_open(&lfs, &file[0], "splitdir/bump",
|
||||
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
||||
lfs_file_write(&lfs, &file[0], buffer, size) => LFS_ERR_NOSPC;
|
||||
lfs_file_close(&lfs, &file[0]) => 0;
|
||||
|
||||
lfs_unmount(&lfs) => 0;
|
||||
TEST
|
||||
|
||||
echo "--- Results ---"
|
||||
tests/stats.py
|
||||
|
|
Loading…
Reference in New Issue