|
|
|
@ -27,6 +27,18 @@ void mufs_del_tree(struct mufs_tree *tree) |
|
|
|
|
free(tree); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static size_t mufs_get_index(struct mufs *fs, uint32_t va, uint8_t depth) |
|
|
|
|
{ |
|
|
|
|
size_t i; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < depth; ++i) |
|
|
|
|
va >>= fs->log2_nentries; |
|
|
|
|
|
|
|
|
|
va &= BITS(0, fs->log2_nentries); |
|
|
|
|
|
|
|
|
|
return va; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int mufs_do_lookup(struct mufs *fs, uint32_t *page, |
|
|
|
|
uint32_t base, uint8_t depth, uint32_t va, uint32_t new_page, |
|
|
|
|
unsigned alloc) |
|
|
|
@ -38,15 +50,16 @@ static int mufs_do_lookup(struct mufs *fs, uint32_t *page, |
|
|
|
|
if (!base) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
if (!depth) { |
|
|
|
|
if (depth == 0) { |
|
|
|
|
*page = base; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
index = va & ((1 << ((depth - 1) * fs->log2_nentries)) - 1); |
|
|
|
|
base <<= dev->log2_block_size; |
|
|
|
|
index = mufs_get_index(fs, va, depth); |
|
|
|
|
base += index * sizeof entry; |
|
|
|
|
|
|
|
|
|
if (flash_read(dev, (base << dev->log2_block_size) + index * sizeof entry, |
|
|
|
|
&entry, sizeof entry) == 0) |
|
|
|
|
if (flash_read(dev, base, &entry, sizeof entry) == 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
if (!entry) { |
|
|
|
@ -58,8 +71,7 @@ static int mufs_do_lookup(struct mufs *fs, uint32_t *page, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (flash_write(dev, (base << dev->log2_block_size) + |
|
|
|
|
index * sizeof entry, &entry, sizeof entry) == 0) |
|
|
|
|
if (flash_write(dev, base, &entry, sizeof entry) == 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
if (flash_sync(dev) < 0) |
|
|
|
@ -104,27 +116,27 @@ static int mufs_do_free_page(struct mufs *fs, uint32_t base, |
|
|
|
|
uint32_t entry; |
|
|
|
|
size_t index; |
|
|
|
|
|
|
|
|
|
if (base == 0) |
|
|
|
|
if (!base) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
if (!depth) { |
|
|
|
|
if (depth == 0) { |
|
|
|
|
if (free_page) |
|
|
|
|
mufs_free_block(fs, base); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
index = va & ((1 << (fs->log2_nentries * (depth - 1))) - 1); |
|
|
|
|
base <<= dev->log2_block_size; |
|
|
|
|
index = mufs_get_index(fs, va, depth); |
|
|
|
|
base += index * sizeof entry; |
|
|
|
|
|
|
|
|
|
if (flash_read(fs->dev, (base << dev->log2_block_size) + index * |
|
|
|
|
sizeof entry, &entry, sizeof entry) == 0) |
|
|
|
|
if (flash_read(fs->dev, base, &entry, sizeof entry) == 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
if (mufs_do_free_page(fs, entry, depth - 1, va, free_page) < 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
if (flash_write0(fs->dev, (base << dev->log2_block_size) + index * |
|
|
|
|
sizeof entry, sizeof entry) == 0) |
|
|
|
|
if (flash_write0(fs->dev, base, sizeof entry) == 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
return flash_sync(fs->dev); |
|
|
|
|