Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/dm Track the number of cdev and bdev opens and fail ...



details:   https://anonhg.NetBSD.org/src/rev/b96f30fe316d
branches:  trunk
changeset: 1021082:b96f30fe316d
user:      hannken <hannken%NetBSD.org@localhost>
date:      Fri May 07 09:54:43 2021 +0000

description:
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)

diffstat:

 sys/dev/dm/device-mapper.c |  49 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 48 insertions(+), 1 deletions(-)

diffs (81 lines):

diff -r 3bd1f31b26ee -r b96f30fe316d sys/dev/dm/device-mapper.c
--- a/sys/dev/dm/device-mapper.c        Fri May 07 09:53:39 2021 +0000
+++ b/sys/dev/dm/device-mapper.c        Fri May 07 09:54:43 2021 +0000
@@ -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 @@
 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 @@
 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 @@
 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;
 }
 



Home | Main Index | Thread Index | Old Index