Annotation of kernel/bsd/dev/vnd.c, revision 1.1.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.