| /* |
| * Copyright (C) 2015-2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include <stdbool.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include <lk/list.h> |
| |
| #include "block_cache.h" |
| #include "block_range.h" |
| #include "block_tree.h" |
| |
| extern bool print_lookup; /* TODO: remove */ |
| |
| #define BLOCK_SET_MAX_DEPTH (BLOCK_TREE_MAX_DEPTH) |
| |
| /** |
| * struct block_set - In-memory state of B+ tree backed block set |
| * @node: List node used to link transaction allocated sets in fs. |
| * @block_tree: Block tree state. |
| * @inserting_range: Block range added to set but not yet in @block_tree. |
| * @updating: %true while updating the set, %false otherwise. If a |
| * set insert or remove operation is re-entered while |
| * @updating is %true, the update is only applied to |
| * @inserting_range/@removing_range. |
| * |
| * In-memory state of B+ tree backed block set. Blocks that are part of the |
| * block-set are tracked as ranges. A range is stored in @block_tree with the |
| * start values as the key and the end value as the data. Unless an update is |
| * in progress, all ranges in @block_tree are non-overlapping, and non-adjacent. |
| * For instance, a block set containing only block 1 and 3 will be stored as two |
| * ranges in @block_tree. Adding block 2 to this block-set will cause those two |
| * ranges to be merged into a single range covering block 1 through 3. |
| */ |
| struct block_set { |
| struct list_node node; |
| struct block_tree block_tree; |
| struct block_range initial_range; |
| bool updating; |
| }; |
| |
| #define BLOCK_SET_INITIAL_VALUE(block_set) \ |
| { \ |
| .node = LIST_INITIAL_CLEARED_VALUE, \ |
| .block_tree = BLOCK_TREE_INITIAL_VALUE(block_set.block_tree), \ |
| .initial_range = BLOCK_RANGE_INITIAL_VALUE(block_set.initial_range), \ |
| .updating = 0, \ |
| } |
| |
| struct transaction; |
| struct fs; |
| |
| void block_set_print(struct transaction* tr, struct block_set* set); |
| bool block_set_check(struct transaction* tr, struct block_set* set); |
| |
| bool block_set_block_in_set(struct transaction* tr, |
| struct block_set* set, |
| data_block_t block); |
| bool block_set_range_in_set(struct transaction* tr, |
| struct block_set* set, |
| struct block_range range); |
| bool block_set_range_not_in_set(struct transaction* tr, |
| struct block_set* set, |
| struct block_range range); |
| |
| data_block_t block_set_find_next_block(struct transaction* tr, |
| struct block_set* set, |
| data_block_t min_block, |
| bool in_set); |
| |
| struct block_range block_set_find_next_range(struct transaction* tr, |
| struct block_set* set, |
| data_block_t min_block); |
| |
| bool block_set_overlap(struct transaction* tr, |
| struct block_set* set_a, |
| struct block_set* set_b); |
| |
| void block_set_add_range(struct transaction* tr, |
| struct block_set* set, |
| struct block_range range); |
| |
| void block_set_add_block(struct transaction* tr, |
| struct block_set* set, |
| data_block_t block); |
| |
| void block_set_remove_range(struct transaction* tr, |
| struct block_set* set, |
| struct block_range range); |
| |
| void block_set_remove_block(struct transaction* tr, |
| struct block_set* set, |
| data_block_t block); |
| |
| void block_set_init(struct fs* fs, struct block_set* set); |
| |
| void block_set_add_initial_range(struct block_set* set, |
| struct block_range range); |
| |
| void block_set_copy(struct transaction* tr, |
| struct block_set* dest, |
| const struct block_set* src); |
| |
| void block_set_copy_ro_fs(struct fs* fs, |
| struct block_set* dest, |
| const struct block_set* src); |
| |
| void block_set_copy_ro(struct transaction* tr, |
| struct block_set* dest, |
| const struct block_set* src); |