Annotation of kernel/bsd/dev/vnd.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
        !            26: /*
        !            27:  * Copyright (c) 1988 University of Utah.
        !            28:  * Copyright (c) 1990, 1993
        !            29:  *     The Regents of the University of California.  All rights reserved.
        !            30:  *
        !            31:  * This code is derived from software contributed to Berkeley by
        !            32:  * the Systems Programming Group of the University of Utah Computer
        !            33:  * Science Department.
        !            34:  *
        !            35:  * Redistribution and use in source and binary forms, with or without
        !            36:  * modification, are permitted provided that the following conditions
        !            37:  * are met:
        !            38:  * 1. Redistributions of source code must retain the above copyright
        !            39:  *    notice, this list of conditions and the following disclaimer.
        !            40:  * 2. Redistributions in binary form must reproduce the above copyright
        !            41:  *    notice, this list of conditions and the following disclaimer in the
        !            42:  *    documentation and/or other materials provided with the distribution.
        !            43:  * 3. All advertising materials mentioning features or use of this software
        !            44:  *    must display the following acknowledgement:
        !            45:  *     This product includes software developed by the University of
        !            46:  *     California, Berkeley and its contributors.
        !            47:  * 4. Neither the name of the University nor the names of its contributors
        !            48:  *    may be used to endorse or promote products derived from this software
        !            49:  *    without specific prior written permission.
        !            50:  *
        !            51:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            52:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            53:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            54:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            55:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            56:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            57:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            58:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            59:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            60:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            61:  * SUCH DAMAGE.
        !            62:  *
        !            63:  * from: Utah $Hdr: vn.c 1.13 94/04/02$
        !            64:  *
        !            65:  *     @(#)vn.c        8.9 (Berkeley) 5/14/95
        !            66:  */
        !            67: 
        !            68: /*
        !            69:  * Vnode disk driver.
        !            70:  *
        !            71:  * Block/character interface to a vnode.  Allows one to treat a file
        !            72:  * as a disk (e.g. build a filesystem in it, mount it, etc.).
        !            73:  *
        !            74:  * NOTE 1: This uses the VOP_BMAP/VOP_STRATEGY interface to the vnode
        !            75:  * instead of a simple VOP_RDWR.  We do this to avoid distorting the
        !            76:  * local buffer cache.
        !            77:  *
        !            78:  * NOTE 2: There is a security issue involved with this driver.
        !            79:  * Once mounted all access to the contents of the "mapped" file via
        !            80:  * the special file is controlled by the permissions on the special
        !            81:  * file, the protection of the mapped file is ignored (effectively,
        !            82:  * by using root credentials in all transactions).
        !            83:  *
        !            84:  * NOTE 3: Doesn't interact with leases, should it?
        !            85:  */
        !            86: #include "vnd.h"
        !            87: #if NVND > 0
        !            88: 
        !            89: #include <sys/param.h>
        !            90: #include <sys/systm.h>
        !            91: #include <sys/namei.h>
        !            92: #include <sys/proc.h>
        !            93: #include <sys/errno.h>
        !            94: #include <sys/dkstat.h>
        !            95: #include <sys/buf.h>
        !            96: #include <sys/malloc.h>
        !            97: #include <sys/ioctl.h>
        !            98: #include <sys/disklabel.h>
        !            99: #include <sys/mount.h>
        !           100: #include <sys/vnode.h>
        !           101: #include <sys/file.h>
        !           102: #include <sys/uio.h>
        !           103: 
        !           104: #include <miscfs/specfs/specdev.h>
        !           105: 
        !           106: #include <dev/vndioctl.h>
        !           107: 
        !           108: #ifdef DEBUG
        !           109: int dovndcluster = 1;
        !           110: int vnddebug = 0x00;
        !           111: #define VDB_FOLLOW     0x01
        !           112: #define VDB_INIT       0x02
        !           113: #define VDB_IO         0x04
        !           114: #endif
        !           115: 
        !           116: #define b_cylin        b_resid
        !           117: 
        !           118: #define        vndunit(x)      DISKUNIT(x)
        !           119: 
        !           120: struct vndbuf {
        !           121:        struct buf      vb_buf;
        !           122:        struct buf      *vb_obp;
        !           123: };
        !           124: 
        !           125: //#define      getvndbuf()     \
        !           126: //     ((struct vndbuf *)malloc(sizeof(struct vndbuf), M_DEVBUF, M_WAITOK))
        !           127: #define putvndbuf(vbp) \
        !           128:        free((caddr_t)(vbp), M_DEVBUF)
        !           129: 
        !           130: struct vnd_softc {
        !           131:        int              sc_flags;      /* flags */
        !           132:        size_t           sc_size;       /* size of vnd */
        !           133:        struct vnode    *sc_vp;         /* vnode */
        !           134:        struct ucred    *sc_cred;       /* credentials */
        !           135:        int              sc_maxactive;  /* max # of active requests */
        !           136:        struct buf       sc_tab;        /* transfer queue */
        !           137: };
        !           138: 
        !           139: /* sc_flags */
        !           140: #define        VNF_ALIVE       0x01
        !           141: #define VNF_INITED     0x02
        !           142: 
        !           143: #if 0  /* if you need static allocation */
        !           144: struct vnd_softc vn_softc[NVND];
        !           145: int numvnd = NVND;
        !           146: #else
        !           147: struct vnd_softc *vnd_softc;
        !           148: int numvnd;
        !           149: #endif
        !           150: 
        !           151: void   vndclear __P((struct vnd_softc *));
        !           152: void   vndstart __P((struct vnd_softc *));
        !           153: int    vndsetcred __P((struct vnd_softc *, struct ucred *));
        !           154: void   vndthrottle __P((struct vnd_softc *, struct vnode *));
        !           155: 
        !           156: void
        !           157: vndattach(num)
        !           158:        int num;
        !           159: {
        !           160:        char *mem;
        !           161:        register u_long size;
        !           162: 
        !           163:        if (num <= 0)
        !           164:                return;
        !           165:        size = num * sizeof(struct vnd_softc);
        !           166: //     mem = malloc(size, M_DEVBUF, M_NOWAIT);
        !           167:        MALLOC(mem, char *, size, M_DEVBUF, M_NOWAIT);
        !           168:        if (mem == NULL) {
        !           169:                printf("WARNING: no memory for vnode disks\n");
        !           170:                return;
        !           171:        }
        !           172:        bzero(mem, size);
        !           173:        vnd_softc = (struct vnd_softc *)mem;
        !           174:        numvnd = num;
        !           175: }
        !           176: 
        !           177: int
        !           178: vndopen(dev, flags, mode, p)
        !           179:        dev_t dev;
        !           180:        int flags, mode;
        !           181:        struct proc *p;
        !           182: {
        !           183:        int unit = vndunit(dev);
        !           184: 
        !           185: #ifdef DEBUG
        !           186:        if (vnddebug & VDB_FOLLOW)
        !           187:                printf("vndopen(%x, %x, %x, %x)\n", dev, flags, mode, p);
        !           188: #endif
        !           189:        if (unit >= numvnd)
        !           190:                return(ENXIO);
        !           191:        return(0);
        !           192: }
        !           193: 
        !           194: int
        !           195: vndclose(dev, flags, mode, p)
        !           196:        dev_t dev;
        !           197:        int flags, mode;
        !           198:        struct proc *p;
        !           199: {
        !           200: #ifdef DEBUG
        !           201:        if (vnddebug & VDB_FOLLOW)
        !           202:                printf("vndclose(%x, %x, %x, %x)\n", dev, flags, mode, p);
        !           203: #endif
        !           204:        return 0;
        !           205: }
        !           206: 
        !           207: /*
        !           208:  * Break the request into bsize pieces and submit using VOP_BMAP/VOP_STRATEGY.
        !           209:  * Note that this driver can only be used for swapping over NFS on the hp
        !           210:  * since nfs_strategy on the vax cannot handle u-areas and page tables.
        !           211:  */
        !           212: void
        !           213: vndstrategy(bp)
        !           214:        register struct buf *bp;
        !           215: {
        !           216:        int unit = vndunit(bp->b_dev);
        !           217:        register struct vnd_softc *vnd = &vnd_softc[unit];
        !           218:        register struct vndbuf *nbp;
        !           219:        register int bn, bsize, resid;
        !           220:        register caddr_t addr;
        !           221:        int sz, flags, error;
        !           222:        extern void vndiodone();
        !           223: 
        !           224: #ifdef DEBUG
        !           225:        if (vnddebug & VDB_FOLLOW)
        !           226:                printf("vndstrategy(%x): unit %d\n", bp, unit);
        !           227: #endif
        !           228:        if ((vnd->sc_flags & VNF_INITED) == 0) {
        !           229:                bp->b_error = ENXIO;
        !           230:                bp->b_flags |= B_ERROR;
        !           231:                biodone(bp);
        !           232:                return;
        !           233:        }
        !           234:        bn = bp->b_blkno;
        !           235:        sz = howmany(bp->b_bcount, DEV_BSIZE);
        !           236:        bp->b_resid = bp->b_bcount;
        !           237:        if (bn < 0 || bn + sz > vnd->sc_size) {
        !           238:                if (bn != vnd->sc_size) {
        !           239:                        bp->b_error = EINVAL;
        !           240:                        bp->b_flags |= B_ERROR;
        !           241:                }
        !           242:                biodone(bp);
        !           243:                return;
        !           244:        }
        !           245:        bn = dbtob(bn);
        !           246:        bsize = vnd->sc_vp->v_mount->mnt_stat.f_iosize;
        !           247:        addr = bp->b_data;
        !           248:        flags = bp->b_flags | B_CALL;
        !           249:        for (resid = bp->b_resid; resid; resid -= sz) {
        !           250:                struct vnode *vp;
        !           251:                daddr_t nbn;
        !           252:                int off, s, nra;
        !           253: 
        !           254:                nra = 0;
        !           255:                error = VOP_BMAP(vnd->sc_vp, bn / bsize, &vp, &nbn, &nra);
        !           256:                if (error == 0 && (long)nbn == -1)
        !           257:                        error = EIO;
        !           258: #ifdef DEBUG
        !           259:                if (!dovndcluster)
        !           260:                        nra = 0;
        !           261: #endif
        !           262: 
        !           263:                if (off = bn % bsize)
        !           264:                        sz = bsize - off;
        !           265:                else
        !           266:                        sz = (1 + nra) * bsize;
        !           267:                if (resid < sz)
        !           268:                        sz = resid;
        !           269: #ifdef DEBUG
        !           270:                if (vnddebug & VDB_IO)
        !           271:                        printf("vndstrategy: vp %x/%x bn %x/%x sz %x\n",
        !           272:                               vnd->sc_vp, vp, bn, nbn, sz);
        !           273: #endif
        !           274: 
        !           275: //             nbp = getvndbuf();
        !           276:                MALLOC(nbp, struct vndbuf *, sizeof(struct vndbuf),M_DEVBUF, M_WAITOK);
        !           277:                nbp->vb_buf.b_flags = flags;
        !           278:                nbp->vb_buf.b_bcount = sz;
        !           279:                nbp->vb_buf.b_bufsize = bp->b_bufsize;
        !           280:                nbp->vb_buf.b_error = 0;
        !           281:                if (vp->v_type == VBLK || vp->v_type == VCHR)
        !           282:                        nbp->vb_buf.b_dev = vp->v_rdev;
        !           283:                else
        !           284:                        nbp->vb_buf.b_dev = NODEV;
        !           285:                nbp->vb_buf.b_data = addr;
        !           286:                nbp->vb_buf.b_blkno = nbn + btodb(off);
        !           287:                nbp->vb_buf.b_proc = bp->b_proc;
        !           288:                nbp->vb_buf.b_iodone = vndiodone;
        !           289:                nbp->vb_buf.b_vp = vp;
        !           290:                nbp->vb_buf.b_rcred = vnd->sc_cred;     /* XXX crdup? */
        !           291:                nbp->vb_buf.b_wcred = vnd->sc_cred;     /* XXX crdup? */
        !           292:                nbp->vb_buf.b_dirtyoff = bp->b_dirtyoff;
        !           293:                nbp->vb_buf.b_dirtyend = bp->b_dirtyend;
        !           294:                nbp->vb_buf.b_validoff = bp->b_validoff;
        !           295:                nbp->vb_buf.b_validend = bp->b_validend;
        !           296: 
        !           297:                /* save a reference to the old buffer */
        !           298:                nbp->vb_obp = bp;
        !           299: 
        !           300:                /*
        !           301:                 * If there was an error or a hole in the file...punt.
        !           302:                 * Note that we deal with this after the nbp allocation.
        !           303:                 * This ensures that we properly clean up any operations
        !           304:                 * that we have already fired off.
        !           305:                 *
        !           306:                 * XXX we could deal with holes here but it would be
        !           307:                 * a hassle (in the write case).
        !           308:                 */
        !           309:                if (error) {
        !           310:                        nbp->vb_buf.b_error = error;
        !           311:                        nbp->vb_buf.b_flags |= B_ERROR;
        !           312:                        bp->b_resid -= (resid - sz);
        !           313:                        biodone(&nbp->vb_buf);
        !           314:                        return;
        !           315:                }
        !           316:                /*
        !           317:                 * Just sort by block number
        !           318:                 */
        !           319:                nbp->vb_buf.b_cylin = nbp->vb_buf.b_blkno;
        !           320:                s = splbio();
        !           321:                disksort(&vnd->sc_tab, &nbp->vb_buf);
        !           322:                if (vnd->sc_tab.b_active < vnd->sc_maxactive) {
        !           323:                        vnd->sc_tab.b_active++;
        !           324:                        vndstart(vnd);
        !           325:                }
        !           326:                splx(s);
        !           327:                bn += sz;
        !           328:                addr += sz;
        !           329:        }
        !           330: }
        !           331: 
        !           332: /*
        !           333:  * Feed requests sequentially.
        !           334:  * We do it this way to keep from flooding NFS servers if we are connected
        !           335:  * to an NFS file.  This places the burden on the client rather than the
        !           336:  * server.
        !           337:  */
        !           338: void
        !           339: vndstart(vnd)
        !           340:        register struct vnd_softc *vnd;
        !           341: {
        !           342:        register struct buf *bp;
        !           343: 
        !           344:        /*
        !           345:         * Dequeue now since lower level strategy routine might
        !           346:         * queue using same links
        !           347:         */
        !           348:        bp = vnd->sc_tab.b_actf;
        !           349:        vnd->sc_tab.b_actf = bp->b_actf;
        !           350: #ifdef DEBUG
        !           351:        if (vnddebug & VDB_IO)
        !           352:                printf("vndstart(%d): bp %x vp %x blkno %x addr %x cnt %x\n",
        !           353:                    vnd-vnd_softc, bp, bp->b_vp, bp->b_blkno, bp->b_data,
        !           354:                    bp->b_bcount);
        !           355: #endif
        !           356:        if ((bp->b_flags & B_READ) == 0)
        !           357:                bp->b_vp->v_numoutput++;
        !           358:        VOP_STRATEGY(bp);
        !           359: }
        !           360: 
        !           361: void
        !           362: vndiodone(vbp)
        !           363:        register struct vndbuf *vbp;
        !           364: {
        !           365:        register struct buf *pbp = vbp->vb_obp;
        !           366:        register struct vnd_softc *vnd = &vnd_softc[vndunit(pbp->b_dev)];
        !           367:        int s;
        !           368: 
        !           369:        s = splbio();
        !           370: #ifdef DEBUG
        !           371:        if (vnddebug & VDB_IO)
        !           372:                printf("vndiodone(%d): vbp %x vp %x blkno %x addr %x cnt %x\n",
        !           373:                    vnd-vnd_softc, vbp, vbp->vb_buf.b_vp, vbp->vb_buf.b_blkno,
        !           374:                    vbp->vb_buf.b_data, vbp->vb_buf.b_bcount);
        !           375: #endif
        !           376:        if (vbp->vb_buf.b_error) {
        !           377: #ifdef DEBUG
        !           378:                if (vnddebug & VDB_IO)
        !           379:                        printf("vndiodone: vbp %x error %d\n", vbp,
        !           380:                            vbp->vb_buf.b_error);
        !           381: #endif
        !           382:                pbp->b_flags |= B_ERROR;
        !           383:                pbp->b_error = biowait(&vbp->vb_buf);
        !           384:        }
        !           385:        pbp->b_resid -= vbp->vb_buf.b_bcount;
        !           386:        putvndbuf(vbp);
        !           387:        if (pbp->b_resid == 0) {
        !           388: #ifdef DEBUG
        !           389:                if (vnddebug & VDB_IO)
        !           390:                        printf("vndiodone: pbp %x iodone\n", pbp);
        !           391: #endif
        !           392:                biodone(pbp);
        !           393:        }
        !           394:        if (vnd->sc_tab.b_actf)
        !           395:                vndstart(vnd);
        !           396:        else
        !           397:                vnd->sc_tab.b_active--;
        !           398:        splx(s);
        !           399: }
        !           400: 
        !           401: /* ARGSUSED */
        !           402: int
        !           403: vndioctl(dev, cmd, data, flag, p)
        !           404:        dev_t dev;
        !           405:        u_long cmd;
        !           406:        caddr_t data;
        !           407:        int flag;
        !           408:        struct proc *p;
        !           409: {
        !           410:        int unit = vndunit(dev);
        !           411:        register struct vnd_softc *vnd;
        !           412:        struct vnd_ioctl *vio;
        !           413:        struct vattr vattr;
        !           414:        struct nameidata nd;
        !           415:        int error;
        !           416: 
        !           417: #ifdef DEBUG
        !           418:        if (vnddebug & VDB_FOLLOW)
        !           419:                printf("vndioctl(%x, %lx, %x, %x, %x): unit %d\n",
        !           420:                    dev, cmd, data, flag, p, unit);
        !           421: #endif
        !           422:        error = suser(p->p_ucred, &p->p_acflag);
        !           423:        if (error)
        !           424:                return (error);
        !           425:        if (unit >= numvnd)
        !           426:                return (ENXIO);
        !           427: 
        !           428:        vnd = &vnd_softc[unit];
        !           429:        vio = (struct vnd_ioctl *)data;
        !           430:        switch (cmd) {
        !           431: 
        !           432:        case VNDIOCSET:
        !           433:                if (vnd->sc_flags & VNF_INITED)
        !           434:                        return(EBUSY);
        !           435:                /*
        !           436:                 * Always open for read and write.
        !           437:                 * This is probably bogus, but it lets vn_open()
        !           438:                 * weed out directories, sockets, etc. so we don't
        !           439:                 * have to worry about them.
        !           440:                 */
        !           441:                NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, vio->vnd_file, p);
        !           442:                if (error = vn_open(&nd, FREAD|FWRITE, 0))
        !           443:                        return(error);
        !           444:                if (error = VOP_GETATTR(nd.ni_vp, &vattr, p->p_ucred, p)) {
        !           445:                        VOP_UNLOCK(nd.ni_vp);
        !           446:                        (void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
        !           447:                        return(error);
        !           448:                }
        !           449:                VOP_UNLOCK(nd.ni_vp);
        !           450:                vnd->sc_vp = nd.ni_vp;
        !           451:                vnd->sc_size = btodb(vattr.va_size);    /* note truncation */
        !           452:                if (error = vndsetcred(vnd, p->p_ucred)) {
        !           453:                        (void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
        !           454:                        return(error);
        !           455:                }
        !           456:                vndthrottle(vnd, vnd->sc_vp);
        !           457:                vio->vnd_size = dbtob(vnd->sc_size);
        !           458:                vnd->sc_flags |= VNF_INITED;
        !           459: #ifdef DEBUG
        !           460:                if (vnddebug & VDB_INIT)
        !           461:                        printf("vndioctl: SET vp %x size %x\n",
        !           462:                            vnd->sc_vp, vnd->sc_size);
        !           463: #endif
        !           464:                break;
        !           465: 
        !           466:        case VNDIOCCLR:
        !           467:                if ((vnd->sc_flags & VNF_INITED) == 0)
        !           468:                        return(ENXIO);
        !           469:                vndclear(vnd);
        !           470: #ifdef DEBUG
        !           471:                if (vnddebug & VDB_INIT)
        !           472:                        printf("vndioctl: CLRed\n");
        !           473: #endif
        !           474:                break;
        !           475: 
        !           476:        default:
        !           477:                return(ENOTTY);
        !           478:        }
        !           479:        return(0);
        !           480: }
        !           481: 
        !           482: /*
        !           483:  * Duplicate the current processes' credentials.  Since we are called only
        !           484:  * as the result of a SET ioctl and only root can do that, any future access
        !           485:  * to this "disk" is essentially as root.  Note that credentials may change
        !           486:  * if some other uid can write directly to the mapped file (NFS).
        !           487:  */
        !           488: int
        !           489: vndsetcred(vnd, cred)
        !           490:        register struct vnd_softc *vnd;
        !           491:        struct ucred *cred;
        !           492: {
        !           493:        struct uio auio;
        !           494:        struct iovec aiov;
        !           495:        char *tmpbuf;
        !           496:        int error;
        !           497: 
        !           498:        vnd->sc_cred = crdup(cred);
        !           499: //     tmpbuf = malloc(DEV_BSIZE, M_TEMP, M_WAITOK);
        !           500:        MALLOC(tmpbuf, char *, DEV_BSIZE, M_TEMP, M_WAITOK);
        !           501: 
        !           502:        /* XXX: Horrible kludge to establish credentials for NFS */
        !           503:        aiov.iov_base = tmpbuf;
        !           504:        aiov.iov_len = min(DEV_BSIZE, dbtob(vnd->sc_size));
        !           505:        auio.uio_iov = &aiov;
        !           506:        auio.uio_iovcnt = 1;
        !           507:        auio.uio_offset = 0;
        !           508:        auio.uio_rw = UIO_READ;
        !           509:        auio.uio_segflg = UIO_SYSSPACE;
        !           510:        auio.uio_resid = aiov.iov_len;
        !           511:        error = VOP_READ(vnd->sc_vp, &auio, 0, vnd->sc_cred);
        !           512: 
        !           513:        free(tmpbuf, M_TEMP);
        !           514:        return (error);
        !           515: }
        !           516: 
        !           517: /*
        !           518:  * Set maxactive based on FS type
        !           519:  */
        !           520: void
        !           521: vndthrottle(vnd, vp)
        !           522:        register struct vnd_softc *vnd;
        !           523:        struct vnode *vp;
        !           524: {
        !           525: #ifdef NFSCLIENT
        !           526:        extern int (**nfsv2_vnodeop_p)();
        !           527: 
        !           528:        if (vp->v_op == nfsv2_vnodeop_p)
        !           529:                vnd->sc_maxactive = 2;
        !           530:        else
        !           531: #endif
        !           532:                vnd->sc_maxactive = 8;
        !           533: 
        !           534:        if (vnd->sc_maxactive < 1)
        !           535:                vnd->sc_maxactive = 1;
        !           536: }
        !           537: 
        !           538: void
        !           539: vndshutdown()
        !           540: {
        !           541:        register struct vnd_softc *vnd;
        !           542: 
        !           543:        for (vnd = &vnd_softc[0]; vnd < &vnd_softc[numvnd]; vnd++)
        !           544:                if (vnd->sc_flags & VNF_INITED)
        !           545:                        vndclear(vnd);
        !           546: }
        !           547: 
        !           548: void
        !           549: vndclear(vnd)
        !           550:        register struct vnd_softc *vnd;
        !           551: {
        !           552:        register struct vnode *vp = vnd->sc_vp;
        !           553:        struct proc *p = curproc;               /* XXX */
        !           554:        struct ucred    *cred;
        !           555: 
        !           556: #ifdef DEBUG
        !           557:        if (vnddebug & VDB_FOLLOW)
        !           558:                printf("vndclear(%x): vp %x\n", vp);
        !           559: #endif
        !           560:        vnd->sc_flags &= ~VNF_INITED;
        !           561:        if (vp == (struct vnode *)0)
        !           562:                panic("vndioctl: null vp");
        !           563:        (void) vn_close(vp, FREAD|FWRITE, vnd->sc_cred, p);
        !           564:        cred = vnd->sc_cred;
        !           565:        if (cred != NOCRED) {
        !           566:                vnd->sc_cred = NOCRED;
        !           567:                crfree(cred);
        !           568:        }
        !           569:        vnd->sc_vp = (struct vnode *)0;
        !           570:        vnd->sc_size = 0;
        !           571: }
        !           572: 
        !           573: int
        !           574: vndsize(dev)
        !           575:        dev_t dev;
        !           576: {
        !           577:        int unit = vndunit(dev);
        !           578:        register struct vnd_softc *vnd = &vnd_softc[unit];
        !           579: 
        !           580:        if (unit >= numvnd || (vnd->sc_flags & VNF_INITED) == 0)
        !           581:                return(-1);
        !           582:        return(vnd->sc_size);
        !           583: }
        !           584: 
        !           585: int
        !           586: vnddump(dev)
        !           587:        dev_t dev;
        !           588: {
        !           589: 
        !           590:        return(ENXIO);
        !           591: }
        !           592: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.