mufs: add code to lookup, allocate and free pages in file trees
This commit is contained in:
parent
88707097fb
commit
a88a33ef01
3 changed files with 110 additions and 0 deletions
1
Makefile
1
Makefile
|
@ -25,6 +25,7 @@ obj-y += source/core/flash.o
|
|||
|
||||
obj-y += source/fs/mufs/block.o
|
||||
obj-y += source/fs/mufs/super.o
|
||||
obj-y += source/fs/mufs/tree.o
|
||||
|
||||
obj-y += source/ftl/dev.o
|
||||
obj-y += source/ftl/ftl.o
|
||||
|
|
97
source/fs/mufs/tree.c
Normal file
97
source/fs/mufs/tree.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include <bitops.h>
|
||||
#include <flash.h>
|
||||
|
||||
#include <fs/mufs.h>
|
||||
|
||||
#include "block.h"
|
||||
#include "tree.h"
|
||||
|
||||
static int mufs_do_lookup(struct mufs *fs, uint32_t *page,
|
||||
uint32_t base, uint8_t depth, uint32_t va, unsigned alloc)
|
||||
{
|
||||
char data[1 << fs->dev->log2_block_size];
|
||||
uint32_t *table = (uint32_t *)data;
|
||||
size_t index;
|
||||
uint8_t log2_nentries = fs->dev->log2_block_size - ilog2(sizeof(uint32_t));
|
||||
|
||||
if (!base)
|
||||
return -1;
|
||||
|
||||
if (!depth) {
|
||||
*page = base;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flash_read(fs->dev, base << fs->dev->log2_block_size, data,
|
||||
sizeof data) == 0)
|
||||
return -1;
|
||||
|
||||
index = va & ((1 << (log2_nentries * (depth - 1))) - 1);
|
||||
|
||||
if (!table[index]) {
|
||||
if (!alloc || mufs_alloc_block(fs, &table[index]) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return mufs_do_lookup(fs, page, table[index], depth - 1, va, alloc);
|
||||
}
|
||||
|
||||
int mufs_lookup_page(struct mufs *fs, struct mufs_tree *tree, uint32_t *page,
|
||||
uint32_t va)
|
||||
{
|
||||
return mufs_do_lookup(fs, page, tree->base, tree->depth, va, 0);
|
||||
}
|
||||
|
||||
int mufs_alloc_page(struct mufs *fs, struct mufs_tree *tree, uint32_t *page,
|
||||
uint32_t va)
|
||||
{
|
||||
return mufs_do_lookup(fs, page, tree->base, tree->depth, va, 1);
|
||||
}
|
||||
|
||||
static int mufs_do_free_page(struct mufs *fs, uint32_t base,
|
||||
uint8_t depth, uint32_t va)
|
||||
{
|
||||
char data[1 << fs->dev->log2_block_size];
|
||||
uint32_t *table = (uint32_t *)data;
|
||||
size_t index;
|
||||
uint8_t log2_nentries = fs->dev->log2_block_size - ilog2(sizeof(uint32_t));
|
||||
|
||||
if (!base)
|
||||
return -1;
|
||||
|
||||
if (!depth) {
|
||||
mufs_free_block(fs, base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flash_read(fs->dev, base << fs->dev->log2_block_size, data,
|
||||
sizeof data) == 0)
|
||||
return -1;
|
||||
|
||||
index = va & ((1 << (log2_nentries * (depth - 1))) - 1);
|
||||
|
||||
if (mufs_do_free_page(fs, table[index], depth - 1, va) < 0)
|
||||
return -1;
|
||||
|
||||
table[index] = 0;
|
||||
|
||||
for (index = 0; index < (UINT32_C(1) << log2_nentries); ++index) {
|
||||
if (!table[index])
|
||||
continue;
|
||||
|
||||
if (flash_write(fs->dev, base << fs->dev->log2_block_size, data,
|
||||
sizeof data) == 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mufs_free_block(fs, base);
|
||||
}
|
||||
|
||||
void mufs_free_page(struct mufs *fs, struct mufs_tree *tree, uint32_t va)
|
||||
{
|
||||
mufs_do_free_page(fs, tree->base, tree->depth, va);
|
||||
}
|
12
source/fs/mufs/tree.h
Normal file
12
source/fs/mufs/tree.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
struct mufs_tree {
|
||||
uint32_t base;
|
||||
uint8_t depth;
|
||||
};
|
||||
|
||||
int mufs_lookup_page(struct mufs *fs, struct mufs_tree *tree, uint32_t *page,
|
||||
uint32_t va);
|
||||
int mufs_alloc_page(struct mufs *fs, struct mufs_tree *tree, uint32_t *page,
|
||||
uint32_t va);
|
||||
void mufs_free_page(struct mufs *fs, struct mufs_tree *tree, uint32_t va);
|
Loading…
Add table
Reference in a new issue