Source-Changes-HG archive

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

[src/pgoyette-localcount]: src/sys/dev Make sure that whenever we're using th...



details:   https://anonhg.NetBSD.org/src/rev/90cbe6233896
branches:  pgoyette-localcount
changeset: 852837:90cbe6233896
user:      pgoyette <pgoyette%NetBSD.org@localhost>
date:      Fri Jul 22 03:39:43 2016 +0000

description:
Make sure that whenever we're using the cgd device's softc, we maintain
a reference to the device so things won't get deleted out from under us!

diffstat:

 sys/dev/cgd.c |  136 ++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 95 insertions(+), 41 deletions(-)

diffs (truncated from 391 to 300 lines):

diff -r a7a5313e5d55 -r 90cbe6233896 sys/dev/cgd.c
--- a/sys/dev/cgd.c     Fri Jul 22 02:05:39 2016 +0000
+++ b/sys/dev/cgd.c     Fri Jul 22 03:39:43 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cgd.c,v 1.108.2.4 2016/07/20 06:51:13 pgoyette Exp $ */
+/* $NetBSD: cgd.c,v 1.108.2.5 2016/07/22 03:39:43 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.4 2016/07/20 06:51:13 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.108.2.5 2016/07/22 03:39:43 pgoyette Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -102,7 +102,7 @@
 static int cgd_match(device_t, cfdata_t, void *);
 static void cgd_attach(device_t, device_t, void *);
 static int cgd_detach(device_t, int);
-static struct cgd_softc        *cgd_spawn(int);
+static struct cgd_softc        *cgd_spawn(int, *device_t);
 static int cgd_destroy(device_t);
 
 /* Internal Functions */
@@ -172,7 +172,8 @@
 /* Utility Functions */
 
 #define CGDUNIT(x)             DISKUNIT(x)
-#define GETCGD_SOFTC(_cs, x)   if (!((_cs) = getcgd_softc(x))) return ENXIO
+#define GETCGD_SOFTC(_cs, x, _dv)                              \
+       if (!((_cs) = getcgd_softc(x, &_dv))) return ENXIO;
 
 /* The code */
 
@@ -188,16 +189,20 @@
 }
 
 static struct cgd_softc *
-getcgd_softc(dev_t dev)
+getcgd_softc(dev_t dev, device_t *self)
 {
        int     unit = CGDUNIT(dev);
        struct cgd_softc *sc;
 
        DPRINTF_FOLLOW(("getcgd_softc(0x%"PRIx64"): unit = %d\n", dev, unit));
 
-       sc = device_lookup_private(&cgd_cd, unit);
+       *self = device_lookup_acquire(&cgd_cd, unit);
+       if (*self == NULL)
+               return NULL;
+       
+       sc = device_private(*self);
        if (sc == NULL)
-               sc = cgd_spawn(unit);
+               sc = cgd_spawn(unit, *self);
        return sc;
 }
 
@@ -256,9 +261,8 @@
 }
 
 static struct cgd_softc *
-cgd_spawn(int unit)
+cgd_spawn(int unit, device_t *self)
 {
-       device_t self;
        cfdata_t cf;
 
        cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
@@ -270,14 +274,15 @@
        if (config_attach_pseudo(cf) == NULL)
                return NULL;
 
-       self = device_lookup_acquire(&cgd_cd, unit);
+       *self = device_lookup_acquire(&cgd_cd, unit);
        if (self == NULL)
                return NULL;
        else
                /*
-                * Note that we return with a reference to the device!
+                * Note that we return while still holding a reference
+                * to the device!
                 */
-               return device_private(self);
+               return device_private(*self);
 }
 
 static int
@@ -297,40 +302,50 @@
 static int
 cgdopen(dev_t dev, int flags, int fmt, struct lwp *l)
 {
+       device_t self;
+       int     error;
        struct  cgd_softc *cs;
 
        DPRINTF_FOLLOW(("cgdopen(0x%"PRIx64", %d)\n", dev, flags));
-       GETCGD_SOFTC(cs, dev);
-       return dk_open(&cs->sc_dksc, dev, flags, fmt, l);
+       GETCGD_SOFTC(cs, dev, self);
+       error = dk_open(&cs->sc_dksc, dev, flags, fmt, l);
+       device_release(self);
+       return error;
 }
 
 static int
 cgdclose(dev_t dev, int flags, int fmt, struct lwp *l)
 {
        int error;
+       device_t self;
        struct  cgd_softc *cs;
        struct  dk_softc *dksc;
 
        DPRINTF_FOLLOW(("cgdclose(0x%"PRIx64", %d)\n", dev, flags));
-       GETCGD_SOFTC(cs, dev);
+       GETCGD_SOFTC(cs, dev, self);
        dksc = &cs->sc_dksc;
-       if ((error =  dk_close(dksc, dev, flags, fmt, l)) != 0)
+       if ((error =  dk_close(dksc, dev, flags, fmt, l)) != 0) {
+               device_release(self);
                return error;
+       }
 
        if (!DK_ATTACHED(dksc)) {
                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;
                }
        }
-       return 0;
+       device_release(self);
+       return error;
 }
 
 static void
 cgdstrategy(struct buf *bp)
 {
-       struct  cgd_softc *cs = getcgd_softc(bp->b_dev);
+       device_t self;
+       struct  cgd_softc *cs = getcgd_softc(bp->b_dev, &self);
        struct  dk_softc *dksc = &cs->sc_dksc;
        struct  disk_geom *dg = &dksc->sc_dkdev.dk_geom;
 
@@ -349,12 +364,14 @@
                bp->b_resid = bp->b_bcount;
                biodone(bp);
                cgd_release(bp->b_dev);
+               device_release(self);
                return;
        }
 
        /* XXXrcd: Should we test for (cs != NULL)? */
        dk_strategy(&cs->sc_dksc, bp);
        cgd_release(bp->b_dev);
+       device_release(self);
        return;
 }
 
@@ -362,7 +379,8 @@
 cgdsize(dev_t dev)
 {
        int retval;
-       struct cgd_softc *cs = getcgd_softc(dev);
+       device_t self;
+       struct cgd_softc *cs = getcgd_softc(dev, &self);
 
        DPRINTF_FOLLOW(("cgdsize(0x%"PRIx64")\n", dev));
        if (!cs)
@@ -371,6 +389,7 @@
                retval = dk_size(&cs->sc_dksc, dev);
 
        cgd_release(dev);
+       device_release(self);
        return retval;
 }
 
@@ -481,8 +500,9 @@
 cgdiodone(struct buf *nbp)
 {
        dev_t dev;
+       device_t self;
        struct  buf *obp = nbp->b_private;
-       struct  cgd_softc *cs = getcgd_softc(obp->b_dev);
+       struct  cgd_softc *cs = getcgd_softc(obp->b_dev, &self);
        struct  dk_softc *dksc = &cs->sc_dksc;
        struct  disk_geom *dg = &dksc->sc_dkdev.dk_geom;
        daddr_t bn;
@@ -531,6 +551,7 @@
        dev = obp->b_dev;
        dk_done(dksc, obp);
        cgd_release(dev);
+       device_release(self);
 
        dk_start(dksc, NULL);
 }
@@ -585,40 +606,52 @@
 static int
 cgdread(dev_t dev, struct uio *uio, int flags)
 {
+       device_t self;
+       int     error;
        struct  cgd_softc *cs;
        struct  dk_softc *dksc;
 
        DPRINTF_FOLLOW(("cgdread(0x%llx, %p, %d)\n",
            (unsigned long long)dev, uio, flags));
-       GETCGD_SOFTC(cs, dev);
+       GETCGD_SOFTC(cs, dev, self);
        dksc = &cs->sc_dksc;
        if (!DK_ATTACHED(dksc))
                return ENXIO;
-       return physio(cgdstrategy, NULL, dev, B_READ, minphys, uio);
+       error = physio(cgdstrategy, NULL, dev, B_READ, minphys, uio);
+       device_release(self);
+       return error;
 }
 
 /* XXX: we should probably put these into dksubr.c, mostly */
 static int
 cgdwrite(dev_t dev, struct uio *uio, int flags)
 {
+       device_t self;
+       int     error;
        struct  cgd_softc *cs;
        struct  dk_softc *dksc;
 
        DPRINTF_FOLLOW(("cgdwrite(0x%"PRIx64", %p, %d)\n", dev, uio, flags));
-       GETCGD_SOFTC(cs, dev);
+       GETCGD_SOFTC(cs, dev, self);
        dksc = &cs->sc_dksc;
-       if (!DK_ATTACHED(dksc))
+       if (!DK_ATTACHED(dksc)) {
+               device_release(self);
                return ENXIO;
-       return physio(cgdstrategy, NULL, dev, B_WRITE, minphys, uio);
+       }
+       error = physio(cgdstrategy, NULL, dev, B_WRITE, minphys, uio);
+       device_release(self);
+       return error;
 }
 
 static int
 cgdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
 {
+       device_t self;
        struct  cgd_softc *cs;
        struct  dk_softc *dksc;
        int     part = DISKPART(dev);
        int     pmask = 1 << part;
+       int     error = 0;
 
        DPRINTF_FOLLOW(("cgdioctl(0x%"PRIx64", %ld, %p, %d, %p)\n",
            dev, cmd, data, flag, l));
@@ -632,7 +665,7 @@
                        return EBADF;
                /* FALLTHROUGH */
        default:
-               GETCGD_SOFTC(cs, dev);
+               GETCGD_SOFTC(cs, dev, self);
                dksc = &cs->sc_dksc;
                break;
        }
@@ -640,46 +673,61 @@
        switch (cmd) {
        case CGDIOCSET:
                if (DK_ATTACHED(dksc))
-                       return EBUSY;
-               return cgd_ioctl_set(cs, data, l);
+                       error = EBUSY;
+               else
+                       cgd_ioctl_set(cs, data, l);
+               break;
        case CGDIOCCLR:
                if (DK_BUSY(&cs->sc_dksc, pmask))
-                       return EBUSY;
-               return cgd_ioctl_clr(cs, l);
+                       error = EBUSY;
+               else
+                       cgd_ioctl_clr(cs, l);
+               break;
        case DIOCCACHESYNC:
                /*
                 * XXX Do we really need to care about having a writable
                 * file descriptor here?
                 */
                if ((flag & FWRITE) == 0)
-                       return (EBADF);
+                       error = (EBADF);
 
                /*
                 * We pass this call down to the underlying disk.
                 */
-               return VOP_IOCTL(cs->sc_tvn, cmd, data, flag, l->l_cred);
+               else
+                       error = VOP_IOCTL(cs->sc_tvn, cmd, data, flag,



Home | Main Index | Thread Index | Old Index