t: Added lookahead to lfsr_traversal_t, adopted in lfs_alloc
This sort of turned into a complete refactor of lfs_alloc in order to
move/reuse the lookahead buffer filling logic into lfsr_fs_traverse.
lfs_alloc now calls lfsr_fs_traverse to fill the lookahead buffer when
no more blocks are available, but also you can too with lfsr_traversal_t
+ LFS_T_LOOKAHEAD.
The one big caveat being if any mutation happens to the filesystem, any
incomplete lookahead needs to be tossed out. To help with this,
lfsr_traversal_read now returns LFS_ERR_BUSY (-16) instead of
LFS_ERR_NOENT (-2) if the filesystem has been modified since the
traversal was opened.
Note that by default lfsr_traversal_t will still try to keep traversing
blocks, but can be told to terminate immediately with LFS_T_EXCL.
Continuing the traversal is probably desired for checking checksums,
debugging, etc, as otherwise you could end up looping over only the
first couple blocks in a write-heavy system, but if you are trying to
populate the lookahead buffer you probably want to just abort and start
over.
I considered adding a flags field to lfs_tinfo for this, but decided
against it since it would be the only place in the current API where we
don't use error codes to convey behavior-changing information. Though
this may be worth reconsidering at some point...
---
In reworking lfs_alloc, a lot of the internal logic was broken up into
specific functions:
- lfs_alloc_ckpoint - checkpoint the allocator
- lfs_alloc_discard - discard any lookahead
- lfs_alloc_shift - discard/shift lookahead if progress can be made
- lfs_alloc_markinuse - mark a block as in-use
- lfs_alloc_markfree - mark any remaining blocks as free
- lfs_alloc_findnext - find the next free block in lookahead
If anything this probably makes lfs_alloc more readable, though the
original motivation was to allow lfsr_traversal_t to only shift/zero the
lookahead buffer if there's a chance we can make progress.
This was based on upstream work by opilat and myself.
Code changes:
code stack
before: 34226 2560
after: 34474 (+0.7%) 2552 (-0.3%)
This commit is contained in:
+9
-12
@@ -27,11 +27,10 @@ code = '''
|
||||
lfs_alloc_ckpoint(&lfs);
|
||||
lfs_size_t alloced = 0;
|
||||
while (true) {
|
||||
lfs_block_t block;
|
||||
int err = lfs_alloc(&lfs, &block, ERASE);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
lfs_sblock_t block = lfs_alloc(&lfs, ERASE);
|
||||
assert(block >= 0 || block == LFS_ERR_NOSPC);
|
||||
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
if (block == LFS_ERR_NOSPC) {
|
||||
break;
|
||||
}
|
||||
alloced += 1;
|
||||
@@ -61,11 +60,10 @@ code = '''
|
||||
lfs_alloc_ckpoint(&lfs);
|
||||
lfs_size_t alloced = 0;
|
||||
while (true) {
|
||||
lfs_block_t block;
|
||||
int err = lfs_alloc(&lfs, &block, ERASE);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
lfs_sblock_t block = lfs_alloc(&lfs, ERASE);
|
||||
assert(block >= 0 || block == LFS_ERR_NOSPC);
|
||||
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
if (block == LFS_ERR_NOSPC) {
|
||||
break;
|
||||
}
|
||||
alloced += 1;
|
||||
@@ -83,11 +81,10 @@ code = '''
|
||||
lfs_alloc_ckpoint(&lfs);
|
||||
alloced = 0;
|
||||
while (true) {
|
||||
lfs_block_t block;
|
||||
int err = lfs_alloc(&lfs, &block, ERASE);
|
||||
assert(!err || err == LFS_ERR_NOSPC);
|
||||
lfs_sblock_t block = lfs_alloc(&lfs, ERASE);
|
||||
assert(block >= 0 || block == LFS_ERR_NOSPC);
|
||||
|
||||
if (err == LFS_ERR_NOSPC) {
|
||||
if (block == LFS_ERR_NOSPC) {
|
||||
break;
|
||||
}
|
||||
alloced += 1;
|
||||
|
||||
+2101
-45
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user