Module Name:    src
Committed By:   dyoung
Date:           Tue Jul 28 17:55:27 UTC 2009

Modified Files:
        src/sys/dev: md.c

Log Message:
Make mdopen() and mdclose() maintain the openmask.  md_detach()
depends on the openmask to know whether it should either return
EBUSY because the device is open, or tear the device down.

Alan Barrett reports that this fixes kern/41725, in part: it prevents
the UVM fault, and the kernel detaches /dev/md0a after unmounting
/ on /dev/md0a instead of before.


To generate a diff of this commit:
cvs rdiff -u -r1.59 -r1.60 src/sys/dev/md.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/md.c
diff -u src/sys/dev/md.c:1.59 src/sys/dev/md.c:1.60
--- src/sys/dev/md.c:1.59	Tue May 19 20:25:41 2009
+++ src/sys/dev/md.c	Tue Jul 28 17:55:27 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: md.c,v 1.59 2009/05/19 20:25:41 dyoung Exp $	*/
+/*	$NetBSD: md.c,v 1.60 2009/07/28 17:55:27 dyoung Exp $	*/
 
 /*
  * Copyright (c) 1995 Gordon W. Ross, Leo Weppelman.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: md.c,v 1.59 2009/05/19 20:25:41 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: md.c,v 1.60 2009/07/28 17:55:27 dyoung Exp $");
 
 #include "opt_md.h"
 #include "opt_tftproot.h"
@@ -59,6 +59,7 @@
 #include <sys/bufq.h>
 #include <sys/device.h>
 #include <sys/disk.h>
+#include <sys/stat.h>
 #include <sys/proc.h>
 #include <sys/conf.h>
 #include <sys/disklabel.h>
@@ -243,18 +244,23 @@
 mdopen(dev_t dev, int flag, int fmt, struct lwp *l)
 {
 	int unit;
+	int part = DISKPART(dev);
+	int pmask = 1 << part;
 	struct md_softc *sc;
+	struct disk *dk;
 
 	unit = MD_UNIT(dev);
 	sc = device_lookup_private(&md_cd, unit);
 	if (sc == NULL)
 		return ENXIO;
 
+	dk = &sc->sc_dkdev;
+
 	/*
 	 * The raw partition is used for ioctl to configure.
 	 */
-	if (DISKPART(dev) == RAW_PART)
-		return 0;
+	if (part == RAW_PART)
+		goto ok;
 
 #ifdef	MEMORY_DISK_HOOKS
 	/* Call the open hook to allow loading the device. */
@@ -268,13 +274,52 @@
 	if (sc->sc_type == MD_UNCONFIGURED)
 		return ENXIO;
 
+ok:
+	/* XXX duplicates code in dk_open().  Call dk_open(), instead? */
+	mutex_enter(&dk->dk_openlock);
+	/* Mark our unit as open. */
+	switch (fmt) {
+	case S_IFCHR:
+		dk->dk_copenmask |= pmask;
+		break;
+	case S_IFBLK:
+		dk->dk_bopenmask |= pmask;
+		break;
+	}
+
+	dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
+
+	mutex_exit(&dk->dk_openlock);
 	return 0;
 }
 
 static int
 mdclose(dev_t dev, int flag, int fmt, struct lwp *l)
 {
+	int part = DISKPART(dev);
+	int pmask = 1 << part;
+	struct md_softc *sc;
+	struct disk *dk;
+
+	sc = device_lookup_private(&md_cd, MD_UNIT(dev));
+	if (sc == NULL)
+		return ENXIO;
+
+	dk = &sc->sc_dkdev;
+
+	mutex_enter(&dk->dk_openlock);
+
+	switch (fmt) {
+	case S_IFCHR:
+		dk->dk_copenmask &= ~pmask;
+		break;
+	case S_IFBLK:
+		dk->dk_bopenmask &= ~pmask;
+		break;
+	}
+	dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
 
+	mutex_exit(&dk->dk_openlock);
 	return 0;
 }
 

Reply via email to