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