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);