Sun Jan 14 07:56:53 2024 UTC (127d)
Avoid leaving a configured device without resources.


(mlelstv)
diff -r1.56 -r1.57 src/sys/dev/dm/dm_ioctl.c

cvs diff -r1.56 -r1.57 src/sys/dev/dm/dm_ioctl.c (expand / switch to unified diff)

--- src/sys/dev/dm/dm_ioctl.c 2022/10/13 06:10:48 1.56
+++ src/sys/dev/dm/dm_ioctl.c 2024/01/14 07:56:53 1.57
@@ -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