From ba12823d8b720fbf718458cc9415bf64f4b9ee89 Mon Sep 17 00:00:00 2001 From: "S.J.R. van Schaik" Date: Mon, 29 May 2017 14:57:13 +0200 Subject: [PATCH] mufs: add mufs_shrink_tree() to shrink a file tree to a specific size in terms of VAS --- source/fs/mufs/tree.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ source/fs/mufs/tree.h | 1 + 2 files changed, 45 insertions(+) diff --git a/source/fs/mufs/tree.c b/source/fs/mufs/tree.c index 5f7c697..1e26c5a 100644 --- a/source/fs/mufs/tree.c +++ b/source/fs/mufs/tree.c @@ -116,3 +116,47 @@ int mufs_extend_tree(struct mufs *fs, struct mufs_tree *tree, uint8_t depth) return 0; } + +int mufs_shrink_tree(struct mufs *fs, struct mufs_tree *tree, uint32_t max_size) +{ + char data[1 << fs->dev->log2_block_size]; + uint32_t *table = (uint32_t *)data; + size_t index; + uint32_t base, size; + uint8_t log2_nentries = fs->dev->log2_block_size - ilog2(sizeof(uint32_t)); + uint8_t depth; + + base = tree->root; + + for (depth = tree->depth; depth; --depth) { + size = 1 << (depth * log2_nentries + fs->dev->log2_block_size); + + if (size < max_size) + return 0; + + index = max_size >> ((depth - 1) * log2_nentries + + fs->dev->log2_block_size); + + if (flash_read(fs->dev, base, data, sizeof data) == 0) + return -1; + + if (index <= 1) { + tree->root = table[0]; + --tree->depth; + + mufs_free_block(fs, base); + + continue; + } + + for (; index < (UINT32_C(1) << log2_nentries); ++index) { + table[index] = 0; + } + + if (flash_write(fs->dev, base << fs->dev->log2_block_size, data, + sizeof data) == 0) + return -1; + } + + return 0; +} diff --git a/source/fs/mufs/tree.h b/source/fs/mufs/tree.h index 45650a4..4d6a801 100644 --- a/source/fs/mufs/tree.h +++ b/source/fs/mufs/tree.h @@ -6,3 +6,4 @@ 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); int mufs_extend_tree(struct mufs *fs, struct mufs_tree *tree, uint8_t depth); +int mufs_shrink_tree(struct mufs *fs, struct mufs_tree *tree, uint32_t max_size);