Skip to content

Commit e66cc74

Browse files
authored
Merge pull request #6046 from geky/fix-lookahead-noack-pop
littlefs: Fix incorrect lookahead population before ack
2 parents f2ff36b + df1896b commit e66cc74

File tree

3 files changed

+55
-22
lines changed

3 files changed

+55
-22
lines changed

features/filesystem/littlefs/littlefs/lfs.c

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
278278
% (lfs_soff_t)(lfs->cfg->block_count))
279279
+ lfs->cfg->block_count) % lfs->cfg->block_count;
280280

281-
if (off < lfs->cfg->lookahead) {
281+
if (off < lfs->free.size) {
282282
lfs->free.buffer[off / 32] |= 1U << (off % 32);
283283
}
284284

@@ -287,18 +287,7 @@ static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
287287

288288
static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
289289
while (true) {
290-
while (true) {
291-
// check if we have looked at all blocks since last ack
292-
if (lfs->free.begin + lfs->free.off == lfs->free.end) {
293-
LFS_WARN("No more free space %ld", lfs->free.end);
294-
return LFS_ERR_NOSPC;
295-
}
296-
297-
if (lfs->free.off >= lfs_min(
298-
lfs->cfg->lookahead, lfs->cfg->block_count)) {
299-
break;
300-
}
301-
290+
while (lfs->free.off != lfs->free.size) {
302291
lfs_block_t off = lfs->free.off;
303292
lfs->free.off += 1;
304293

@@ -309,7 +298,15 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
309298
}
310299
}
311300

312-
lfs->free.begin += lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
301+
// check if we have looked at all blocks since last ack
302+
if (lfs->free.off == lfs->free.ack - lfs->free.begin) {
303+
LFS_WARN("No more free space %ld", lfs->free.off + lfs->free.begin);
304+
return LFS_ERR_NOSPC;
305+
}
306+
307+
lfs->free.begin += lfs->free.size;
308+
lfs->free.size = lfs_min(lfs->cfg->lookahead,
309+
lfs->free.ack - lfs->free.begin);
313310
lfs->free.off = 0;
314311

315312
// find mask of free blocks from tree
@@ -322,7 +319,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
322319
}
323320

324321
static void lfs_alloc_ack(lfs_t *lfs) {
325-
lfs->free.end = lfs->free.begin + lfs->free.off + lfs->cfg->block_count;
322+
lfs->free.ack = lfs->free.off-1 + lfs->free.begin + lfs->cfg->block_count;
326323
}
327324

328325

@@ -1966,11 +1963,11 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
19661963
// create free lookahead
19671964
memset(lfs->free.buffer, 0, lfs->cfg->lookahead/8);
19681965
lfs->free.begin = 0;
1966+
lfs->free.size = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
19691967
lfs->free.off = 0;
1970-
lfs->free.end = lfs->free.begin + lfs->free.off + lfs->cfg->block_count;
1968+
lfs_alloc_ack(lfs);
19711969

19721970
// create superblock dir
1973-
lfs_alloc_ack(lfs);
19741971
lfs_dir_t superdir;
19751972
err = lfs_dir_alloc(lfs, &superdir);
19761973
if (err) {
@@ -2042,10 +2039,11 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
20422039
return err;
20432040
}
20442041

2045-
// setup free lookahead, rewind so first allocation triggers a scan
2046-
lfs->free.begin = -lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
2047-
lfs->free.off = -lfs->free.begin;
2048-
lfs->free.end = lfs->free.begin + lfs->free.off + lfs->cfg->block_count;
2042+
// setup free lookahead
2043+
lfs->free.begin = 0;
2044+
lfs->free.size = 0;
2045+
lfs->free.off = 0;
2046+
lfs_alloc_ack(lfs);
20492047

20502048
// load superblock
20512049
lfs_dir_t dir;

features/filesystem/littlefs/littlefs/lfs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,9 @@ typedef struct lfs_superblock {
239239

240240
typedef struct lfs_free {
241241
lfs_block_t begin;
242-
lfs_block_t end;
242+
lfs_block_t size;
243243
lfs_block_t off;
244+
lfs_block_t ack;
244245
uint32_t *buffer;
245246
} lfs_free_t;
246247

features/filesystem/littlefs/littlefs/tests/test_alloc.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,40 @@ tests/test.py << TEST
266266
lfs_mkdir(&lfs, "exhaustiondir2") => LFS_ERR_NOSPC;
267267
TEST
268268

269+
echo "--- Split dir test ---"
270+
rm -rf blocks
271+
tests/test.py << TEST
272+
lfs_format(&lfs, &cfg) => 0;
273+
TEST
274+
tests/test.py << TEST
275+
lfs_mount(&lfs, &cfg) => 0;
276+
277+
// create one block whole for half a directory
278+
lfs_file_open(&lfs, &file[0], "bump", LFS_O_WRONLY | LFS_O_CREAT) => 0;
279+
lfs_file_write(&lfs, &file[0], (void*)"hi", 2) => 2;
280+
lfs_file_close(&lfs, &file[0]) => 0;
281+
282+
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
283+
size = strlen("blahblahblahblah");
284+
memcpy(buffer, "blahblahblahblah", size);
285+
for (lfs_size_t i = 0;
286+
i < (cfg.block_count-6)*(cfg.block_size-8);
287+
i += size) {
288+
lfs_file_write(&lfs, &file[0], buffer, size) => size;
289+
}
290+
lfs_file_close(&lfs, &file[0]) => 0;
291+
292+
// open whole
293+
lfs_remove(&lfs, "bump") => 0;
294+
295+
lfs_mkdir(&lfs, "splitdir") => 0;
296+
lfs_file_open(&lfs, &file[0], "splitdir/bump",
297+
LFS_O_WRONLY | LFS_O_CREAT) => 0;
298+
lfs_file_write(&lfs, &file[0], buffer, size) => LFS_ERR_NOSPC;
299+
lfs_file_close(&lfs, &file[0]) => 0;
300+
301+
lfs_unmount(&lfs) => 0;
302+
TEST
269303

270304
echo "--- Results ---"
271305
tests/stats.py

0 commit comments

Comments
 (0)