Skip to content

Commit

Permalink
Renamed a number of internal block-allocator fields
Browse files Browse the repository at this point in the history
- Renamed lfs.free      -> lfs.lookahead
- Renamed lfs.free.off  -> lfs.lookahead.start
- Renamed lfs.free.i    -> lfs.lookahead.next
- Renamed lfs.free.ack  -> lfs.lookahead.ckpoint
- Renamed lfs_alloc_ack -> lfs_alloc_ckpoint

These have been named a bit confusingly, and I think the new names make
their relevant purposes a bit clearer.

At the very it's clear lfs.lookahead is related to the lookahead buffer.
(and doesn't imply a closed free-bitmap).
  • Loading branch information
geky committed Dec 20, 2023
1 parent c733d9e commit 7b68441
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 52 deletions.
93 changes: 48 additions & 45 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,11 +596,11 @@ static int lfs_rawunmount(lfs_t *lfs);
#ifndef LFS_READONLY
static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
lfs_t *lfs = (lfs_t*)p;
lfs_block_t off = ((block - lfs->free.off)
lfs_block_t off = ((block - lfs->lookahead.start)
+ lfs->block_count) % lfs->block_count;

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

return 0;
Expand All @@ -610,28 +610,31 @@ static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
// indicate allocated blocks have been committed into the filesystem, this
// is to prevent blocks from being garbage collected in the middle of a
// commit operation
static void lfs_alloc_ack(lfs_t *lfs) {
lfs->free.ack = lfs->block_count;
static void lfs_alloc_ckpoint(lfs_t *lfs) {
lfs->lookahead.ckpoint = lfs->block_count;
}

// drop the lookahead buffer, this is done during mounting and failed
// traversals in order to avoid invalid lookahead state
static void lfs_alloc_drop(lfs_t *lfs) {
lfs->free.size = 0;
lfs->free.i = 0;
lfs_alloc_ack(lfs);
lfs->lookahead.size = 0;
lfs->lookahead.next = 0;
lfs_alloc_ckpoint(lfs);
}

#ifndef LFS_READONLY
static int lfs_fs_rawgc(lfs_t *lfs) {
// Move free offset at the first unused block (lfs->free.i)
// lfs->free.i is equal lfs->free.size when all blocks are used
lfs->free.off = (lfs->free.off + lfs->free.i) % lfs->block_count;
lfs->free.size = lfs_min(8*lfs->cfg->lookahead_size, lfs->free.ack);
lfs->free.i = 0;
// Move free offset at the first unused block (lfs->lookahead.next)
// lfs->lookahead.next is equal lfs->lookahead.size when all blocks are used
lfs->lookahead.start = (lfs->lookahead.start + lfs->lookahead.next)
% lfs->block_count;
lfs->lookahead.size = lfs_min(
8*lfs->cfg->lookahead_size,
lfs->lookahead.ckpoint);
lfs->lookahead.next = 0;

// find mask of free blocks from tree
memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size);
memset(lfs->lookahead.buffer, 0, lfs->cfg->lookahead_size);
int err = lfs_fs_rawtraverse(lfs, lfs_alloc_lookahead, lfs, true);
if (err) {
lfs_alloc_drop(lfs);
Expand All @@ -645,32 +648,32 @@ static int lfs_fs_rawgc(lfs_t *lfs) {
#ifndef LFS_READONLY
static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
while (true) {
while (lfs->free.i != lfs->free.size) {
lfs_block_t off = lfs->free.i;
lfs->free.i += 1;
lfs->free.ack -= 1;
while (lfs->lookahead.next != lfs->lookahead.size) {
lfs_block_t off = lfs->lookahead.next;
lfs->lookahead.next += 1;
lfs->lookahead.ckpoint -= 1;

if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) {
if (!(lfs->lookahead.buffer[off / 32] & (1U << (off % 32)))) {
// found a free block
*block = (lfs->free.off + off) % lfs->block_count;
*block = (lfs->lookahead.start + off) % lfs->block_count;

// eagerly find next off so an alloc ack can
// discredit old lookahead blocks
while (lfs->free.i != lfs->free.size &&
(lfs->free.buffer[lfs->free.i / 32]
& (1U << (lfs->free.i % 32)))) {
lfs->free.i += 1;
lfs->free.ack -= 1;
while (lfs->lookahead.next != lfs->lookahead.size &&
(lfs->lookahead.buffer[lfs->lookahead.next / 32]
& (1U << (lfs->lookahead.next % 32)))) {
lfs->lookahead.next += 1;
lfs->lookahead.ckpoint -= 1;
}

return 0;
}
}

// check if we have looked at all blocks since last ack
if (lfs->free.ack == 0) {
if (lfs->lookahead.ckpoint == 0) {
LFS_ERROR("No more free space %"PRIu32,
lfs->free.i + lfs->free.off);
lfs->lookahead.next + lfs->lookahead.start);
return LFS_ERR_NOSPC;
}

Expand Down Expand Up @@ -2586,7 +2589,7 @@ static int lfs_rawmkdir(lfs_t *lfs, const char *path) {
}

// build up new directory
lfs_alloc_ack(lfs);
lfs_alloc_ckpoint(lfs);
lfs_mdir_t dir;
err = lfs_dir_alloc(lfs, &dir);
if (err) {
Expand Down Expand Up @@ -3272,7 +3275,7 @@ static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) {
#ifndef LFS_READONLY
static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file) {
file->off = file->pos;
lfs_alloc_ack(lfs);
lfs_alloc_ckpoint(lfs);
int err = lfs_file_relocate(lfs, file);
if (err) {
return err;
Expand Down Expand Up @@ -3535,7 +3538,7 @@ static lfs_ssize_t lfs_file_flushedwrite(lfs_t *lfs, lfs_file_t *file,
}

// extend file with new blocks
lfs_alloc_ack(lfs);
lfs_alloc_ckpoint(lfs);
int err = lfs_ctz_extend(lfs, &file->cache, &lfs->rcache,
file->block, file->pos,
&file->block, &file->off);
Expand Down Expand Up @@ -3578,7 +3581,7 @@ static lfs_ssize_t lfs_file_flushedwrite(lfs_t *lfs, lfs_file_t *file,
data += diff;
nsize -= diff;

lfs_alloc_ack(lfs);
lfs_alloc_ckpoint(lfs);
}

return size;
Expand Down Expand Up @@ -4185,10 +4188,10 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
LFS_ASSERT(lfs->cfg->lookahead_size % 8 == 0 &&
(uintptr_t)lfs->cfg->lookahead_buffer % 4 == 0);
if (lfs->cfg->lookahead_buffer) {
lfs->free.buffer = lfs->cfg->lookahead_buffer;
lfs->lookahead.buffer = lfs->cfg->lookahead_buffer;
} else {
lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead_size);
if (!lfs->free.buffer) {
lfs->lookahead.buffer = lfs_malloc(lfs->cfg->lookahead_size);
if (!lfs->lookahead.buffer) {
err = LFS_ERR_NOMEM;
goto cleanup;
}
Expand Down Expand Up @@ -4245,7 +4248,7 @@ static int lfs_deinit(lfs_t *lfs) {
}

if (!lfs->cfg->lookahead_buffer) {
lfs_free(lfs->free.buffer);
lfs_free(lfs->lookahead.buffer);
}

return 0;
Expand All @@ -4265,12 +4268,12 @@ static int lfs_rawformat(lfs_t *lfs, const struct lfs_config *cfg) {
LFS_ASSERT(cfg->block_count != 0);

// create free lookahead
memset(lfs->free.buffer, 0, lfs->cfg->lookahead_size);
lfs->free.off = 0;
lfs->free.size = lfs_min(8*lfs->cfg->lookahead_size,
memset(lfs->lookahead.buffer, 0, lfs->cfg->lookahead_size);
lfs->lookahead.start = 0;
lfs->lookahead.size = lfs_min(8*lfs->cfg->lookahead_size,
lfs->block_count);
lfs->free.i = 0;
lfs_alloc_ack(lfs);
lfs->lookahead.next = 0;
lfs_alloc_ckpoint(lfs);

// create root dir
lfs_mdir_t root;
Expand Down Expand Up @@ -4478,7 +4481,7 @@ static int lfs_rawmount(lfs_t *lfs, const struct lfs_config *cfg) {

// setup free lookahead, to distribute allocations uniformly across
// boots, we start the allocator at a random location
lfs->free.off = lfs->seed % lfs->block_count;
lfs->lookahead.start = lfs->seed % lfs->block_count;
lfs_alloc_drop(lfs);

return 0;
Expand Down Expand Up @@ -5451,10 +5454,10 @@ static int lfs1_mount(lfs_t *lfs, struct lfs1 *lfs1,
lfs->lfs1->root[1] = LFS_BLOCK_NULL;

// setup free lookahead
lfs->free.off = 0;
lfs->free.size = 0;
lfs->free.i = 0;
lfs_alloc_ack(lfs);
lfs->lookahead.start = 0;
lfs->lookahead.size = 0;
lfs->lookahead.next = 0;
lfs_alloc_ckpoint(lfs);

// load superblock
lfs1_dir_t dir;
Expand Down
10 changes: 5 additions & 5 deletions lfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,13 +430,13 @@ typedef struct lfs {
lfs_gstate_t gdisk;
lfs_gstate_t gdelta;

struct lfs_free {
lfs_block_t off;
struct lfs_lookahead {
lfs_block_t start;
lfs_block_t size;
lfs_block_t i;
lfs_block_t ack;
lfs_block_t next;
lfs_block_t ckpoint;
uint32_t *buffer;
} free;
} lookahead;

const struct lfs_config *cfg;
lfs_size_t block_count;
Expand Down
4 changes: 2 additions & 2 deletions tests/test_orphans.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ code = '''
lfs_mount(&lfs, cfg) => 0;
// create an orphan
lfs_mdir_t orphan;
lfs_alloc_ack(&lfs);
lfs_alloc_ckpoint(&lfs);
lfs_dir_alloc(&lfs, &orphan) => 0;
lfs_dir_commit(&lfs, &orphan, NULL, 0) => 0;

Expand Down Expand Up @@ -170,7 +170,7 @@ code = '''
lfs_mount(&lfs, cfg) => 0;
// create an orphan
lfs_mdir_t orphan;
lfs_alloc_ack(&lfs);
lfs_alloc_ckpoint(&lfs);
lfs_dir_alloc(&lfs, &orphan) => 0;
lfs_dir_commit(&lfs, &orphan, NULL, 0) => 0;

Expand Down

0 comments on commit 7b68441

Please sign in to comment.