diff options
| author | thorpej <thorpej@NetBSD.org> | 2004-09-25 04:28:08 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 2004-09-25 04:28:08 +0000 |
| commit | 46cfcf0eb86917bafc33cbc2635b43dbbf1ae57f (patch) | |
| tree | 95e33627e9f4edd4c1531e5e1fc23540eeffaab2 /sys/dev | |
| parent | 49fe2034a34712a8fbcf3f371cc2422bf2471e37 (diff) | |
Add support for wedges to the logical disk driver.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ld.c | 109 | ||||
| -rw-r--r-- | sys/dev/ldvar.h | 4 |
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 */ |
