| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: dm_dev.c,v 1.1.2.11 2008/10/16 23:26:42 haad Exp $ */ | | 1 | /* $NetBSD: dm_dev.c,v 1.1.2.12 2008/10/16 23:43:03 haad Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1996, 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1996, 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Adam Hamsik. | | 8 | * by Adam Hamsik. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -39,34 +39,36 @@ | | | @@ -39,34 +39,36 @@ |
39 | | | 39 | |
40 | #include "netbsd-dm.h" | | 40 | #include "netbsd-dm.h" |
41 | #include "dm.h" | | 41 | #include "dm.h" |
42 | | | 42 | |
43 | static struct dm_dev* dm_dev_lookup_name(const char *); | | 43 | static struct dm_dev* dm_dev_lookup_name(const char *); |
44 | static struct dm_dev* dm_dev_lookup_uuid(const char *); | | 44 | static struct dm_dev* dm_dev_lookup_uuid(const char *); |
45 | static struct dm_dev* dm_dev_lookup_minor(int); | | 45 | static struct dm_dev* dm_dev_lookup_minor(int); |
46 | | | 46 | |
47 | static struct dm_dev_head dm_dev_list = | | 47 | static struct dm_dev_head dm_dev_list = |
48 | TAILQ_HEAD_INITIALIZER(dm_dev_list); | | 48 | TAILQ_HEAD_INITIALIZER(dm_dev_list); |
49 | | | 49 | |
50 | kmutex_t dm_dev_mutex; | | 50 | kmutex_t dm_dev_mutex; |
51 | | | 51 | |
52 | #define DISABLE_DEV(dmv) do { \ | | 52 | __inline static void |
53 | TAILQ_REMOVE(&dm_dev_list, dmv, next_devlist); \ | | 53 | disable_dev(struct dm_dev *dmv) |
54 | mutex_enter(&dmv->dev_mtx); \ | | 54 | { |
55 | mutex_exit(&dm_dev_mutex); \ | | 55 | TAILQ_REMOVE(&dm_dev_list, dmv, next_devlist); |
56 | while(dmv->ref_cnt != 0) \ | | 56 | mutex_enter(&dmv->dev_mtx); |
57 | cv_wait(&dmv->dev_cv, &dmv->dev_mtx); \ | | 57 | mutex_exit(&dm_dev_mutex); |
58 | mutex_exit(&dmv->dev_mtx); \ | | 58 | while(dmv->ref_cnt != 0) |
59 | } while (/*CONSTCOND*/0) | | 59 | cv_wait(&dmv->dev_cv, &dmv->dev_mtx); |
| | | 60 | mutex_exit(&dmv->dev_mtx); |
| | | 61 | } |
60 | | | 62 | |
61 | /* | | 63 | /* |
62 | * Generic function used to lookup struct dm_dev. Calling with dm_dev_name | | 64 | * Generic function used to lookup struct dm_dev. Calling with dm_dev_name |
63 | * and dm_dev_uuid NULL is allowed. | | 65 | * and dm_dev_uuid NULL is allowed. |
64 | */ | | 66 | */ |
65 | struct dm_dev* | | 67 | struct dm_dev* |
66 | dm_dev_lookup(const char *dm_dev_name, const char *dm_dev_uuid, | | 68 | dm_dev_lookup(const char *dm_dev_name, const char *dm_dev_uuid, |
67 | int dm_dev_minor) | | 69 | int dm_dev_minor) |
68 | { | | 70 | { |
69 | struct dm_dev *dmv; | | 71 | struct dm_dev *dmv; |
70 | | | 72 | |
71 | dmv = NULL; | | 73 | dmv = NULL; |
72 | mutex_enter(&dm_dev_mutex); | | 74 | mutex_enter(&dm_dev_mutex); |
| @@ -93,210 +95,210 @@ dm_dev_lookup(const char *dm_dev_name, c | | | @@ -93,210 +95,210 @@ dm_dev_lookup(const char *dm_dev_name, c |
93 | return dmv; | | 95 | return dmv; |
94 | } | | 96 | } |
95 | mutex_exit(&dm_dev_mutex); | | 97 | mutex_exit(&dm_dev_mutex); |
96 | return NULL; | | 98 | return NULL; |
97 | } | | 99 | } |
98 | | | 100 | |
99 | | | 101 | |
100 | /* | | 102 | /* |
101 | * Lookup device with its minor number. | | 103 | * Lookup device with its minor number. |
102 | */ | | 104 | */ |
103 | static struct dm_dev* | | 105 | static struct dm_dev* |
104 | dm_dev_lookup_minor(int dm_dev_minor) | | 106 | dm_dev_lookup_minor(int dm_dev_minor) |
105 | { | | 107 | { |
106 | struct dm_dev *dm_dev; | | 108 | struct dm_dev *dmv; |
107 | | | 109 | |
108 | TAILQ_FOREACH(dm_dev, &dm_dev_list, next_devlist){ | | 110 | TAILQ_FOREACH(dmv, &dm_dev_list, next_devlist){ |
109 | if (dm_dev_minor == dm_dev->minor) | | 111 | if (dm_dev_minor == dmv->minor) |
110 | return dm_dev; | | 112 | return dmv; |
111 | } | | 113 | } |
112 | | | 114 | |
113 | return NULL; | | 115 | return NULL; |
114 | } | | 116 | } |
115 | | | 117 | |
116 | /* | | 118 | /* |
117 | * Lookup device with it's device name. | | 119 | * Lookup device with it's device name. |
118 | */ | | 120 | */ |
119 | static struct dm_dev* | | 121 | static struct dm_dev* |
120 | dm_dev_lookup_name(const char *dm_dev_name) | | 122 | dm_dev_lookup_name(const char *dm_dev_name) |
121 | { | | 123 | { |
122 | struct dm_dev *dm_dev; | | 124 | struct dm_dev *dmv; |
123 | int dlen; int slen; | | 125 | int dlen; int slen; |
124 | | | 126 | |
125 | slen = strlen(dm_dev_name); | | 127 | slen = strlen(dm_dev_name); |
126 | | | 128 | |
127 | if (slen == 0) | | 129 | if (slen == 0) |
128 | return NULL; | | 130 | return NULL; |
129 | | | 131 | |
130 | TAILQ_FOREACH(dm_dev, &dm_dev_list, next_devlist){ | | 132 | TAILQ_FOREACH(dmv, &dm_dev_list, next_devlist){ |
131 | | | 133 | |
132 | dlen = strlen(dm_dev->name); | | 134 | dlen = strlen(dmv->name); |
133 | | | 135 | |
134 | if(slen != dlen) | | 136 | if(slen != dlen) |
135 | continue; | | 137 | continue; |
136 | | | 138 | |
137 | if (strncmp(dm_dev_name, dm_dev->name, slen) == 0) | | 139 | if (strncmp(dm_dev_name, dmv->name, slen) == 0) |
138 | return dm_dev; | | 140 | return dmv; |
139 | } | | 141 | } |
140 | | | 142 | |
141 | return NULL; | | 143 | return NULL; |
142 | } | | 144 | } |
143 | | | 145 | |
144 | /* | | 146 | /* |
145 | * Lookup device with it's device uuid. Used mostly by LVM2tools. | | 147 | * Lookup device with it's device uuid. Used mostly by LVM2tools. |
146 | */ | | 148 | */ |
147 | static struct dm_dev* | | 149 | static struct dm_dev* |
148 | dm_dev_lookup_uuid(const char *dm_dev_uuid) | | 150 | dm_dev_lookup_uuid(const char *dm_dev_uuid) |
149 | { | | 151 | { |
150 | struct dm_dev *dm_dev; | | 152 | struct dm_dev *dmv; |
151 | size_t len; | | 153 | size_t len; |
152 | | | 154 | |
153 | len = 0; | | 155 | len = 0; |
154 | len = strlen(dm_dev_uuid); | | 156 | len = strlen(dm_dev_uuid); |
155 | | | 157 | |
156 | if (len == 0) | | 158 | if (len == 0) |
157 | return NULL; | | 159 | return NULL; |
158 | | | 160 | |
159 | TAILQ_FOREACH(dm_dev, &dm_dev_list, next_devlist){ | | 161 | TAILQ_FOREACH(dmv, &dm_dev_list, next_devlist){ |
160 | | | 162 | |
161 | if (strlen(dm_dev->uuid) != len) | | 163 | if (strlen(dmv->uuid) != len) |
162 | continue; | | 164 | continue; |
163 | | | 165 | |
164 | if (strncmp(dm_dev_uuid, dm_dev->uuid, strlen(dm_dev->uuid)) == 0) | | 166 | if (strncmp(dm_dev_uuid, dmv->uuid, strlen(dmv->uuid)) == 0) |
165 | return dm_dev; | | 167 | return dmv; |
166 | } | | 168 | } |
167 | | | 169 | |
168 | return NULL; | | 170 | return NULL; |
169 | } | | 171 | } |
170 | | | 172 | |
171 | /* | | 173 | /* |
172 | * Insert new device to the global list of devices. | | 174 | * Insert new device to the global list of devices. |
173 | */ | | 175 | */ |
174 | int | | 176 | int |
175 | dm_dev_insert(struct dm_dev *dev) | | 177 | dm_dev_insert(struct dm_dev *dev) |
176 | { | | 178 | { |
177 | struct dm_dev *dmt; | | 179 | struct dm_dev *dmv; |
178 | int r; | | 180 | int r; |
179 | | | 181 | |
180 | dmt = NULL; | | 182 | dmv = NULL; |
181 | r = 0; | | 183 | r = 0; |
182 | | | 184 | |
183 | KASSERT(dev != NULL); | | 185 | KASSERT(dev != NULL); |
184 | mutex_enter(&dm_dev_mutex); | | 186 | mutex_enter(&dm_dev_mutex); |
185 | if (((dmt = dm_dev_lookup_uuid(dev->uuid)) == NULL) && | | 187 | if (((dmv = dm_dev_lookup_uuid(dev->uuid)) == NULL) && |
186 | ((dmt = dm_dev_lookup_name(dev->name)) == NULL) && | | 188 | ((dmv = dm_dev_lookup_name(dev->name)) == NULL) && |
187 | ((dmt = dm_dev_lookup_minor(dev->minor)) == NULL)){ | | 189 | ((dmv = dm_dev_lookup_minor(dev->minor)) == NULL)){ |
188 | | | 190 | |
189 | TAILQ_INSERT_TAIL(&dm_dev_list, dev, next_devlist); | | 191 | TAILQ_INSERT_TAIL(&dm_dev_list, dev, next_devlist); |
190 | | | 192 | |
191 | } else | | 193 | } else |
192 | r = EEXIST; | | 194 | r = EEXIST; |
193 | | | 195 | |
194 | mutex_exit(&dm_dev_mutex); | | 196 | mutex_exit(&dm_dev_mutex); |
195 | return r; | | 197 | return r; |
196 | } | | 198 | } |
197 | | | 199 | |
198 | | | 200 | |
199 | | | 201 | |
200 | | | 202 | |
201 | /* | | 203 | /* |
202 | * Lookup device with its minor number. | | 204 | * Lookup device with its minor number. |
203 | */ | | 205 | */ |
204 | int | | 206 | int |
205 | dm_dev_test_minor(int dm_dev_minor) | | 207 | dm_dev_test_minor(int dm_dev_minor) |
206 | { | | 208 | { |
207 | struct dm_dev *dm_dev; | | 209 | struct dm_dev *dmv; |
208 | | | 210 | |
209 | mutex_enter(&dm_dev_mutex); | | 211 | mutex_enter(&dm_dev_mutex); |
210 | TAILQ_FOREACH(dm_dev, &dm_dev_list, next_devlist){ | | 212 | TAILQ_FOREACH(dmv, &dm_dev_list, next_devlist){ |
211 | if (dm_dev_minor == dm_dev->minor){ | | 213 | if (dm_dev_minor == dmv->minor){ |
212 | mutex_exit(&dm_dev_mutex); | | 214 | mutex_exit(&dm_dev_mutex); |
213 | return 1; | | 215 | return 1; |
214 | } | | 216 | } |
215 | } | | 217 | } |
216 | mutex_exit(&dm_dev_mutex); | | 218 | mutex_exit(&dm_dev_mutex); |
217 | | | 219 | |
218 | return 0; | | 220 | return 0; |
219 | } | | 221 | } |
220 | | | 222 | |
221 | /* | | 223 | /* |
222 | * Remove device selected with dm_dev from global list of devices. | | 224 | * Remove device selected with dm_dev from global list of devices. |
223 | */ | | 225 | */ |
224 | struct dm_dev* | | 226 | struct dm_dev* |
225 | dm_dev_rem(const char *dm_dev_name, const char *dm_dev_uuid, | | 227 | dm_dev_rem(const char *dm_dev_name, const char *dm_dev_uuid, |
226 | int dm_dev_minor) | | 228 | int dm_dev_minor) |
227 | { | | 229 | { |
228 | struct dm_dev *dmv; | | 230 | struct dm_dev *dmv; |
229 | dmv = NULL; | | 231 | dmv = NULL; |
230 | | | 232 | |
231 | mutex_enter(&dm_dev_mutex); | | 233 | mutex_enter(&dm_dev_mutex); |
232 | | | 234 | |
233 | if (dm_dev_minor > 0) | | 235 | if (dm_dev_minor > 0) |
234 | if ((dmv = dm_dev_lookup_minor(dm_dev_minor)) != NULL){ | | 236 | if ((dmv = dm_dev_lookup_minor(dm_dev_minor)) != NULL){ |
235 | DISABLE_DEV(dmv); | | 237 | disable_dev(dmv); |
236 | return dmv; | | 238 | return dmv; |
237 | } | | 239 | } |
238 | | | 240 | |
239 | if (dm_dev_name != NULL) | | 241 | if (dm_dev_name != NULL) |
240 | if ((dmv = dm_dev_lookup_name(dm_dev_name)) != NULL){ | | 242 | if ((dmv = dm_dev_lookup_name(dm_dev_name)) != NULL){ |
241 | DISABLE_DEV(dmv); | | 243 | disable_dev(dmv); |
242 | return dmv; | | 244 | return dmv; |
243 | } | | 245 | } |
244 | | | 246 | |
245 | if (dm_dev_uuid != NULL) | | 247 | if (dm_dev_uuid != NULL) |
246 | if ((dmv = dm_dev_lookup_name(dm_dev_uuid)) != NULL){ | | 248 | if ((dmv = dm_dev_lookup_name(dm_dev_uuid)) != NULL){ |
247 | DISABLE_DEV(dmv); | | 249 | disable_dev(dmv); |
248 | return dmv; | | 250 | return dmv; |
249 | } | | 251 | } |
250 | mutex_exit(&dm_dev_mutex); | | 252 | mutex_exit(&dm_dev_mutex); |
251 | | | 253 | |
252 | return NULL; | | 254 | return NULL; |
253 | } | | 255 | } |
254 | | | 256 | |
255 | /* | | 257 | /* |
256 | * Destroy all devices created in device-mapper. Remove all tables | | 258 | * Destroy all devices created in device-mapper. Remove all tables |
257 | * free all allocated memmory. | | 259 | * free all allocated memmory. |
258 | */ | | 260 | */ |
259 | int | | 261 | int |
260 | dm_dev_destroy(void) | | 262 | dm_dev_destroy(void) |
261 | { | | 263 | { |
262 | struct dm_dev *dm_dev; | | 264 | struct dm_dev *dmv; |
263 | mutex_enter(&dm_dev_mutex); | | 265 | mutex_enter(&dm_dev_mutex); |
264 | | | 266 | |
265 | while (TAILQ_FIRST(&dm_dev_list) != NULL){ | | 267 | while (TAILQ_FIRST(&dm_dev_list) != NULL){ |
266 | | | 268 | |
267 | dm_dev = TAILQ_FIRST(&dm_dev_list); | | 269 | dmv = TAILQ_FIRST(&dm_dev_list); |
268 | | | 270 | |
269 | TAILQ_REMOVE(&dm_dev_list, TAILQ_FIRST(&dm_dev_list), | | 271 | TAILQ_REMOVE(&dm_dev_list, TAILQ_FIRST(&dm_dev_list), |
270 | next_devlist); | | 272 | next_devlist); |
271 | | | 273 | |
272 | mutex_enter(&dm_dev->dev_mtx); | | 274 | mutex_enter(&dmv->dev_mtx); |
273 | | | 275 | |
274 | while (dm_dev->ref_cnt != 0) | | 276 | while (dmv->ref_cnt != 0) |
275 | cv_wait(&dm_dev->dev_cv, &dm_dev->dev_mtx); | | 277 | cv_wait(&dmv->dev_cv, &dmv->dev_mtx); |
276 | | | 278 | |
277 | /* Destroy active table first. */ | | 279 | /* Destroy active table first. */ |
278 | dm_table_destroy(&dm_dev->table_head, DM_TABLE_ACTIVE); | | 280 | dm_table_destroy(&dmv->table_head, DM_TABLE_ACTIVE); |
279 | | | 281 | |
280 | /* Destroy inactive table if exits, too. */ | | 282 | /* Destroy inactive table if exits, too. */ |
281 | dm_table_destroy(&dm_dev->table_head, DM_TABLE_INACTIVE); | | 283 | dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE); |
282 | | | 284 | |
283 | dm_table_head_destroy(&dm_dev->table_head); | | 285 | dm_table_head_destroy(&dmv->table_head); |
284 | | | 286 | |
285 | mutex_exit(&dm_dev->dev_mtx); | | 287 | mutex_exit(&dmv->dev_mtx); |
286 | mutex_destroy(&dm_dev->dev_mtx); | | 288 | mutex_destroy(&dmv->dev_mtx); |
287 | cv_destroy(&dm_dev->dev_cv); | | 289 | cv_destroy(&dmv->dev_cv); |
288 | | | 290 | |
289 | (void)kmem_free(dm_dev, sizeof(struct dm_dev)); | | 291 | (void)kmem_free(dmv, sizeof(struct dm_dev)); |
290 | } | | 292 | } |
291 | mutex_exit(&dm_dev_mutex); | | 293 | mutex_exit(&dm_dev_mutex); |
292 | | | 294 | |
293 | mutex_destroy(&dm_dev_mutex); | | 295 | mutex_destroy(&dm_dev_mutex); |
294 | return 0; | | 296 | return 0; |
295 | } | | 297 | } |
296 | | | 298 | |
297 | /* | | 299 | /* |
298 | * Allocate new device entry. | | 300 | * Allocate new device entry. |
299 | */ | | 301 | */ |
300 | struct dm_dev* | | 302 | struct dm_dev* |
301 | dm_dev_alloc() | | 303 | dm_dev_alloc() |
302 | { | | 304 | { |
| @@ -339,45 +341,45 @@ dm_dev_unbusy(struct dm_dev *dmv) | | | @@ -339,45 +341,45 @@ dm_dev_unbusy(struct dm_dev *dmv) |
339 | | | 341 | |
340 | mutex_enter(&dmv->dev_mtx); | | 342 | mutex_enter(&dmv->dev_mtx); |
341 | if (--dmv->ref_cnt == 0) | | 343 | if (--dmv->ref_cnt == 0) |
342 | cv_broadcast(&dmv->dev_cv); | | 344 | cv_broadcast(&dmv->dev_cv); |
343 | mutex_exit(&dmv->dev_mtx); | | 345 | mutex_exit(&dmv->dev_mtx); |
344 | } | | 346 | } |
345 | | | 347 | |
346 | /* | | 348 | /* |
347 | * Return prop_array of dm_targer_list dictionaries. | | 349 | * Return prop_array of dm_targer_list dictionaries. |
348 | */ | | 350 | */ |
349 | prop_array_t | | 351 | prop_array_t |
350 | dm_dev_prop_list(void) | | 352 | dm_dev_prop_list(void) |
351 | { | | 353 | { |
352 | struct dm_dev *dmd; | | 354 | struct dm_dev *dmv; |
353 | | | 355 | |
354 | int j; | | 356 | int j; |
355 | | | 357 | |
356 | prop_array_t dev_array; | | 358 | prop_array_t dev_array; |
357 | prop_dictionary_t dev_dict; | | 359 | prop_dictionary_t dev_dict; |
358 | | | 360 | |
359 | j =0; | | 361 | j =0; |
360 | | | 362 | |
361 | dev_array = prop_array_create(); | | 363 | dev_array = prop_array_create(); |
362 | | | 364 | |
363 | mutex_enter(&dm_dev_mutex); | | 365 | mutex_enter(&dm_dev_mutex); |
364 | | | 366 | |
365 | TAILQ_FOREACH(dmd, &dm_dev_list,next_devlist) { | | 367 | TAILQ_FOREACH(dmv, &dm_dev_list,next_devlist) { |
366 | dev_dict = prop_dictionary_create(); | | 368 | dev_dict = prop_dictionary_create(); |
367 | | | 369 | |
368 | prop_dictionary_set_cstring(dev_dict, DM_DEV_NAME, dmd->name); | | 370 | prop_dictionary_set_cstring(dev_dict, DM_DEV_NAME, dmv->name); |
369 | | | 371 | |
370 | prop_dictionary_set_uint32(dev_dict, DM_DEV_DEV, dmd->minor); | | 372 | prop_dictionary_set_uint32(dev_dict, DM_DEV_DEV, dmv->minor); |
371 | | | 373 | |
372 | prop_array_set(dev_array, j, dev_dict); | | 374 | prop_array_set(dev_array, j, dev_dict); |
373 | | | 375 | |
374 | prop_object_release(dev_dict); | | 376 | prop_object_release(dev_dict); |
375 | | | 377 | |
376 | j++; | | 378 | j++; |
377 | } | | 379 | } |
378 | | | 380 | |
379 | mutex_exit(&dm_dev_mutex); | | 381 | mutex_exit(&dm_dev_mutex); |
380 | return dev_array; | | 382 | return dev_array; |
381 | } | | 383 | } |
382 | | | 384 | |
383 | /* | | 385 | /* |