Module Name:    src
Committed By:   hannken
Date:           Fri May  7 09:54:43 UTC 2021

Modified Files:
        src/sys/dev/dm: device-mapper.c

Log Message:
Track the number of cdev and bdev opens and fail dm_detach()
on open devices unless detach is forced.

PR kern/54969 (Disk cache is no longer flushed on shutdown)


To generate a diff of this commit:
cvs rdiff -u -r1.61 -r1.62 src/sys/dev/dm/device-mapper.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/dm/device-mapper.c
diff -u src/sys/dev/dm/device-mapper.c:1.61 src/sys/dev/dm/device-mapper.c:1.62
--- src/sys/dev/dm/device-mapper.c:1.61	Wed Jul  8 15:07:13 2020
+++ src/sys/dev/dm/device-mapper.c	Fri May  7 09:54:43 2021
@@ -1,4 +1,4 @@
-/*        $NetBSD: device-mapper.c,v 1.61 2020/07/08 15:07:13 thorpej Exp $ */
+/*        $NetBSD: device-mapper.c,v 1.62 2021/05/07 09:54:43 hannken Exp $ */
 
 /*
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -260,8 +260,17 @@ dm_attach(device_t parent, device_t self
 static int
 dm_detach(device_t self, int flags)
 {
+	bool busy;
 	dm_dev_t *dmv;
 
+	dmv = dm_dev_lookup(NULL, NULL, device_unit(self));
+	mutex_enter(&dmv->diskp->dk_openlock);
+	busy = (dmv->diskp->dk_openmask != 0 && (flags & DETACH_FORCE) == 0);
+	mutex_exit(&dmv->diskp->dk_openlock);
+	dm_dev_unbusy(dmv);
+	if (busy)
+		return EBUSY;
+
 	pmf_device_deregister(self);
 
 	/* Detach device from global device list */
@@ -334,6 +343,25 @@ dmdestroy(void)
 static int
 dmopen(dev_t dev, int flags, int mode, struct lwp *l)
 {
+	dm_dev_t *dmv;
+	struct disk *dk;
+
+	dmv = dm_dev_lookup(NULL, NULL, minor(dev));
+	if (dmv) {
+		dk = dmv->diskp;
+		mutex_enter(&dk->dk_openlock);
+		switch (mode) {
+		case S_IFCHR:
+			dk->dk_copenmask |= 1;
+			break;
+		case S_IFBLK:
+			dk->dk_bopenmask |= 1;
+			break;
+		}
+		dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
+		mutex_exit(&dk->dk_openlock);
+		dm_dev_unbusy(dmv);
+	}
 
 	aprint_debug("dm open routine called %" PRIu32 "\n", minor(dev));
 	return 0;
@@ -342,8 +370,27 @@ dmopen(dev_t dev, int flags, int mode, s
 static int
 dmclose(dev_t dev, int flags, int mode, struct lwp *l)
 {
+	dm_dev_t *dmv;
+	struct disk *dk;
 
 	aprint_debug("dm close routine called %" PRIu32 "\n", minor(dev));
+
+	dmv = dm_dev_lookup(NULL, NULL, minor(dev));
+	if (dmv) {
+		dk = dmv->diskp;
+		mutex_enter(&dk->dk_openlock);
+		switch (mode) {
+		case S_IFCHR:
+			dk->dk_copenmask &= ~1;
+			break;
+		case S_IFBLK:
+			dk->dk_bopenmask &= ~1;
+			break;
+		}
+		dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
+		mutex_exit(&dk->dk_openlock);
+		dm_dev_unbusy(dmv);
+	}
 	return 0;
 }
 

Reply via email to