Module Name:    src
Committed By:   pgoyette
Date:           Sun Jul 24 10:44:57 UTC 2016

Modified Files:
        src/sys/dev [pgoyette-localcount]: cgd.c

Log Message:
Call device_release() in appropriate error paths.

In the module initialization code, make the bmajor/cmajor variables
global so they can be shared with the rump component initialization.


To generate a diff of this commit:
cvs rdiff -u -r1.108.2.12 -r1.108.2.13 src/sys/dev/cgd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/cgd.c
diff -u src/sys/dev/cgd.c:1.108.2.12 src/sys/dev/cgd.c:1.108.2.13
--- src/sys/dev/cgd.c:1.108.2.12	Sun Jul 24 00:14:08 2016
+++ src/sys/dev/cgd.c	Sun Jul 24 10:44:57 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: cgd.c,v 1.108.2.12 2016/07/24 00:14:08 pgoyette Exp $ */
+/* $NetBSD: cgd.c,v 1.108.2.13 2016/07/24 10:44:57 pgoyette Exp $ */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.108.2.12 2016/07/24 00:14:08 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.108.2.13 2016/07/24 10:44:57 pgoyette Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -179,6 +179,13 @@ static void	hexprint(const char *, void 
 
 /* The code */
 
+/*
+ * Lookup the device and return it's softc.  If the device doesn't
+ * exist, spawn it.
+ *
+ * In either case, the device is "acquired", and must be "released"
+ * by the caller after it is finished with the softc.
+ */
 static struct cgd_softc *
 getcgd_softc(dev_t dev, device_t *self)
 {
@@ -208,7 +215,9 @@ cgd_match(device_t self, cfdata_t cfdata
 static void
 cgd_attach(device_t parent, device_t self, void *aux)
 {
-	struct cgd_softc *sc = device_private(self);
+	struct cgd_softc *sc;
+
+	sc = device_private(self);
 
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_BIO);
 	dk_init(&sc->sc_dksc, self, DKTYPE_CGD);
@@ -220,6 +229,10 @@ cgd_attach(device_t parent, device_t sel
 }
 
 
+/*
+ * The caller must hold a reference to the device's localcount.  the
+ * reference is released if the device is available for detach.
+ */
 static int
 cgd_detach(device_t self, int flags)
 {
@@ -238,6 +251,7 @@ cgd_detach(device_t self, int flags)
 	disk_destroy(&dksc->sc_dkdev);
 	mutex_destroy(&sc->sc_lock);
 
+	device_release(self);
 	return 0;
 }
 
@@ -256,6 +270,7 @@ static struct cgd_softc *
 cgd_spawn(int unit, device_t *self)
 {
 	cfdata_t cf;
+	struct cgd_softc *sc;
 
 	cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
 	cf->cf_name = cgd_cd.cd_name;
@@ -269,12 +284,14 @@ cgd_spawn(int unit, device_t *self)
 	*self = device_lookup_acquire(&cgd_cd, unit);
 	if (self == NULL)
 		return NULL;
-	else
+	else {
 		/*
 		 * Note that we return while still holding a reference
 		 * to the device!
 		 */
-		return device_private(*self);
+		sc = device_private(*self);
+		return sc;
+	}
 }
 
 static int
@@ -285,10 +302,10 @@ cgd_destroy(device_t dev)
 
 	cf = device_cfdata(dev);
 	error = config_detach(dev, DETACH_QUIET);
-	if (error)
-		return error;
-	free(cf, M_DEVBUF);
-	return 0;
+	if (error == 0)
+		free(cf, M_DEVBUF);
+
+	return error;
 }
 
 static int
@@ -325,11 +342,10 @@ cgdclose(dev_t dev, int flags, int fmt, 
 		if ((error = cgd_destroy(cs->sc_dksc.sc_dev)) != 0) {
 			aprint_error_dev(dksc->sc_dev,
 			    "unable to detach instance\n");
-			device_release(self);
 			return error;
 		}
-	}
-	device_release(self);
+	} else
+		device_release(self);
 	return 0;
 }
 
@@ -597,8 +613,10 @@ cgdread(dev_t dev, struct uio *uio, int 
 	    (unsigned long long)dev, uio, flags));
 	GETCGD_SOFTC(cs, dev, self);
 	dksc = &cs->sc_dksc;
-	if (!DK_ATTACHED(dksc))
+	if (!DK_ATTACHED(dksc)) {
+		device_release(self);
 		return ENXIO;
+	}
 	error = physio(cgdstrategy, NULL, dev, B_READ, minphys, uio);
 	device_release(self);
 	return error;
@@ -1104,6 +1122,8 @@ MODULE(MODULE_CLASS_DRIVER, cgd, "dk_sub
 
 #ifdef _MODULE
 CFDRIVER_DECL(cgd, DV_DISK, NULL);
+
+devmajor_t cgd_bmajor = -1, cgd_cmajor = -1;
 #endif
 
 static int
@@ -1111,10 +1131,6 @@ cgd_modcmd(modcmd_t cmd, void *arg)
 {
 	int error = 0;
 
-#ifdef _MODULE
-	devmajor_t bmajor = -1, cmajor = -1;
-#endif
-
 	switch (cmd) {
 	case MODULE_CMD_INIT:
 #ifdef _MODULE
@@ -1133,8 +1149,8 @@ cgd_modcmd(modcmd_t cmd, void *arg)
 		/*
 		 * Attach the {b,c}devsw's
 		 */
-		error = devsw_attach("cgd", &cgd_bdevsw, &bmajor,
-		    &cgd_cdevsw, &cmajor);
+		error = devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
+		    &cgd_cdevsw, &cgd_cmajor);
 
 		/*
 		 * If devsw_attach fails, remove from autoconf database
@@ -1161,8 +1177,8 @@ cgd_modcmd(modcmd_t cmd, void *arg)
 		 */
 		error = config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
 		if (error) {
-			error = devsw_attach("cgd", &cgd_bdevsw, &bmajor,
-			    &cgd_cdevsw, &cmajor);
+			error = devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
+			    &cgd_cdevsw, &cgd_cmajor);
 			aprint_error("%s: failed to detach %s cfattach, "
 			    "error %d\n", __func__, cgd_cd.cd_name, error);
 			break;
@@ -1170,8 +1186,8 @@ cgd_modcmd(modcmd_t cmd, void *arg)
 		error = config_cfdriver_detach(&cgd_cd);
 		if (error) {
 			config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
-			devsw_attach("cgd", &cgd_bdevsw, &bmajor,
-			    &cgd_cdevsw, &cmajor);
+			devsw_attach("cgd", &cgd_bdevsw, &cgd_bmajor,
+			    &cgd_cdevsw, &cgd_cmajor);
 			aprint_error("%s: failed to detach %s cfdriver, "
 			    "error %d\n", __func__, cgd_cd.cd_name, error);
 			break;

Reply via email to