mufs: reduce memory footprint in block allocation

This commit is contained in:
S.J.R. van Schaik 2017-06-16 14:20:43 +02:00
parent a22b59b2a8
commit 3c35521979
2 changed files with 50 additions and 35 deletions

View file

@ -6,68 +6,82 @@
#include "block.h" #include "block.h"
static int mufs_mark_block(struct mufs *fs, uint32_t block, int status) int mufs_mark_block(struct mufs *fs, uint32_t block, int status)
{ {
char data[1 << fs->dev->log2_block_size]; struct flash_dev *dev = fs->dev;
uint8_t log2_bits_per_block = fs->dev->log2_block_size + ilog2(8); uint32_t data;
size_t index; size_t offset, index;
index = block & ((UINT32_C(1) << log2_bits_per_block) - 1); if (block >= fs->nblocks)
block >>= log2_bits_per_block; return -1;
if (flash_read(fs->dev, (1 + block) << fs->dev->log2_block_size, data, offset = align(block >> ilog2(8), ilog2(4));
index = mask(block, ilog2(8) + ilog2(4));
if (flash_read(fs->dev, (1 << dev->log2_block_size) + offset, &data,
sizeof data) ==0) sizeof data) ==0)
return -1; return -1;
if (status) { if (status) {
set_bit(data, index); data |= 1 << index;
} else { } else {
clear_bit(data, index); data = data & ~(1 << index);
} }
if (flash_write(fs->dev, (1 + block) << fs->dev->log2_block_size, data, if (flash_write(fs->dev, (1 << dev->log2_block_size) + offset, &data,
sizeof data) == 0) sizeof data) == 0)
return -1; return -1;
return 0; return 0;
} }
int mufs_alloc_block(struct mufs *fs, uint32_t *found) static size_t mufs_next_free_block(struct mufs *fs)
{ {
char data[1 << fs->dev->log2_block_size]; struct flash_dev *dev = fs->dev;
uint32_t nblocks = fs->nblocks; char data[32];
uint32_t nbits; size_t nblocks = fs->nblocks;
uint32_t block = 0; size_t offset, index, bitlen, len;
size_t index;
uint8_t log2_bits_per_block = fs->dev->log2_block_size + ilog2(8); offset = 0;
size_t nbitmap_size = align_up(fs->nblocks, log2_bits_per_block) >>
log2_bits_per_block;
while (nblocks) { while (nblocks) {
if (flash_read(fs->dev, (1 + block) << fs->dev->log2_block_size, data, bitlen = min(BIT_SIZE(data), nblocks);
sizeof data) == 0) len = bitlen >> ilog2(8);
return -1;
nbits = min(nblocks, UINT32_C(1) << log2_bits_per_block); if (flash_read(fs->dev, (1 << dev->log2_block_size) + offset, data,
len) == 0)
return SIZE_MAX;
if ((index = next_clear_bit(data, nbits)) == SIZE_MAX) { if ((index = next_clear_bit(data, bitlen)) != SIZE_MAX)
++block; return (offset >> (ilog2(8) + ilog2(32))) + index;
nblocks -= nbits;
continue; if (flash_write(fs->dev, (1 << dev->log2_block_size) + offset, data,
len) == 0)
return SIZE_MAX;
offset += len;
nblocks -= bitlen;
} }
index += block << log2_bits_per_block; return SIZE_MAX;
*found = 1 + nbitmap_size + index; }
int mufs_alloc_block(struct mufs *fs, uint32_t *found)
{
size_t index;
if ((index = mufs_next_free_block(fs)) == SIZE_MAX)
return -1;
*found = index;
return mufs_mark_block(fs, index, 1); return mufs_mark_block(fs, index, 1);
} }
return -1;
}
int mufs_free_block(struct mufs *fs, uint32_t block) int mufs_free_block(struct mufs *fs, uint32_t block)
{ {
uint8_t log2_bits_per_block = fs->dev->log2_block_size + ilog2(8); struct flash_dev *dev = fs->dev;
uint8_t log2_bits_per_block = dev->log2_block_size + ilog2(8);
size_t nbitmap_size = align_up(fs->nblocks, log2_bits_per_block) >> size_t nbitmap_size = align_up(fs->nblocks, log2_bits_per_block) >>
log2_bits_per_block; log2_bits_per_block;
@ -76,5 +90,5 @@ int mufs_free_block(struct mufs *fs, uint32_t block)
flash_erase(fs->dev, block, 1); flash_erase(fs->dev, block, 1);
return mufs_mark_block(fs, block - 1 - nbitmap_size, 0); return mufs_mark_block(fs, block, 0);
} }

View file

@ -1,4 +1,5 @@
#pragma once #pragma once
int mufs_mark_block(struct mufs *fs, uint32_t block, int status);
int mufs_alloc_block(struct mufs *fs, uint32_t *block); int mufs_alloc_block(struct mufs *fs, uint32_t *block);
int mufs_free_block(struct mufs *fs, uint32_t block); int mufs_free_block(struct mufs *fs, uint32_t block);