]>
Commit | Line | Data |
---|---|---|
34dc7c2f BB |
1 | /* |
2 | * CDDL HEADER START | |
3 | * | |
4 | * The contents of this file are subject to the terms of the | |
5 | * Common Development and Distribution License (the "License"). | |
6 | * You may not use this file except in compliance with the License. | |
7 | * | |
8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 | * or http://www.opensolaris.org/os/licensing. | |
10 | * See the License for the specific language governing permissions | |
11 | * and limitations under the License. | |
12 | * | |
13 | * When distributing Covered Code, include this CDDL HEADER in each | |
14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 | * If applicable, add the following below this CDDL HEADER, with the | |
16 | * fields enclosed by brackets "[]" replaced with your own identifying | |
17 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 | * | |
19 | * CDDL HEADER END | |
20 | */ | |
21 | /* | |
9babb374 | 22 | * Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
34dc7c2f BB |
23 | * Use is subject to license terms. |
24 | */ | |
25 | ||
55d85d5a GW |
26 | /* |
27 | * Copyright (c) 2012 by Delphix. All rights reserved. | |
28 | */ | |
29 | ||
34dc7c2f BB |
30 | #ifndef _SYS_SPACE_MAP_H |
31 | #define _SYS_SPACE_MAP_H | |
32 | ||
34dc7c2f BB |
33 | #include <sys/avl.h> |
34 | #include <sys/dmu.h> | |
35 | ||
36 | #ifdef __cplusplus | |
37 | extern "C" { | |
38 | #endif | |
39 | ||
b01615d5 | 40 | typedef const struct space_map_ops space_map_ops_t; |
34dc7c2f BB |
41 | |
42 | typedef struct space_map { | |
e51be066 | 43 | avl_tree_t sm_root; /* offset-ordered segment AVL tree */ |
34dc7c2f BB |
44 | uint64_t sm_space; /* sum of all segments in the map */ |
45 | uint64_t sm_start; /* start of map */ | |
46 | uint64_t sm_size; /* size of map */ | |
47 | uint8_t sm_shift; /* unit shift */ | |
34dc7c2f BB |
48 | uint8_t sm_loaded; /* map loaded? */ |
49 | uint8_t sm_loading; /* map loading? */ | |
e51be066 | 50 | uint8_t sm_condensing; /* map condensing? */ |
34dc7c2f BB |
51 | kcondvar_t sm_load_cv; /* map load completion */ |
52 | space_map_ops_t *sm_ops; /* space map block picker ops vector */ | |
e51be066 | 53 | avl_tree_t *sm_pp_root; /* size-ordered, picker-private tree */ |
34dc7c2f BB |
54 | void *sm_ppd; /* picker-private data */ |
55 | kmutex_t *sm_lock; /* pointer to lock that protects map */ | |
56 | } space_map_t; | |
57 | ||
58 | typedef struct space_seg { | |
59 | avl_node_t ss_node; /* AVL node */ | |
9babb374 | 60 | avl_node_t ss_pp_node; /* AVL picker-private node */ |
34dc7c2f BB |
61 | uint64_t ss_start; /* starting offset of this segment */ |
62 | uint64_t ss_end; /* ending offset (non-inclusive) */ | |
63 | } space_seg_t; | |
64 | ||
fb5f0bc8 BB |
65 | typedef struct space_ref { |
66 | avl_node_t sr_node; /* AVL node */ | |
67 | uint64_t sr_offset; /* offset (start or end) */ | |
68 | int64_t sr_refcnt; /* associated reference count */ | |
69 | } space_ref_t; | |
70 | ||
34dc7c2f BB |
71 | typedef struct space_map_obj { |
72 | uint64_t smo_object; /* on-disk space map object */ | |
73 | uint64_t smo_objsize; /* size of the object */ | |
74 | uint64_t smo_alloc; /* space allocated from the map */ | |
75 | } space_map_obj_t; | |
76 | ||
77 | struct space_map_ops { | |
78 | void (*smop_load)(space_map_t *sm); | |
79 | void (*smop_unload)(space_map_t *sm); | |
80 | uint64_t (*smop_alloc)(space_map_t *sm, uint64_t size); | |
81 | void (*smop_claim)(space_map_t *sm, uint64_t start, uint64_t size); | |
82 | void (*smop_free)(space_map_t *sm, uint64_t start, uint64_t size); | |
9babb374 | 83 | uint64_t (*smop_max)(space_map_t *sm); |
428870ff | 84 | boolean_t (*smop_fragmented)(space_map_t *sm); |
34dc7c2f BB |
85 | }; |
86 | ||
87 | /* | |
88 | * debug entry | |
89 | * | |
90 | * 1 3 10 50 | |
91 | * ,---+--------+------------+---------------------------------. | |
92 | * | 1 | action | syncpass | txg (lower bits) | | |
93 | * `---+--------+------------+---------------------------------' | |
94 | * 63 62 60 59 50 49 0 | |
95 | * | |
96 | * | |
97 | * | |
98 | * non-debug entry | |
99 | * | |
100 | * 1 47 1 15 | |
101 | * ,-----------------------------------------------------------. | |
102 | * | 0 | offset (sm_shift units) | type | run | | |
103 | * `-----------------------------------------------------------' | |
104 | * 63 62 17 16 15 0 | |
105 | */ | |
106 | ||
107 | /* All this stuff takes and returns bytes */ | |
108 | #define SM_RUN_DECODE(x) (BF64_DECODE(x, 0, 15) + 1) | |
109 | #define SM_RUN_ENCODE(x) BF64_ENCODE((x) - 1, 0, 15) | |
110 | #define SM_TYPE_DECODE(x) BF64_DECODE(x, 15, 1) | |
111 | #define SM_TYPE_ENCODE(x) BF64_ENCODE(x, 15, 1) | |
112 | #define SM_OFFSET_DECODE(x) BF64_DECODE(x, 16, 47) | |
113 | #define SM_OFFSET_ENCODE(x) BF64_ENCODE(x, 16, 47) | |
114 | #define SM_DEBUG_DECODE(x) BF64_DECODE(x, 63, 1) | |
115 | #define SM_DEBUG_ENCODE(x) BF64_ENCODE(x, 63, 1) | |
116 | ||
117 | #define SM_DEBUG_ACTION_DECODE(x) BF64_DECODE(x, 60, 3) | |
118 | #define SM_DEBUG_ACTION_ENCODE(x) BF64_ENCODE(x, 60, 3) | |
119 | ||
120 | #define SM_DEBUG_SYNCPASS_DECODE(x) BF64_DECODE(x, 50, 10) | |
121 | #define SM_DEBUG_SYNCPASS_ENCODE(x) BF64_ENCODE(x, 50, 10) | |
122 | ||
123 | #define SM_DEBUG_TXG_DECODE(x) BF64_DECODE(x, 0, 50) | |
124 | #define SM_DEBUG_TXG_ENCODE(x) BF64_ENCODE(x, 0, 50) | |
125 | ||
126 | #define SM_RUN_MAX SM_RUN_DECODE(~0ULL) | |
127 | ||
128 | #define SM_ALLOC 0x0 | |
129 | #define SM_FREE 0x1 | |
130 | ||
131 | /* | |
132 | * The data for a given space map can be kept on blocks of any size. | |
133 | * Larger blocks entail fewer i/o operations, but they also cause the | |
134 | * DMU to keep more data in-core, and also to waste more i/o bandwidth | |
135 | * when only a few blocks have changed since the last transaction group. | |
136 | * This could use a lot more research, but for now, set the freelist | |
137 | * block size to 4k (2^12). | |
138 | */ | |
139 | #define SPACE_MAP_BLOCKSHIFT 12 | |
140 | ||
141 | typedef void space_map_func_t(space_map_t *sm, uint64_t start, uint64_t size); | |
142 | ||
55d85d5a GW |
143 | extern void space_map_init(void); |
144 | extern void space_map_fini(void); | |
34dc7c2f BB |
145 | extern void space_map_create(space_map_t *sm, uint64_t start, uint64_t size, |
146 | uint8_t shift, kmutex_t *lp); | |
147 | extern void space_map_destroy(space_map_t *sm); | |
148 | extern void space_map_add(space_map_t *sm, uint64_t start, uint64_t size); | |
149 | extern void space_map_remove(space_map_t *sm, uint64_t start, uint64_t size); | |
fb5f0bc8 BB |
150 | extern boolean_t space_map_contains(space_map_t *sm, |
151 | uint64_t start, uint64_t size); | |
13fe0198 MA |
152 | extern space_seg_t *space_map_find(space_map_t *sm, uint64_t start, |
153 | uint64_t size, avl_index_t *wherep); | |
e51be066 | 154 | extern void space_map_swap(space_map_t **msrc, space_map_t **mdest); |
34dc7c2f BB |
155 | extern void space_map_vacate(space_map_t *sm, |
156 | space_map_func_t *func, space_map_t *mdest); | |
157 | extern void space_map_walk(space_map_t *sm, | |
158 | space_map_func_t *func, space_map_t *mdest); | |
34dc7c2f BB |
159 | |
160 | extern void space_map_load_wait(space_map_t *sm); | |
161 | extern int space_map_load(space_map_t *sm, space_map_ops_t *ops, | |
162 | uint8_t maptype, space_map_obj_t *smo, objset_t *os); | |
163 | extern void space_map_unload(space_map_t *sm); | |
164 | ||
165 | extern uint64_t space_map_alloc(space_map_t *sm, uint64_t size); | |
166 | extern void space_map_claim(space_map_t *sm, uint64_t start, uint64_t size); | |
167 | extern void space_map_free(space_map_t *sm, uint64_t start, uint64_t size); | |
9babb374 | 168 | extern uint64_t space_map_maxsize(space_map_t *sm); |
34dc7c2f BB |
169 | |
170 | extern void space_map_sync(space_map_t *sm, uint8_t maptype, | |
171 | space_map_obj_t *smo, objset_t *os, dmu_tx_t *tx); | |
172 | extern void space_map_truncate(space_map_obj_t *smo, | |
173 | objset_t *os, dmu_tx_t *tx); | |
174 | ||
fb5f0bc8 BB |
175 | extern void space_map_ref_create(avl_tree_t *t); |
176 | extern void space_map_ref_destroy(avl_tree_t *t); | |
177 | extern void space_map_ref_add_seg(avl_tree_t *t, | |
178 | uint64_t start, uint64_t end, int64_t refcnt); | |
179 | extern void space_map_ref_add_map(avl_tree_t *t, | |
180 | space_map_t *sm, int64_t refcnt); | |
181 | extern void space_map_ref_generate_map(avl_tree_t *t, | |
182 | space_map_t *sm, int64_t minref); | |
183 | ||
34dc7c2f BB |
184 | #ifdef __cplusplus |
185 | } | |
186 | #endif | |
187 | ||
188 | #endif /* _SYS_SPACE_MAP_H */ |