1 /* 2 * Copyright (C) 2007 Oracle. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public 6 * License v2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public 14 * License along with this program; if not, write to the 15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 * Boston, MA 021110-1307, USA. 17 */ 18 19 /// D translation of extent-cache.h from btrfs-progs (v5.9) 20 module btrfs.c.common.extent_cache; 21 22 import btrfs.c.kernel_lib.rbtree; 23 import btrfs.c.kerncompat; 24 25 extern(C): 26 27 struct cache_tree { 28 rb_root root; 29 } 30 31 struct cache_extent { 32 .rb_node rb_node; 33 u64 objectid; 34 u64 start; 35 u64 size; 36 } 37 38 void cache_tree_init(cache_tree *tree); 39 40 cache_extent *first_cache_extent(cache_tree *tree); 41 cache_extent *last_cache_extent(cache_tree *tree); 42 cache_extent *prev_cache_extent(cache_extent *pe); 43 cache_extent *next_cache_extent(cache_extent *pe); 44 45 /* 46 * Find a cache_extent which covers start. 47 * 48 * If not found, return next cache_extent if possible. 49 */ 50 cache_extent *search_cache_extent(cache_tree *tree, u64 start); 51 52 /* 53 * Find a cache_extent which restrictly covers start. 54 * 55 * If not found, return NULL. 56 */ 57 cache_extent *lookup_cache_extent(cache_tree *tree, 58 u64 start, u64 size); 59 60 /* 61 * Add an non-overlap extent into cache tree 62 * 63 * If [start, start+size) overlap with existing one, it will return -EEXIST. 64 */ 65 int add_cache_extent(cache_tree *tree, u64 start, u64 size); 66 67 /* 68 * Same with add_cache_extent, but with cache_extent strcut. 69 */ 70 int insert_cache_extent(cache_tree *tree, cache_extent *pe); 71 void remove_cache_extent(cache_tree *tree, cache_extent *pe); 72 73 int cache_tree_empty()(cache_tree *tree) 74 { 75 return RB_EMPTY_ROOT(&tree.root); 76 } 77 78 alias free_cache_extent = void function(cache_extent *pe); 79 80 void cache_tree_free_extents(cache_tree *tree, 81 free_cache_extent free_func); 82 83 mixin template FREE_EXTENT_CACHE_BASED_TREE(string name, alias free_func) 84 { 85 mixin(`void free_` ~ name ~ `_tree(cache_tree *tree) 86 { 87 cache_tree_free_extents(tree, free_func); 88 } 89 `); 90 } 91 92 void free_extent_cache_tree(cache_tree *tree); 93 94 /* 95 * Search a cache_extent with same objectid, and covers start. 96 * 97 * If not found, return next if possible. 98 */ 99 cache_extent *search_cache_extent2(cache_tree *tree, 100 u64 objectid, u64 start); 101 /* 102 * Search a cache_extent with same objectid, and covers the range 103 * [start, start + size) 104 * 105 * If not found, return next cache_extent if possible. 106 */ 107 cache_extent *lookup_cache_extent2(cache_tree *tree, 108 u64 objectid, u64 start, u64 size); 109 int insert_cache_extent2(cache_tree *tree, cache_extent *pe); 110 111 /* 112 * Insert a cache_extent range [start, start + size). 113 * 114 * This function may merge with existing cache_extent. 115 * NOTE: caller must ensure the inserted range won't cover with any existing 116 * range. 117 */ 118 int add_merge_cache_extent(cache_tree *tree, u64 start, u64 size);