Skip to content

Commit 273cb7c

Browse files
committed
Fixed problem with lookaheads larger than block device
Simply limiting the lookahead region to the size of the block device fixes the problem. Also added logic to limit the allocated region and floor to nearest word, since the additional memory couldn't really be used effectively.
1 parent d9367e0 commit 273cb7c

File tree

3 files changed

+29
-24
lines changed

3 files changed

+29
-24
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ script:
1515
- CFLAGS="-DLFS_READ_SIZE=1 -DLFS_PROG_SIZE=1" make test
1616
- CFLAGS="-DLFS_READ_SIZE=512 -DLFS_PROG_SIZE=512" make test
1717
- CFLAGS="-DLFS_BLOCK_COUNT=1023" make test
18+
- CFLAGS="-DLFS_LOOKAHEAD=2047" make test

lfs.c

+24-21
Original file line numberDiff line numberDiff line change
@@ -262,12 +262,12 @@ int lfs_deorphan(lfs_t *lfs);
262262
static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
263263
lfs_t *lfs = p;
264264

265-
lfs_block_t off = (((lfs_soff_t)(block - lfs->free.start)
265+
lfs_block_t off = (((lfs_soff_t)(block - lfs->free.begin)
266266
% (lfs_soff_t)(lfs->cfg->block_count))
267267
+ lfs->cfg->block_count) % lfs->cfg->block_count;
268268

269-
if (off < lfs->cfg->lookahead) {
270-
lfs->free.lookahead[off / 32] |= 1U << (off % 32);
269+
if (off < lfs->free.lookahead) {
270+
lfs->free.buffer[off / 32] |= 1U << (off % 32);
271271
}
272272

273273
return 0;
@@ -285,30 +285,30 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
285285
while (true) {
286286
while (true) {
287287
// check if we have looked at all blocks since last ack
288-
if (lfs->free.start + lfs->free.off == lfs->free.end) {
288+
if (lfs->free.begin + lfs->free.off == lfs->free.end) {
289289
LFS_WARN("No more free space %d", lfs->free.end);
290290
return LFS_ERR_NOSPC;
291291
}
292292

293-
if (lfs->free.off >= lfs->cfg->lookahead) {
293+
if (lfs->free.off >= lfs->free.lookahead) {
294294
break;
295295
}
296296

297297
lfs_block_t off = lfs->free.off;
298298
lfs->free.off += 1;
299299

300-
if (!(lfs->free.lookahead[off / 32] & (1U << (off % 32)))) {
300+
if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) {
301301
// found a free block
302-
*block = (lfs->free.start + off) % lfs->cfg->block_count;
302+
*block = (lfs->free.begin + off) % lfs->cfg->block_count;
303303
return 0;
304304
}
305305
}
306306

307-
lfs->free.start += lfs->cfg->lookahead;
307+
lfs->free.begin += lfs->free.lookahead;
308308
lfs->free.off = 0;
309309

310310
// find mask of free blocks from tree
311-
memset(lfs->free.lookahead, 0, lfs->cfg->lookahead/8);
311+
memset(lfs->free.buffer, 0, lfs->free.lookahead/8);
312312
int err = lfs_traverse(lfs, lfs_alloc_lookahead, lfs);
313313
if (err) {
314314
return err;
@@ -317,7 +317,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
317317
}
318318

319319
static void lfs_alloc_ack(lfs_t *lfs) {
320-
lfs->free.end = lfs->free.start + lfs->free.off + lfs->cfg->block_count;
320+
lfs->free.end = lfs->free.begin + lfs->free.off + lfs->cfg->block_count;
321321
}
322322

323323

@@ -1786,12 +1786,15 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
17861786
}
17871787
}
17881788

1789-
// setup lookahead
1789+
// setup lookahead, round down to nearest 32-bits
1790+
lfs->free.lookahead = lfs_min(lfs->cfg->lookahead, lfs->cfg->block_count);
1791+
lfs->free.lookahead = 32 * (lfs->free.lookahead / 32);
1792+
assert(lfs->free.lookahead > 0);
17901793
if (lfs->cfg->lookahead_buffer) {
1791-
lfs->free.lookahead = lfs->cfg->lookahead_buffer;
1794+
lfs->free.buffer = lfs->cfg->lookahead_buffer;
17921795
} else {
1793-
lfs->free.lookahead = malloc(lfs->cfg->lookahead/8);
1794-
if (!lfs->free.lookahead) {
1796+
lfs->free.buffer = malloc(lfs->free.lookahead/8);
1797+
if (!lfs->free.buffer) {
17951798
return LFS_ERR_NOMEM;
17961799
}
17971800
}
@@ -1816,7 +1819,7 @@ static int lfs_deinit(lfs_t *lfs) {
18161819
}
18171820

18181821
if (!lfs->cfg->lookahead_buffer) {
1819-
free(lfs->free.lookahead);
1822+
free(lfs->free.buffer);
18201823
}
18211824

18221825
return 0;
@@ -1829,10 +1832,10 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
18291832
}
18301833

18311834
// create free lookahead
1832-
memset(lfs->free.lookahead, 0, lfs->cfg->lookahead/8);
1833-
lfs->free.start = 0;
1835+
memset(lfs->free.buffer, 0, lfs->free.lookahead/8);
1836+
lfs->free.begin = 0;
18341837
lfs->free.off = 0;
1835-
lfs->free.end = lfs->free.start + lfs->cfg->block_count;
1838+
lfs->free.end = lfs->free.begin + lfs->cfg->block_count;
18361839

18371840
// create superblock dir
18381841
lfs_alloc_ack(lfs);
@@ -1908,9 +1911,9 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
19081911
}
19091912

19101913
// setup free lookahead
1911-
lfs->free.start = -lfs->cfg->lookahead;
1912-
lfs->free.off = lfs->cfg->lookahead;
1913-
lfs->free.end = lfs->free.start + lfs->cfg->block_count;
1914+
lfs->free.begin = -lfs->free.lookahead;
1915+
lfs->free.off = lfs->free.lookahead;
1916+
lfs->free.end = lfs->free.begin + lfs->cfg->block_count;
19141917

19151918
// load superblock
19161919
lfs_dir_t dir;

lfs.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,11 @@ typedef struct lfs_superblock {
225225
} lfs_superblock_t;
226226

227227
typedef struct lfs_free {
228+
lfs_size_t lookahead;
229+
lfs_block_t begin;
228230
lfs_block_t end;
229-
lfs_block_t start;
230231
lfs_block_t off;
231-
uint32_t *lookahead;
232+
uint32_t *buffer;
232233
} lfs_free_t;
233234

234235
// The littlefs type
@@ -237,12 +238,12 @@ typedef struct lfs {
237238

238239
lfs_block_t root[2];
239240
lfs_file_t *files;
240-
bool deorphaned;
241241

242242
lfs_cache_t rcache;
243243
lfs_cache_t pcache;
244244

245245
lfs_free_t free;
246+
bool deorphaned;
246247
} lfs_t;
247248

248249

0 commit comments

Comments
 (0)