Thu Jul 23 21:58:06 2009 UTC ()
Move the RAID shutdown to the raid(4) detachment routine, and use
config_detach(9) to shutdown a RAID.

Detach raid(4) units at shutdown.

Ok by oster@.


(dyoung)
diff -r1.265 -r1.266 src/sys/dev/raidframe/rf_netbsdkintf.c

cvs diff -r1.265 -r1.266 src/sys/dev/raidframe/rf_netbsdkintf.c (expand / switch to context diff)
--- src/sys/dev/raidframe/rf_netbsdkintf.c 2009/06/10 14:17:13 1.265
+++ src/sys/dev/raidframe/rf_netbsdkintf.c 2009/07/23 21:58:06 1.266
@@ -1,4 +1,4 @@
-/*	$NetBSD: rf_netbsdkintf.c,v 1.265 2009/06/10 14:17:13 pooka Exp $	*/
+/*	$NetBSD: rf_netbsdkintf.c,v 1.266 2009/07/23 21:58:06 dyoung Exp $	*/
 /*-
  * Copyright (c) 1996, 1997, 1998, 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -139,7 +139,7 @@
  ***********************************************************/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.265 2009/06/10 14:17:13 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.266 2009/07/23 21:58:06 dyoung Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -260,6 +260,7 @@
 #define RAIDF_INITED	0x01	/* unit has been initialized */
 #define RAIDF_WLABEL	0x02	/* label area is writable */
 #define RAIDF_LABELLING	0x04	/* unit is currently being labelled */
+#define RAIDF_SHUTDOWN	0x08	/* unit is being shutdown */
 #define RAIDF_WANTED	0x40	/* someone is waiting to obtain a lock */
 #define RAIDF_LOCKED	0x80	/* unit is locked */
 
@@ -267,8 +268,9 @@
 int numraid = 0;
 
 extern struct cfdriver raid_cd;
-CFATTACH_DECL_NEW(raid, sizeof(struct raid_softc),
-    raid_match, raid_attach, raid_detach, NULL);
+CFATTACH_DECL3_NEW(raid, sizeof(struct raid_softc),
+    raid_match, raid_attach, raid_detach, NULL, NULL, NULL,
+    DVF_DETACH_SHUTDOWN);
 
 /*
  * Allow RAIDOUTSTANDING number of simultaneous IO's to this RAID device.
@@ -305,6 +307,8 @@
 static int raidlock(struct raid_softc *);
 static void raidunlock(struct raid_softc *);
 
+static int raid_detach_unlocked(struct raid_softc *);
+
 static void rf_markalldirty(RF_Raid_t *);
 static void rf_set_properties(struct raid_softc *, RF_Raid_t *);
 
@@ -729,6 +733,12 @@
 
 	if ((error = raidlock(rs)) != 0)
 		return (error);
+
+	if ((rs->sc_flags & RAIDF_SHUTDOWN) != 0) {
+		error = EBUSY;
+		goto bad;
+	}
+
 	lp = rs->sc_dkdev.dk_label;
 
 	part = DISKPART(dev);
@@ -797,7 +807,6 @@
 raidclose(dev_t dev, int flags, int fmt, struct lwp *l)
 {
 	int     unit = raidunit(dev);
-	cfdata_t cf;
 	struct raid_softc *rs;
 	int     error = 0;
 	int     part;
@@ -833,24 +842,10 @@
 
 		rf_update_component_labels(raidPtrs[unit],
 						 RF_FINAL_COMPONENT_UPDATE);
-		if (doing_shutdown) {
-			/* last one, and we're going down, so
-			   lights out for this RAID set too. */
-			error = rf_Shutdown(raidPtrs[unit]);
 
-			/* It's no longer initialized... */
-			rs->sc_flags &= ~RAIDF_INITED;
-
-			/* detach the device */
-			
-			cf = device_cfdata(rs->sc_dev);
-			error = config_detach(rs->sc_dev, DETACH_QUIET);
-			free(cf, M_RAIDFRAME);
-			
-			/* Detach the disk. */
-			disk_detach(&rs->sc_dkdev);
-			disk_destroy(&rs->sc_dkdev);
-		}
+		/* If the kernel is shutting down, it will detach
+		 * this RAID set soon enough.
+		 */
 	}
 
 	raidunlock(rs);
@@ -964,6 +959,35 @@
 
 }
 
+static int
+raid_detach_unlocked(struct raid_softc *rs)
+{
+	int error;
+	RF_Raid_t *raidPtr;
+
+	raidPtr = raidPtrs[device_unit(rs->sc_dev)];
+
+	/*
+	 * If somebody has a partition mounted, we shouldn't
+	 * shutdown.
+	 */
+	if (rs->sc_dkdev.dk_openmask != 0)
+		return EBUSY;
+
+	if ((rs->sc_flags & RAIDF_INITED) == 0)
+		;	/* not initialized: nothing to do */
+	else if ((error = rf_Shutdown(raidPtr)) != 0)
+		return error;
+	else
+		rs->sc_flags &= ~(RAIDF_INITED|RAIDF_SHUTDOWN);
+
+	/* Detach the disk. */
+	disk_detach(&rs->sc_dkdev);
+	disk_destroy(&rs->sc_dkdev);
+
+	return 0;
+}
+
 int
 raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
 {
@@ -1173,42 +1197,35 @@
 		/* shutdown the system */
 	case RAIDFRAME_SHUTDOWN:
 
+		part = DISKPART(dev);
+		pmask = (1 << part);
+
 		if ((error = raidlock(rs)) != 0)
 			return (error);
 
-		/*
-		 * If somebody has a partition mounted, we shouldn't
-		 * shutdown.
-		 */
-
-		part = DISKPART(dev);
-		pmask = (1 << part);
 		if ((rs->sc_dkdev.dk_openmask & ~pmask) ||
 		    ((rs->sc_dkdev.dk_bopenmask & pmask) &&
-			(rs->sc_dkdev.dk_copenmask & pmask))) {
-			raidunlock(rs);
-			return (EBUSY);
+			(rs->sc_dkdev.dk_copenmask & pmask)))
+			retcode = EBUSY;
+		else {
+			rs->sc_flags |= RAIDF_SHUTDOWN;
+			rs->sc_dkdev.dk_copenmask &= ~pmask;
+			rs->sc_dkdev.dk_bopenmask &= ~pmask;
+			rs->sc_dkdev.dk_openmask &= ~pmask;
+			retcode = 0;
 		}
 
-		retcode = rf_Shutdown(raidPtr);
+		raidunlock(rs);
 
-		/* It's no longer initialized... */
-		rs->sc_flags &= ~RAIDF_INITED;
+		if (retcode != 0)
+			return retcode;
 
 		/* free the pseudo device attach bits */
 
 		cf = device_cfdata(rs->sc_dev);
-		/* XXX this causes us to not return any errors
-		   from the above call to rf_Shutdown() */
-		retcode = config_detach(rs->sc_dev, DETACH_QUIET);
-		free(cf, M_RAIDFRAME);
+		if ((retcode = config_detach(rs->sc_dev, DETACH_QUIET)) == 0)
+			free(cf, M_RAIDFRAME);
 
-		/* Detach the disk. */
-		disk_detach(&rs->sc_dkdev);
-		disk_destroy(&rs->sc_dkdev);
-
-		raidunlock(rs);
-
 		return (retcode);
 	case RAIDFRAME_GET_COMPONENT_LABEL:
 		clabel_ptr = (RF_ComponentLabel_t **) data;
@@ -3620,12 +3637,17 @@
 static int
 raid_detach(device_t self, int flags)
 {
-	struct raid_softc *rs = device_private(self);
+	int error;
+	struct raid_softc *rs = &raid_softc[device_unit(self)];
 
-	if (rs->sc_flags & RAIDF_INITED)
-		return EBUSY;
+	if ((error = raidlock(rs)) != 0)
+		return (error);
 
-	return 0;
+	error = raid_detach_unlocked(rs);
+
+	raidunlock(rs);
+
+	return error;
 }
 
 static void