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