From 1d52ca46a634c844f6ab3e44e8cef365fde6b39d Mon Sep 17 00:00:00 2001 From: "S.J.R. van Schaik" Date: Mon, 12 Jun 2017 14:17:46 +0200 Subject: [PATCH] mufs: rework tree code to support mufs_map_page()/mufs_unmap_page() --- source/fs/mufs/tree.c | 42 ++++++++++++++++++++++++++++++++---------- source/fs/mufs/tree.h | 2 ++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/source/fs/mufs/tree.c b/source/fs/mufs/tree.c index 3e31293..2a3927a 100644 --- a/source/fs/mufs/tree.c +++ b/source/fs/mufs/tree.c @@ -13,7 +13,8 @@ #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) + uint32_t base, uint8_t depth, uint32_t va, uint32_t new_page, + unsigned alloc) { struct flash_dev *dev = fs->dev; char data[1 << dev->log2_block_size]; @@ -35,21 +36,35 @@ static int mufs_do_lookup(struct mufs *fs, uint32_t *page, index = va & ((1 << ((depth - 1) * fs->log2_nentries)) - 1); if (!table[index]) { - if (!alloc || mufs_alloc_block(fs, &table[index]) < 0) + if (depth > 1 && alloc && mufs_alloc_block(fs, &table[index]) < 0) return -1; + if (depth == 1 && new_page) + table[index] = new_page; + if (flash_write(dev, base << dev->log2_block_size, data, sizeof data) == 0) return -1; } - return mufs_do_lookup(fs, page, table[index], depth - 1, va, alloc); + return mufs_do_lookup(fs, page, table[index], depth - 1, va, new_page, + alloc); } int mufs_lookup_page(struct mufs_tree *tree, uint32_t *page, uint32_t va) { - return mufs_do_lookup(tree->fs, page, tree->root, tree->depth, va, 0); + return mufs_do_lookup(tree->fs, page, tree->root, tree->depth, va, 0, 0); +} + +int mufs_map_page(struct mufs_tree *tree, uint32_t va, uint32_t page) +{ + struct mufs *fs = tree->fs; + + if (!tree->root && mufs_alloc_block(fs, &tree->root) < 0) + return -1; + + return mufs_do_lookup(fs, &page, tree->root, tree->depth, va, page, 1); } int mufs_alloc_page(struct mufs_tree *tree, uint32_t *page, @@ -57,14 +72,14 @@ int mufs_alloc_page(struct mufs_tree *tree, uint32_t *page, { struct mufs *fs = tree->fs; - if (!tree->root && mufs_alloc_block(fs, &tree->root) < 0) + if (mufs_alloc_block(fs, page) < 0) return -1; - return mufs_do_lookup(fs, page, tree->root, tree->depth, va, 1); + return mufs_map_page(tree, va, *page); } static int mufs_do_free_page(struct mufs *fs, uint32_t base, - uint8_t depth, uint32_t va) + uint8_t depth, uint32_t va, int free_page) { struct flash_dev *dev = fs->dev; char data[1 << fs->dev->log2_block_size]; @@ -75,7 +90,9 @@ static int mufs_do_free_page(struct mufs *fs, uint32_t base, return -1; if (!depth) { - mufs_free_block(fs, base); + if (free_page) + mufs_free_block(fs, base); + return 0; } @@ -85,7 +102,7 @@ static int mufs_do_free_page(struct mufs *fs, uint32_t base, index = va & ((1 << (fs->log2_nentries * (depth - 1))) - 1); - if (mufs_do_free_page(fs, table[index], depth - 1, va) < 0) + if (mufs_do_free_page(fs, table[index], depth - 1, va, free_page) < 0) return -1; table[index] = 0; @@ -104,9 +121,14 @@ static int mufs_do_free_page(struct mufs *fs, uint32_t base, return mufs_free_block(fs, base); } +void mufs_unmap_page(struct mufs_tree *tree, uint32_t va) +{ + 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); + mufs_do_free_page(tree->fs, tree->root, tree->depth, va, 1); } int mufs_extend_tree(struct mufs_tree *tree, uint8_t depth) diff --git a/source/fs/mufs/tree.h b/source/fs/mufs/tree.h index 39c3602..bc3f0c6 100644 --- a/source/fs/mufs/tree.h +++ b/source/fs/mufs/tree.h @@ -2,6 +2,8 @@ int mufs_lookup_page(struct mufs_tree *tree, uint32_t *page, uint32_t va); +int mufs_map_page(struct mufs_tree *tree, uint32_t va, uint32_t page); +void mufs_unmap_page(struct mufs_tree *tree, uint32_t va); int mufs_alloc_page(struct mufs_tree *tree, uint32_t *page, uint32_t va); void mufs_free_page(struct mufs_tree *tree, uint32_t va);