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