summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorthorpej <thorpej@NetBSD.org>2004-09-25 04:28:08 +0000
committerthorpej <thorpej@NetBSD.org>2004-09-25 04:28:08 +0000
commit46cfcf0eb86917bafc33cbc2635b43dbbf1ae57f (patch)
tree95e33627e9f4edd4c1531e5e1fc23540eeffaab2 /sys/dev
parent49fe2034a34712a8fbcf3f371cc2422bf2471e37 (diff)
Add support for wedges to the logical disk driver.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ld.c109
-rw-r--r--sys/dev/ldvar.h4
2 files changed, 61 insertions, 52 deletions
diff --git a/sys/dev/ld.c b/sys/dev/ld.c
index bba9827067a..0ae668ff8b6 100644
--- a/sys/dev/ld.c
+++ b/sys/dev/ld.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ld.c,v 1.29 2004/08/30 00:34:41 thorpej Exp $ */
+/* $NetBSD: ld.c,v 1.30 2004/09/25 04:28:08 thorpej Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.29 2004/08/30 00:34:41 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.30 2004/09/25 04:28:08 thorpej Exp $");
#include "rnd.h"
@@ -70,11 +70,9 @@ __KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.29 2004/08/30 00:34:41 thorpej Exp $");
static void ldgetdefaultlabel(struct ld_softc *, struct disklabel *);
static void ldgetdisklabel(struct ld_softc *);
-static int ldlock(struct ld_softc *);
static void ldminphys(struct buf *bp);
static void ldshutdown(void *);
static void ldstart(struct ld_softc *);
-static void ldunlock(struct ld_softc *);
extern struct cfdriver ld_cd;
@@ -96,7 +94,7 @@ const struct cdevsw ld_cdevsw = {
nostop, notty, nopoll, nommap, nokqfilter, D_DISK
};
-static struct dkdriver lddkdriver = { ldstrategy };
+static struct dkdriver lddkdriver = { ldstrategy, ldminphys };
static void *ld_sdh;
void
@@ -157,6 +155,9 @@ ldattach(struct ld_softc *sc)
if (ld_sdh == NULL)
ld_sdh = shutdownhook_establish(ldshutdown, NULL);
bufq_alloc(&sc->sc_bufq, BUFQ_DISK_DEFAULT_STRAT()|BUFQ_SORT_RAWBLOCK);
+
+ /* Discover wedges on this disk. */
+ dkwedge_discover(&sc->sc_dk);
}
int
@@ -232,6 +233,9 @@ ldenddetach(struct ld_softc *sc)
vdevgone(cmaj, mn, mn, VCHR);
}
+ /* Delete all of our wedges. */
+ dkwedge_delall(&sc->sc_dk);
+
/* Detach from the disk list. */
disk_detach(&sc->sc_dk);
@@ -275,15 +279,17 @@ static int
ldopen(dev_t dev, int flags, int fmt, struct proc *p)
{
struct ld_softc *sc;
- int unit, part;
+ int error, unit, part;
unit = DISKUNIT(dev);
- if ((sc = device_lookup(&ld_cd, unit))== NULL)
+ if ((sc = device_lookup(&ld_cd, unit)) == NULL)
return (ENXIO);
if ((sc->sc_flags & LDF_ENABLED) == 0)
return (ENODEV);
part = DISKPART(dev);
- ldlock(sc);
+
+ if ((error = lockmgr(&sc->sc_dk.dk_openlock, LK_EXCLUSIVE, NULL)) != 0)
+ return (error);
if (sc->sc_dk.dk_openmask == 0) {
/* Load the partition info if not already loaded. */
@@ -294,8 +300,8 @@ ldopen(dev_t dev, int flags, int fmt, struct proc *p)
/* Check that the partition exists. */
if (part != RAW_PART && (part >= sc->sc_dk.dk_label->d_npartitions ||
sc->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
- ldunlock(sc);
- return (ENXIO);
+ error = ENXIO;
+ goto bad1;
}
/* Ensure only one open at a time. */
@@ -310,8 +316,12 @@ ldopen(dev_t dev, int flags, int fmt, struct proc *p)
sc->sc_dk.dk_openmask =
sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
- ldunlock(sc);
+ (void) lockmgr(&sc->sc_dk.dk_openlock, LK_RELEASE, NULL);
return (0);
+
+ bad1:
+ (void) lockmgr(&sc->sc_dk.dk_openlock, LK_RELEASE, NULL);
+ return (error);
}
/* ARGSUSED */
@@ -319,12 +329,14 @@ static int
ldclose(dev_t dev, int flags, int fmt, struct proc *p)
{
struct ld_softc *sc;
- int part, unit;
+ int error, part, unit;
unit = DISKUNIT(dev);
part = DISKPART(dev);
sc = device_lookup(&ld_cd, unit);
- ldlock(sc);
+
+ if ((error = lockmgr(&sc->sc_dk.dk_openlock, LK_EXCLUSIVE, NULL)) != 0)
+ return (error);
switch (fmt) {
case S_IFCHR:
@@ -345,7 +357,7 @@ ldclose(dev_t dev, int flags, int fmt, struct proc *p)
sc->sc_flags &= ~LDF_VLABEL;
}
- ldunlock(sc);
+ (void) lockmgr(&sc->sc_dk.dk_openlock, LK_RELEASE, NULL);
return (0);
}
@@ -418,7 +430,8 @@ ldioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
if ((flag & FWRITE) == 0)
return (EBADF);
- if ((error = ldlock(sc)) != 0)
+ if ((error = lockmgr(&sc->sc_dk.dk_openlock, LK_EXCLUSIVE,
+ NULL)) == 0)
return (error);
sc->sc_flags |= LDF_LABELLING;
@@ -436,7 +449,7 @@ ldioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
sc->sc_dk.dk_cpulabel);
sc->sc_flags &= ~LDF_LABELLING;
- ldunlock(sc);
+ (void) lockmgr(&sc->sc_dk.dk_openlock, LK_RELEASE, NULL);
break;
case DIOCKLABEL:
@@ -470,6 +483,37 @@ ldioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
break;
#endif
+ case DIOCAWEDGE:
+ {
+ struct dkwedge_info *dkw = (void *) addr;
+
+ if ((flag & FWRITE) == 0)
+ return (EBADF);
+
+ /* If the ioctl happens here, the parent is us. */
+ strcpy(dkw->dkw_parent, sc->sc_dv.dv_xname);
+ return (dkwedge_add(dkw));
+ }
+
+ case DIOCDWEDGE:
+ {
+ struct dkwedge_info *dkw = (void *) addr;
+
+ if ((flag & FWRITE) == 0)
+ return (EBADF);
+
+ /* If the ioctl happens here, the parent is us. */
+ strcpy(dkw->dkw_parent, sc->sc_dv.dv_xname);
+ return (dkwedge_del(dkw));
+ }
+
+ case DIOCLWEDGES:
+ {
+ struct dkwedge_list *dkwl = (void *) addr;
+
+ return (dkwedge_list(&sc->sc_dk, dkwl, p));
+ }
+
default:
error = ENOTTY;
break;
@@ -699,39 +743,6 @@ ldgetdefaultlabel(struct ld_softc *sc, struct disklabel *lp)
}
/*
- * Wait interruptibly for an exclusive lock.
- *
- * XXX Several drivers do this; it should be abstracted and made MP-safe.
- */
-static int
-ldlock(struct ld_softc *sc)
-{
- int error;
-
- while ((sc->sc_flags & LDF_LKHELD) != 0) {
- sc->sc_flags |= LDF_LKWANTED;
- if ((error = tsleep(sc, PRIBIO | PCATCH, "ldlck", 0)) != 0)
- return (error);
- }
- sc->sc_flags |= LDF_LKHELD;
- return (0);
-}
-
-/*
- * Unlock and wake up any waiters.
- */
-static void
-ldunlock(struct ld_softc *sc)
-{
-
- sc->sc_flags &= ~LDF_LKHELD;
- if ((sc->sc_flags & LDF_LKWANTED) != 0) {
- sc->sc_flags &= ~LDF_LKWANTED;
- wakeup(sc);
- }
-}
-
-/*
* Take a dump.
*/
static int
diff --git a/sys/dev/ldvar.h b/sys/dev/ldvar.h
index c75637b9da1..0d11627eb02 100644
--- a/sys/dev/ldvar.h
+++ b/sys/dev/ldvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: ldvar.h,v 1.8 2004/07/20 15:44:20 dbj Exp $ */
+/* $NetBSD: ldvar.h,v 1.9 2004/09/25 04:28:08 thorpej Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -66,8 +66,6 @@ struct ld_softc {
};
#define LDF_ENABLED 0x001 /* device enabled */
-#define LDF_LKHELD 0x002 /* lock held */
-#define LDF_LKWANTED 0x004 /* lock wanted */
#define LDF_WLABEL 0x008 /* label is writable */
#define LDF_LABELLING 0x010 /* writing label */
#define LDF_DRAIN 0x020 /* maxqueuecnt has changed; drain */