|
|
|
@ -97,62 +97,47 @@ int mufs_alloc_page(struct mufs_tree *tree, uint32_t *page, |
|
|
|
|
return mufs_do_lookup(fs, page, tree->root, tree->depth, va, 0, 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int mufs_do_free_page(struct mufs *fs, uint32_t *base, |
|
|
|
|
static int mufs_do_free_page(struct mufs *fs, uint32_t base, |
|
|
|
|
uint8_t depth, uint32_t va, int free_page) |
|
|
|
|
{ |
|
|
|
|
struct flash_dev *dev = fs->dev; |
|
|
|
|
char data[1 << fs->dev->log2_block_size]; |
|
|
|
|
uint32_t *table = (uint32_t *)data; |
|
|
|
|
uint32_t entry; |
|
|
|
|
size_t index; |
|
|
|
|
|
|
|
|
|
if (!base || *base == 0) |
|
|
|
|
if (base == 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
if (!depth) { |
|
|
|
|
if (free_page) { |
|
|
|
|
mufs_free_block(fs, *base); |
|
|
|
|
*base = 0; |
|
|
|
|
} |
|
|
|
|
if (free_page) |
|
|
|
|
mufs_free_block(fs, base); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (flash_read(fs->dev, *base << dev->log2_block_size, data, |
|
|
|
|
sizeof data) == 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
index = va & ((1 << (fs->log2_nentries * (depth - 1))) - 1); |
|
|
|
|
|
|
|
|
|
if (mufs_do_free_page(fs, table + index, depth - 1, va, free_page) < 0) |
|
|
|
|
if (flash_read(fs->dev, (base << dev->log2_block_size) + index * |
|
|
|
|
sizeof entry, &entry, sizeof entry) == 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
for (index = 0; index < (UINT32_C(1) << fs->log2_nentries); ++index) { |
|
|
|
|
if (!table[index]) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (flash_write(dev, *base << dev->log2_block_size, data, |
|
|
|
|
sizeof data) == 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (mufs_free_block(fs, *base) < 0) |
|
|
|
|
if (mufs_do_free_page(fs, entry, depth - 1, va, free_page) < 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
*base = 0; |
|
|
|
|
if (flash_write0(fs->dev, (base << dev->log2_block_size) + index * |
|
|
|
|
sizeof entry, sizeof entry) == 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
return flash_sync(fs->dev); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void mufs_unmap_page(struct mufs_tree *tree, uint32_t va) |
|
|
|
|
{ |
|
|
|
|
mufs_do_free_page(tree->fs, &tree->root, tree->depth, va, 0); |
|
|
|
|
mufs_do_free_page(tree->fs, tree->root, tree->depth, va, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void mufs_free_page(struct mufs_tree *tree, uint32_t va) |
|
|
|
|
{ |
|
|
|
|
mufs_do_free_page(tree->fs, &tree->root, tree->depth, va, 1); |
|
|
|
|
mufs_do_free_page(tree->fs, tree->root, tree->depth, va, 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int mufs_extend_tree(struct mufs_tree *tree, uint8_t depth) |
|
|
|
|