]>
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 | ||
26 | #ifndef _SYS_SPACE_MAP_H | |
27 | #define _SYS_SPACE_MAP_H | |
28 | ||
34dc7c2f BB |
29 | #include <sys/avl.h> |
30 | #include <sys/dmu.h> | |
31 | ||
32 | #ifdef __cplusplus | |
33 | extern "C" { | |
34 | #endif | |
35 | ||
b01615d5 | 36 | typedef const struct space_map_ops space_map_ops_t; |
34dc7c2f BB |
37 | |
38 | typedef struct space_map { | |
39 | avl_tree_t sm_root; /* AVL tree of map segments */ | |
40 | uint64_t sm_space; /* sum of all segments in the map */ | |
41 | uint64_t sm_start; /* start of map */ | |
42 | uint64_t sm_size; /* size of map */ | |
43 | uint8_t sm_shift; /* unit shift */ | |
44 | uint8_t sm_pad[3]; /* unused */ | |
45 | uint8_t sm_loaded; /* map loaded? */ | |
46 | uint8_t sm_loading; /* map loading? */ | |
47 | kcondvar_t sm_load_cv; /* map load completion */ | |
48 | space_map_ops_t *sm_ops; /* space map block picker ops vector */ | |
9babb374 | 49 | avl_tree_t *sm_pp_root; /* picker-private AVL tree */ |
34dc7c2f BB |
50 | void *sm_ppd; /* picker-private data */ |
51 | kmutex_t *sm_lock; /* pointer to lock that protects map */ | |
52 | } space_map_t; | |
53 | ||
54 | typedef struct space_seg { | |
55 | avl_node_t ss_node; /* AVL node */ | |
9babb374 | 56 | avl_node_t ss_pp_node; /* AVL picker-private node */ |
34dc7c2f BB |
57 | uint64_t ss_start; /* starting offset of this segment */ |
58 | uint64_t ss_end; /* ending offset (non-inclusive) */ | |
59 | } space_seg_t; | |
60 | ||
fb5f0bc8 BB |
61 | typedef struct space_ref { |
62 | avl_node_t sr_node; /* AVL node */ | |
63 | uint64_t sr_offset; /* offset (start or end) */ | |
64 | int64_t sr_refcnt; /* associated reference count */ | |
65 | } space_ref_t; | |
66 | ||
34dc7c2f BB |
67 | typedef struct space_map_obj { |
68 | uint64_t smo_object; /* on-disk space map object */ | |
69 | uint64_t smo_objsize; /* size of the object */ | |
70 | uint64_t smo_alloc; /* space allocated from the map */ | |
71 | } space_map_obj_t; | |
72 | ||
73 | struct space_map_ops { | |
74 | void (*smop_load)(space_map_t *sm); | |
75 | void (*smop_unload)(space_map_t *sm); | |
76 | uint64_t (*smop_alloc)(space_map_t *sm, uint64_t size); | |
77 | void (*smop_claim)(space_map_t *sm, uint64_t start, uint64_t size); | |
78 | void (*smop_free)(space_map_t *sm, uint64_t start, uint64_t size); | |
9babb374 | 79 | uint64_t (*smop_max)(space_map_t *sm); |
428870ff | 80 | boolean_t (*smop_fragmented)(space_map_t *sm); |
34dc7c2f BB |
81 | }; |
82 | ||
83 | /* | |
84 | * debug entry | |
85 | * | |
86 | * 1 3 10 50 | |
87 | * ,---+--------+------------+---------------------------------. | |
88 | * | 1 | action | syncpass | txg (lower bits) | | |
89 | * `---+--------+------------+---------------------------------' | |
90 | * 63 62 60 59 50 49 0 | |
91 | * | |
92 | * | |
93 | * | |
94 | * non-debug entry | |
95 | * | |
96 | * 1 47 1 15 | |
97 | * ,-----------------------------------------------------------. | |
98 | * | 0 | offset (sm_shift units) | type | run | | |
99 | * `-----------------------------------------------------------' | |
100 | * 63 62 17 16 15 0 | |
101 | */ | |
102 | ||
103 | /* All this stuff takes and returns bytes */ | |
104 | #define SM_RUN_DECODE(x) (BF64_DECODE(x, 0, 15) + 1) | |
105 | #define SM_RUN_ENCODE(x) BF64_ENCODE((x) - 1, 0, 15) | |
106 | #define SM_TYPE_DECODE(x) BF64_DECODE(x, 15, 1) | |
107 | #define SM_TYPE_ENCODE(x) BF64_ENCODE(x, 15, 1) | |
108 | #define SM_OFFSET_DECODE(x) BF64_DECODE(x, 16, 47) | |
109 | #define SM_OFFSET_ENCODE(x) BF64_ENCODE(x, 16, 47) | |
110 | #define SM_DEBUG_DECODE(x) BF64_DECODE(x, 63, 1) | |
111 | #define SM_DEBUG_ENCODE(x) BF64_ENCODE(x, 63, 1) | |
112 | ||
113 | #define SM_DEBUG_ACTION_DECODE(x) BF64_DECODE(x, 60, 3) | |
114 | #define SM_DEBUG_ACTION_ENCODE(x) BF64_ENCODE(x, 60, 3) | |
115 | ||
116 | #define SM_DEBUG_SYNCPASS_DECODE(x) BF64_DECODE(x, 50, 10) | |
117 | #define SM_DEBUG_SYNCPASS_ENCODE(x) BF64_ENCODE(x, 50, 10) | |
118 | ||
119 | #define SM_DEBUG_TXG_DECODE(x) BF64_DECODE(x, 0, 50) | |
120 | #define SM_DEBUG_TXG_ENCODE(x) BF64_ENCODE(x, 0, 50) | |
121 | ||
122 | #define SM_RUN_MAX SM_RUN_DECODE(~0ULL) | |
123 | ||
124 | #define SM_ALLOC 0x0 | |
125 | #define SM_FREE 0x1 | |
126 | ||
127 | /* | |
128 | * The data for a given space map can be kept on blocks of any size. | |
129 | * Larger blocks entail fewer i/o operations, but they also cause the | |
130 | * DMU to keep more data in-core, and also to waste more i/o bandwidth | |
131 | * when only a few blocks have changed since the last transaction group. | |
132 | * This could use a lot more research, but for now, set the freelist | |
133 | * block size to 4k (2^12). | |
134 | */ | |
135 | #define SPACE_MAP_BLOCKSHIFT 12 | |
136 | ||
137 | typedef void space_map_func_t(space_map_t *sm, uint64_t start, uint64_t size); | |
138 | ||
139 | extern void space_map_create(space_map_t *sm, uint64_t start, uint64_t size, | |
140 | uint8_t shift, kmutex_t *lp); | |
141 | extern void space_map_destroy(space_map_t *sm); | |
142 | extern void space_map_add(space_map_t *sm, uint64_t start, uint64_t size); | |
143 | extern void space_map_remove(space_map_t *sm, uint64_t start, uint64_t size); | |
fb5f0bc8 BB |
144 | extern boolean_t space_map_contains(space_map_t *sm, |
145 | uint64_t start, uint64_t size); | |
34dc7c2f BB |
146 | extern void space_map_vacate(space_map_t *sm, |
147 | space_map_func_t *func, space_map_t *mdest); | |
148 | extern void space_map_walk(space_map_t *sm, | |
149 | space_map_func_t *func, space_map_t *mdest); | |
34dc7c2f BB |
150 | |
151 | extern void space_map_load_wait(space_map_t *sm); | |
152 | extern int space_map_load(space_map_t *sm, space_map_ops_t *ops, | |
153 | uint8_t maptype, space_map_obj_t *smo, objset_t *os); | |
154 | extern void space_map_unload(space_map_t *sm); | |
155 | ||
156 | extern uint64_t space_map_alloc(space_map_t *sm, uint64_t size); | |
157 | extern void space_map_claim(space_map_t *sm, uint64_t start, uint64_t size); | |
158 | extern void space_map_free(space_map_t *sm, uint64_t start, uint64_t size); | |
9babb374 | 159 | extern uint64_t space_map_maxsize(space_map_t *sm); |
34dc7c2f BB |
160 | |
161 | extern void space_map_sync(space_map_t *sm, uint8_t maptype, | |
162 | space_map_obj_t *smo, objset_t *os, dmu_tx_t *tx); | |
163 | extern void space_map_truncate(space_map_obj_t *smo, | |
164 | objset_t *os, dmu_tx_t *tx); | |
165 | ||
fb5f0bc8 BB |
166 | extern void space_map_ref_create(avl_tree_t *t); |
167 | extern void space_map_ref_destroy(avl_tree_t *t); | |
168 | extern void space_map_ref_add_seg(avl_tree_t *t, | |
169 | uint64_t start, uint64_t end, int64_t refcnt); | |
170 | extern void space_map_ref_add_map(avl_tree_t *t, | |
171 | space_map_t *sm, int64_t refcnt); | |
172 | extern void space_map_ref_generate_map(avl_tree_t *t, | |
173 | space_map_t *sm, int64_t minref); | |
174 | ||
34dc7c2f BB |
175 | #ifdef __cplusplus |
176 | } | |
177 | #endif | |
178 | ||
179 | #endif /* _SYS_SPACE_MAP_H */ |