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