Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev A slight abstraction for disks. This is mainly [rig...
details: https://anonhg.NetBSD.org/src/rev/2f541ae88f0d
branches: trunk
changeset: 537681:2f541ae88f0d
user: elric <elric%NetBSD.org@localhost>
date: Fri Oct 04 18:02:00 2002 +0000
description:
A slight abstraction for disks. This is mainly [right now] in
support of the cryptographic disk which I'll be checking in shortly.
diffstat:
sys/dev/dksubr.c | 542 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/dkvar.h | 119 ++++++++++++
2 files changed, 661 insertions(+), 0 deletions(-)
diffs (truncated from 669 to 300 lines):
diff -r 3c6dc89022dd -r 2f541ae88f0d sys/dev/dksubr.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/dksubr.c Fri Oct 04 18:02:00 2002 +0000
@@ -0,0 +1,542 @@
+/* $NetBSD: dksubr.c,v 1.1 2002/10/04 18:02:00 elric Exp $ */
+
+/*-
+ * Copyright (c) 1996, 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe and Roland C. Dowdeswell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/ioctl.h>
+#include <sys/device.h>
+#include <sys/disk.h>
+#include <sys/disklabel.h>
+#include <sys/vnode.h>
+#include <sys/fcntl.h>
+#include <sys/namei.h>
+
+#include <dev/dkvar.h>
+
+int dkdebug = 0;
+
+#ifdef DEBUG
+#define DKDB_FOLLOW 0x1
+#define DKDB_INIT 0x2
+#define DKDB_VNODE 0x4
+
+#define IFDEBUG(x,y) if (dkdebug & (x)) y
+#define DPRINTF(x,y) IFDEBUG(x, printf y)
+#define DPRINTF_FOLLOW(y) DPRINTF(DKDB_FOLLOW, y)
+#else
+#define IFDEBUG(x,y)
+#define DPRINTF(x,y)
+#define DPRINTF_FOLLOW(y)
+#endif
+
+#define DKLABELDEV(dev) \
+ (MAKEDISKDEV(major((dev)), DISKUNIT((dev)), RAW_PART))
+
+void dk_makedisklabel(struct dk_intf *, struct dk_softc *);
+
+void
+dk_sc_init(struct dk_softc *dksc, void *osc, char *xname)
+{
+
+ memset(dksc, 0x0, sizeof(*dksc));
+ dksc->sc_osc = osc;
+ strncpy(dksc->sc_xname, xname, DK_XNAME_SIZE);
+ dksc->sc_dkdev.dk_name = dksc->sc_xname;
+ lockinit(&dksc->sc_lock, PRIBIO, "dklk", 0, 0);
+}
+
+/* ARGSUSED */
+int
+dk_open(struct dk_intf *di, struct dk_softc *dksc, dev_t dev,
+ int flags, int fmt, struct proc *p)
+{
+ struct disklabel *lp = dksc->sc_dkdev.dk_label;
+ int part = DISKPART(dev);
+ int pmask = 1 << part;
+ int ret = 0;
+
+ DPRINTF_FOLLOW(("dk_open(%s, %p, 0x%x, 0x%x)\n",
+ di->di_dkname, dksc, dev, flags));
+
+ if ((ret = lockmgr(&dksc->sc_lock, LK_EXCLUSIVE, NULL)) != 0)
+ return ret;
+
+ part = DISKPART(dev);
+ pmask = 1 << part;
+
+ /*
+ * If we're init'ed and there are no other open partitions then
+ * update the in-core disklabel.
+ */
+ if ((dksc->sc_flags & DKF_INITED) && dksc->sc_dkdev.dk_openmask == 0)
+ dk_getdisklabel(di, dksc, dev);
+
+ /* Fail if we can't find the partition. */
+ if ((part != RAW_PART) &&
+ (((dksc->sc_flags & DKF_INITED) == 0) ||
+ ((part >= lp->d_npartitions) ||
+ (lp->d_partitions[part].p_fstype == FS_UNUSED)))) {
+ ret = ENXIO;
+ goto done;
+ }
+
+ /* Mark our unit as open. */
+ switch (fmt) {
+ case S_IFCHR:
+ dksc->sc_dkdev.dk_copenmask |= pmask;
+ break;
+ case S_IFBLK:
+ dksc->sc_dkdev.dk_bopenmask |= pmask;
+ break;
+ }
+
+ dksc->sc_dkdev.dk_openmask =
+ dksc->sc_dkdev.dk_copenmask | dksc->sc_dkdev.dk_bopenmask;
+
+done:
+ lockmgr(&dksc->sc_lock, LK_RELEASE, NULL);
+ return ret;
+}
+
+/* ARGSUSED */
+int
+dk_close(struct dk_intf *di, struct dk_softc *dksc, dev_t dev,
+ int flags, int fmt, struct proc *p)
+{
+ int part = DISKPART(dev);
+ int pmask = 1 << part;
+ int ret;
+
+ DPRINTF_FOLLOW(("dk_close(%s, %p, 0x%x, 0x%x)\n",
+ di->di_dkname, dksc, dev, flags));
+
+ if ((ret = lockmgr(&dksc->sc_lock, LK_EXCLUSIVE, NULL)) != 0)
+ return ret;
+
+ switch (fmt) {
+ case S_IFCHR:
+ dksc->sc_dkdev.dk_copenmask &= ~pmask;
+ break;
+ case S_IFBLK:
+ dksc->sc_dkdev.dk_bopenmask &= ~pmask;
+ break;
+ }
+ dksc->sc_dkdev.dk_openmask =
+ dksc->sc_dkdev.dk_copenmask | dksc->sc_dkdev.dk_bopenmask;
+
+ lockmgr(&dksc->sc_lock, LK_RELEASE, NULL);
+ return 0;
+}
+
+void
+dk_strategy(struct dk_intf *di, struct dk_softc *dksc, struct buf *bp)
+{
+ struct disklabel *lp = dksc->sc_dkdev.dk_label;
+ int s;
+ int wlabel;
+
+ DPRINTF_FOLLOW(("dk_strategy(%s, %p, %p)\n",
+ di->di_dkname, dksc, bp));
+
+ if (!(dksc->sc_flags & DKF_INITED)) {
+ DPRINTF_FOLLOW(("dk_stragy: not inited\n"));
+ bp->b_error = ENXIO;
+ bp->b_flags |= B_ERROR;
+ return;
+ }
+
+ /* XXX look for some more errors, c.f. ld.c */
+
+ bp->b_resid = bp->b_bcount;
+
+ /* If there is nothing to do, then we are done */
+ if (bp->b_bcount == 0) {
+ biodone(bp);
+ return;
+ }
+
+ wlabel = dksc->sc_flags & (DKF_WLABEL|DKF_LABELLING);
+ if (DISKPART(bp->b_dev) != RAW_PART &&
+ bounds_check_with_label(bp, lp, wlabel) <= 0) {
+ biodone(bp);
+ return;
+ }
+
+ /*
+ * Start the unit by calling the start routine
+ * provided by the individual driver.
+ */
+ s = splbio();
+ di->di_diskstart(dksc->sc_osc, bp);
+ splx(s);
+ return;
+}
+
+int
+dk_size(struct dk_intf *di, struct dk_softc *dksc, dev_t dev)
+{
+ struct disklabel *lp;
+ int is_open;
+ int part;
+ int size;
+
+ if ((dksc->sc_flags & DKF_INITED) == 0)
+ return -1;
+
+ part = DISKPART(dev);
+ is_open = dksc->sc_dkdev.dk_openmask & (1 << part);
+
+ if (!is_open && di->di_open(dev, 0, S_IFBLK, curproc))
+ return -1;
+
+ lp = dksc->sc_dkdev.dk_label;
+ if (lp->d_partitions[part].p_fstype != FS_SWAP)
+ size = -1;
+ else
+ size = lp->d_partitions[part].p_size *
+ (lp->d_secsize / DEV_BSIZE);
+
+ if (!is_open && di->di_close(dev, 0, S_IFBLK, curproc))
+ return 1;
+
+ return size;
+}
+
+int
+dk_ioctl(struct dk_intf *di, struct dk_softc *dksc, dev_t dev,
+ u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct disklabel *lp;
+#ifdef __HAVE_OLD_DISKLABEL
+ struct disklabel newlabel;
+#endif
+ int error = 0;
+
+ DPRINTF_FOLLOW(("dk_ioctl(%s, %p, 0x%x, 0x%lx)\n",
+ di->di_dkname, dksc, dev, cmd));
+
+ /* ensure that the pseudo disk is open for writes for these commands */
+ switch (cmd) {
+ case DIOCSDINFO:
+ case DIOCWDINFO:
+#ifdef __HAVE_OLD_DISKLABEL
+ case ODIOCSDINFO:
+ case ODIOCWDINFO:
+#endif
+ case DIOCWLABEL:
+ if ((flag & FWRITE) == 0)
+ return EBADF;
+ }
+
+ /* ensure that the pseudo-disk is initialized for these */
+ switch (cmd) {
+ case DIOCGDINFO:
+ case DIOCSDINFO:
+ case DIOCWDINFO:
+ case DIOCGPART:
+ case DIOCWLABEL:
+ case DIOCGDEFLABEL:
+#ifdef __HAVE_OLD_DISKLABEL
+ case ODIOCGDINFO:
+ case ODIOCSDINFO:
+ case ODIOCWDINFO:
+ case ODIOCGDEFLABEL:
+#endif
+ if ((dksc->sc_flags & DKF_INITED) == 0)
+ return ENXIO;
+ }
+
+ switch (cmd) {
+ case DIOCGDINFO:
+ *(struct disklabel *)data = *(dksc->sc_dkdev.dk_label);
+ break;
+
+#ifdef __HAVE_OLD_DISKLABEL
+ case ODIOCGDINFO:
+ newlabel = *(dksc->sc_dkdev.dk_label);
+ if (newlabel.d_npartitions > OLDMAXPARTITIONS)
+ return ENOTTY;
+ memcpy(data, &newlabel, sizeof (struct olddisklabel));
Home |
Main Index |
Thread Index |
Old Index