| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: dm_ioctl.c,v 1.56 2022/10/13 06:10:48 andvar Exp $ */ | | 1 | /* $NetBSD: dm_ioctl.c,v 1.57 2024/01/14 07:56:53 mlelstv Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2008 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. |
| @@ -19,27 +19,27 @@ | | | @@ -19,27 +19,27 @@ |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | #include <sys/cdefs.h> | | 31 | #include <sys/cdefs.h> |
32 | __KERNEL_RCSID(0, "$NetBSD: dm_ioctl.c,v 1.56 2022/10/13 06:10:48 andvar Exp $"); | | 32 | __KERNEL_RCSID(0, "$NetBSD: dm_ioctl.c,v 1.57 2024/01/14 07:56:53 mlelstv Exp $"); |
33 | | | 33 | |
34 | /* | | 34 | /* |
35 | * Locking is used to synchronise between ioctl calls and between dm_table's | | 35 | * Locking is used to synchronise between ioctl calls and between dm_table's |
36 | * users. | | 36 | * users. |
37 | * | | 37 | * |
38 | * ioctl locking: | | 38 | * ioctl locking: |
39 | * Simple reference counting, to count users of device will be used routines | | 39 | * Simple reference counting, to count users of device will be used routines |
40 | * dm_dev_busy/dm_dev_unbusy are used for that. | | 40 | * dm_dev_busy/dm_dev_unbusy are used for that. |
41 | * dm_dev_lookup/dm_dev_rem call dm_dev_busy before return(caller is therefore | | 41 | * dm_dev_lookup/dm_dev_rem call dm_dev_busy before return(caller is therefore |
42 | * holder of reference_counter last). | | 42 | * holder of reference_counter last). |
43 | * | | 43 | * |
44 | * ioctl routines which change/remove dm_dev parameters must wait on | | 44 | * ioctl routines which change/remove dm_dev parameters must wait on |
45 | * dm_dev::dev_cv and when last user will call dm_dev_unbusy they will wake | | 45 | * dm_dev::dev_cv and when last user will call dm_dev_unbusy they will wake |
| @@ -199,65 +199,68 @@ dm_dev_create_ioctl(prop_dictionary_t dm | | | @@ -199,65 +199,68 @@ dm_dev_create_ioctl(prop_dictionary_t dm |
199 | /* Get needed values from dictionary. */ | | 199 | /* Get needed values from dictionary. */ |
200 | prop_dictionary_get_string(dm_dict, DM_IOCTL_NAME, &name); | | 200 | prop_dictionary_get_string(dm_dict, DM_IOCTL_NAME, &name); |
201 | prop_dictionary_get_string(dm_dict, DM_IOCTL_UUID, &uuid); | | 201 | prop_dictionary_get_string(dm_dict, DM_IOCTL_UUID, &uuid); |
202 | prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); | | 202 | prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); |
203 | | | 203 | |
204 | dm_dbg_print_flags(flags); | | 204 | dm_dbg_print_flags(flags); |
205 | | | 205 | |
206 | /* Lookup name and uuid if device already exist quit. */ | | 206 | /* Lookup name and uuid if device already exist quit. */ |
207 | if ((dmv = dm_dev_lookup(name, uuid, -1)) != NULL) { | | 207 | if ((dmv = dm_dev_lookup(name, uuid, -1)) != NULL) { |
208 | DM_ADD_FLAG(flags, DM_EXISTS_FLAG); /* Device already exists */ | | 208 | DM_ADD_FLAG(flags, DM_EXISTS_FLAG); /* Device already exists */ |
209 | dm_dev_unbusy(dmv); | | 209 | dm_dev_unbusy(dmv); |
210 | return EEXIST; | | 210 | return EEXIST; |
211 | } | | 211 | } |
| | | 212 | |
| | | 213 | if ((dmv = dm_dev_alloc()) == NULL) |
| | | 214 | return ENOMEM; |
| | | 215 | |
212 | cf = kmem_alloc(sizeof(*cf), KM_SLEEP); | | 216 | cf = kmem_alloc(sizeof(*cf), KM_SLEEP); |
213 | cf->cf_name = dm_cd.cd_name; | | 217 | cf->cf_name = dm_cd.cd_name; |
214 | cf->cf_atname = dm_ca.ca_name; | | 218 | cf->cf_atname = dm_ca.ca_name; |
215 | cf->cf_unit = atomic_inc_32_nv(&sc_minor_num); | | 219 | cf->cf_unit = atomic_inc_32_nv(&sc_minor_num); |
216 | cf->cf_fstate = FSTATE_NOTFOUND; | | 220 | cf->cf_fstate = FSTATE_NOTFOUND; |
217 | if ((devt = config_attach_pseudo(cf)) == NULL) { | | 221 | if ((devt = config_attach_pseudo(cf)) == NULL) { |
| | | 222 | dm_dev_free(dmv); |
218 | kmem_free(cf, sizeof(*cf)); | | 223 | kmem_free(cf, sizeof(*cf)); |
219 | aprint_error("Unable to attach pseudo device dm/%s\n", name); | | 224 | aprint_error("Unable to attach pseudo device dm/%s\n", name); |
220 | return (ENOMEM); | | 225 | return (ENOMEM); |
221 | } | | 226 | } |
222 | if ((dmv = dm_dev_alloc()) == NULL) | | | |
223 | return ENOMEM; | | | |
224 | | | 227 | |
225 | if (uuid) | | 228 | if (uuid) |
226 | strncpy(dmv->uuid, uuid, DM_UUID_LEN); | | 229 | strncpy(dmv->uuid, uuid, DM_UUID_LEN); |
227 | else | | 230 | else |
228 | dmv->uuid[0] = '\0'; | | 231 | dmv->uuid[0] = '\0'; |
229 | | | 232 | |
230 | if (name) | | 233 | if (name) |
231 | strlcpy(dmv->name, name, DM_NAME_LEN); | | 234 | strlcpy(dmv->name, name, DM_NAME_LEN); |
232 | | | 235 | |
233 | dmv->minor = cf->cf_unit; | | 236 | dmv->minor = cf->cf_unit; |
234 | dmv->flags = 0; /* device flags are set when needed */ | | 237 | dmv->flags = 0; /* device flags are set when needed */ |
235 | dmv->ref_cnt = 0; | | 238 | dmv->ref_cnt = 0; |
236 | dmv->event_nr = 0; | | 239 | dmv->event_nr = 0; |
237 | dmv->devt = devt; | | 240 | dmv->devt = devt; |
238 | | | 241 | |
239 | dm_table_head_init(&dmv->table_head); | | 242 | dm_table_head_init(&dmv->table_head); |
240 | | | 243 | |
241 | mutex_init(&dmv->dev_mtx, MUTEX_DEFAULT, IPL_NONE); | | 244 | mutex_init(&dmv->dev_mtx, MUTEX_DEFAULT, IPL_NONE); |
242 | mutex_init(&dmv->diskp_mtx, MUTEX_DEFAULT, IPL_NONE); | | 245 | mutex_init(&dmv->diskp_mtx, MUTEX_DEFAULT, IPL_NONE); |
243 | cv_init(&dmv->dev_cv, "dm_dev"); | | 246 | cv_init(&dmv->dev_cv, "dm_dev"); |
244 | | | 247 | |
245 | if (flags & DM_READONLY_FLAG) | | 248 | if (flags & DM_READONLY_FLAG) |
246 | dmv->flags |= DM_READONLY_FLAG; | | 249 | dmv->flags |= DM_READONLY_FLAG; |
247 | | | 250 | |
248 | prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); | | 251 | prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); |
249 | | | 252 | |
250 | disk_init(dmv->diskp, dmv->name, &dmdkdriver); | | 253 | disk_init(dmv->diskp, device_xname(devt), &dmdkdriver); |
251 | disk_attach(dmv->diskp); | | 254 | disk_attach(dmv->diskp); |
252 | | | 255 | |
253 | dmv->diskp->dk_info = NULL; | | 256 | dmv->diskp->dk_info = NULL; |
254 | | | 257 | |
255 | if ((r = dm_dev_insert(dmv)) != 0) | | 258 | if ((r = dm_dev_insert(dmv)) != 0) |
256 | dm_dev_free(dmv); | | 259 | dm_dev_free(dmv); |
257 | | | 260 | |
258 | DM_ADD_FLAG(flags, DM_EXISTS_FLAG); | | 261 | DM_ADD_FLAG(flags, DM_EXISTS_FLAG); |
259 | DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); | | 262 | DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); |
260 | | | 263 | |
261 | /* Increment device counter After creating device */ | | 264 | /* Increment device counter After creating device */ |
262 | atomic_inc_32(&dm_dev_counter); | | 265 | atomic_inc_32(&dm_dev_counter); |
263 | | | 266 | |