Annotation of Net2/nfs/nfs_vfsops.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1989 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Rick Macklem at The University of Guelph.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by the University of
                     19:  *     California, Berkeley and its contributors.
                     20:  * 4. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  *
                     36:  *     @(#)nfs_vfsops.c        7.31 (Berkeley) 5/6/91
                     37:  */
                     38: 
                     39: #include "param.h"
                     40: #include "conf.h"
                     41: #include "ioctl.h"
                     42: #include "signal.h"
                     43: #include "proc.h"
                     44: #include "namei.h"
                     45: #include "vnode.h"
                     46: #include "mount.h"
                     47: #include "buf.h"
                     48: #include "mbuf.h"
                     49: #include "socket.h"
                     50: #include "systm.h"
                     51: 
                     52: #include "../net/if.h"
                     53: #include "../net/route.h"
                     54: #include "../netinet/in.h"
                     55: 
                     56: #include "nfsv2.h"
                     57: #include "nfsnode.h"
                     58: #include "nfsmount.h"
                     59: #include "nfs.h"
                     60: #include "xdr_subs.h"
                     61: #include "nfsm_subs.h"
                     62: #include "nfsdiskless.h"
                     63: 
                     64: /*
                     65:  * nfs vfs operations.
                     66:  */
                     67: struct vfsops nfs_vfsops = {
                     68:        nfs_mount,
                     69:        nfs_start,
                     70:        nfs_unmount,
                     71:        nfs_root,
                     72:        nfs_quotactl,
                     73:        nfs_statfs,
                     74:        nfs_sync,
                     75:        nfs_fhtovp,
                     76:        nfs_vptofh,
                     77:        nfs_init,
                     78: };
                     79: 
                     80: static u_char nfs_mntid;
                     81: extern u_long nfs_procids[NFS_NPROCS];
                     82: extern u_long nfs_prog, nfs_vers;
                     83: struct nfs_diskless nfs_diskless;
                     84: void nfs_disconnect();
                     85: 
                     86: #define TRUE   1
                     87: #define        FALSE   0
                     88: 
                     89: /*
                     90:  * nfs statfs call
                     91:  */
                     92: nfs_statfs(mp, sbp, p)
                     93:        struct mount *mp;
                     94:        register struct statfs *sbp;
                     95:        struct proc *p;
                     96: {
                     97:        register struct vnode *vp;
                     98:        register struct nfsv2_statfs *sfp;
                     99:        register caddr_t cp;
                    100:        register long t1;
                    101:        caddr_t bpos, dpos, cp2;
                    102:        u_long xid;
                    103:        int error = 0;
                    104:        struct mbuf *mreq, *mrep, *md, *mb, *mb2;
                    105:        struct nfsmount *nmp;
                    106:        struct ucred *cred;
                    107:        struct nfsnode *np;
                    108: 
                    109:        nmp = VFSTONFS(mp);
                    110:        if (error = nfs_nget(mp, &nmp->nm_fh, &np))
                    111:                return (error);
                    112:        vp = NFSTOV(np);
                    113:        nfsstats.rpccnt[NFSPROC_STATFS]++;
                    114:        cred = crget();
                    115:        cred->cr_ngroups = 1;
                    116:        nfsm_reqhead(nfs_procids[NFSPROC_STATFS], cred, NFSX_FH);
                    117:        nfsm_fhtom(vp);
                    118:        nfsm_request(vp, NFSPROC_STATFS, p, 0);
                    119:        nfsm_disect(sfp, struct nfsv2_statfs *, NFSX_STATFS);
                    120:        sbp->f_type = MOUNT_NFS;
                    121:        sbp->f_flags = nmp->nm_flag;
                    122:        sbp->f_bsize = fxdr_unsigned(long, sfp->sf_tsize);
                    123:        sbp->f_fsize = fxdr_unsigned(long, sfp->sf_bsize);
                    124:        sbp->f_blocks = fxdr_unsigned(long, sfp->sf_blocks);
                    125:        sbp->f_bfree = fxdr_unsigned(long, sfp->sf_bfree);
                    126:        sbp->f_bavail = fxdr_unsigned(long, sfp->sf_bavail);
                    127:        sbp->f_files = 0;
                    128:        sbp->f_ffree = 0;
                    129:        if (sbp != &mp->mnt_stat) {
                    130:                bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
                    131:                bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
                    132:        }
                    133:        nfsm_reqdone;
                    134:        nfs_nput(vp);
                    135:        crfree(cred);
                    136:        return (error);
                    137: }
                    138: 
                    139: /*
                    140:  * Mount a remote root fs via. nfs. This depends on the info in the
                    141:  * nfs_diskless structure that has been filled in properly by some primary
                    142:  * bootstrap.
                    143:  * It goes something like this:
                    144:  * - do enough of "ifconfig" by calling ifioctl() so that the system
                    145:  *   can talk to the server
                    146:  * - If nfs_diskless.mygateway is filled in, use that address as
                    147:  *   a default gateway.
                    148:  *   (This is done the 4.3 way with rtioctl() and should be changed)
                    149:  * - hand craft the swap nfs vnode hanging off a fake mount point
                    150:  * - build the rootfs mount point and call mountnfs() to do the rest.
                    151:  */
                    152: nfs_mountroot()
                    153: {
                    154:        register struct mount *mp;
                    155:        register struct mbuf *m;
                    156:        struct socket *so;
                    157:        struct vnode *vp;
                    158:        int error;
                    159: 
                    160:        /*
                    161:         * Do enough of ifconfig(8) so that critical net interface can
                    162:         * talk to the server.
                    163:         */
                    164:        if (socreate(nfs_diskless.myif.ifra_addr.sa_family, &so, SOCK_DGRAM, 0))
                    165:                panic("nfs ifconf");
                    166:        if (ifioctl(so, SIOCAIFADDR, &nfs_diskless.myif))
                    167:                panic("nfs ifconf2");
                    168:        soclose(so);
                    169: 
                    170:        /*
                    171:         * If the gateway field is filled in, set it as the default route.
                    172:         */
                    173: #ifdef COMPAT_43
                    174:        if (nfs_diskless.mygateway.sa_family == AF_INET) {
                    175:                struct ortentry rt;
                    176:                struct sockaddr_in *sin;
                    177: 
                    178:                sin = (struct sockaddr_in *) &rt.rt_dst;
                    179:                sin->sin_len = sizeof (struct sockaddr_in);
                    180:                sin->sin_family = AF_INET;
                    181:                sin->sin_addr.s_addr = 0;       /* default */
                    182:                bcopy((caddr_t)&nfs_diskless.mygateway, (caddr_t)&rt.rt_gateway,
                    183:                        sizeof (struct sockaddr_in));
                    184:                rt.rt_flags = (RTF_UP | RTF_GATEWAY);
                    185:                if (rtioctl(SIOCADDRT, (caddr_t)&rt))
                    186:                        panic("nfs root route");
                    187:        }
                    188: #endif /* COMPAT_43 */
                    189: 
                    190:        /*
                    191:         * If swapping to an nfs node (indicated by swdevt[0].sw_dev == NODEV):
                    192:         * Create a fake mount point just for the swap vnode so that the
                    193:         * swap file can be on a different server from the rootfs.
                    194:         */
                    195:        if (swdevt[0].sw_dev == NODEV) {
                    196:                mp = (struct mount *)malloc((u_long)sizeof(struct mount),
                    197:                        M_MOUNT, M_NOWAIT);
                    198:                if (mp == NULL)
                    199:                        panic("nfs root mount");
                    200:                mp->mnt_op = &nfs_vfsops;
                    201:                mp->mnt_flag = 0;
                    202:                mp->mnt_exroot = 0;
                    203:                mp->mnt_mounth = NULLVP;
                    204:        
                    205:                /*
                    206:                 * Set up the diskless nfs_args for the swap mount point
                    207:                 * and then call mountnfs() to mount it.
                    208:                 * Since the swap file is not the root dir of a file system,
                    209:                 * hack it to a regular file.
                    210:                 */
                    211:                nfs_diskless.swap_args.fh = (nfsv2fh_t *)nfs_diskless.swap_fh;
                    212:                MGET(m, MT_SONAME, M_DONTWAIT);
                    213:                if (m == NULL)
                    214:                        panic("nfs root mbuf");
                    215:                bcopy((caddr_t)&nfs_diskless.swap_saddr, mtod(m, caddr_t),
                    216:                        nfs_diskless.swap_saddr.sa_len);
                    217:                m->m_len = nfs_diskless.swap_saddr.sa_len;
                    218:                if (mountnfs(&nfs_diskless.swap_args, mp, m, "/swap",
                    219:                        nfs_diskless.swap_hostnam, &vp))
                    220:                        panic("nfs swap");
                    221:                vp->v_type = VREG;
                    222:                vp->v_flag = 0;
                    223:                swapdev_vp = vp;
                    224:                VREF(vp);
                    225:                swdevt[0].sw_vp = vp;
                    226:        }
                    227: 
                    228:        /*
                    229:         * Create the rootfs mount point.
                    230:         */
                    231:        mp = (struct mount *)malloc((u_long)sizeof(struct mount),
                    232:                M_MOUNT, M_NOWAIT);
                    233:        if (mp == NULL)
                    234:                panic("nfs root mount2");
                    235:        mp->mnt_op = &nfs_vfsops;
                    236:        mp->mnt_flag = MNT_RDONLY;
                    237:        mp->mnt_exroot = 0;
                    238:        mp->mnt_mounth = NULLVP;
                    239: 
                    240:        /*
                    241:         * Set up the root fs args and call mountnfs() to do the rest.
                    242:         */
                    243:        nfs_diskless.root_args.fh = (nfsv2fh_t *)nfs_diskless.root_fh;
                    244:        MGET(m, MT_SONAME, M_DONTWAIT);
                    245:        if (m == NULL)
                    246:                panic("nfs root mbuf2");
                    247:        bcopy((caddr_t)&nfs_diskless.root_saddr, mtod(m, caddr_t),
                    248:                nfs_diskless.root_saddr.sa_len);
                    249:        m->m_len = nfs_diskless.root_saddr.sa_len;
                    250:        if (mountnfs(&nfs_diskless.root_args, mp, m, "/",
                    251:                nfs_diskless.root_hostnam, &vp))
                    252:                panic("nfs root");
                    253:        if (vfs_lock(mp))
                    254:                panic("nfs root2");
                    255:        rootfs = mp;
                    256:        mp->mnt_next = mp;
                    257:        mp->mnt_prev = mp;
                    258:        mp->mnt_vnodecovered = NULLVP;
                    259:        vfs_unlock(mp);
                    260:        rootvp = vp;
                    261:        inittodr((time_t)0);    /* There is no time in the nfs fsstat so ?? */
                    262:        return (0);
                    263: }
                    264: 
                    265: /*
                    266:  * VFS Operations.
                    267:  *
                    268:  * mount system call
                    269:  * It seems a bit dumb to copyinstr() the host and path here and then
                    270:  * bcopy() them in mountnfs(), but I wanted to detect errors before
                    271:  * doing the sockargs() call because sockargs() allocates an mbuf and
                    272:  * an error after that means that I have to release the mbuf.
                    273:  */
                    274: /* ARGSUSED */
                    275: nfs_mount(mp, path, data, ndp, p)
                    276:        struct mount *mp;
                    277:        char *path;
                    278:        caddr_t data;
                    279:        struct nameidata *ndp;
                    280:        struct proc *p;
                    281: {
                    282:        int error;
                    283:        struct nfs_args args;
                    284:        struct mbuf *nam;
                    285:        struct vnode *vp;
                    286:        char pth[MNAMELEN], hst[MNAMELEN];
                    287:        u_int len;
                    288:        nfsv2fh_t nfh;
                    289: 
                    290:        if (mp->mnt_flag & MNT_UPDATE)
                    291:                return (0);
                    292:        if (error = copyin(data, (caddr_t)&args, sizeof (struct nfs_args)))
                    293:                return (error);
                    294:        if (error = copyin((caddr_t)args.fh, (caddr_t)&nfh, sizeof (nfsv2fh_t)))
                    295:                return (error);
                    296:        if (error = copyinstr(path, pth, MNAMELEN-1, &len))
                    297:                return (error);
                    298:        bzero(&pth[len], MNAMELEN - len);
                    299:        if (error = copyinstr(args.hostname, hst, MNAMELEN-1, &len))
                    300:                return (error);
                    301:        bzero(&hst[len], MNAMELEN - len);
                    302:        /* sockargs() call must be after above copyin() calls */
                    303:        if (error = sockargs(&nam, (caddr_t)args.addr,
                    304:                sizeof (struct sockaddr), MT_SONAME))
                    305:                return (error);
                    306:        args.fh = &nfh;
                    307:        error = mountnfs(&args, mp, nam, pth, hst, &vp);
                    308:        return (error);
                    309: }
                    310: 
                    311: /*
                    312:  * Common code for mount and mountroot
                    313:  */
                    314: mountnfs(argp, mp, nam, pth, hst, vpp)
                    315:        register struct nfs_args *argp;
                    316:        register struct mount *mp;
                    317:        struct mbuf *nam;
                    318:        char *pth, *hst;
                    319:        struct vnode **vpp;
                    320: {
                    321:        register struct nfsmount *nmp;
                    322:        struct proc *p = curproc;               /* XXX */
                    323:        struct nfsnode *np;
                    324:        int error;
                    325:        fsid_t tfsid;
                    326: 
                    327:        MALLOC(nmp, struct nfsmount *, sizeof *nmp, M_NFSMNT, M_WAITOK);
                    328:        bzero((caddr_t)nmp, sizeof *nmp);
                    329:        mp->mnt_data = (qaddr_t)nmp;
                    330:        /*
                    331:         * Generate a unique nfs mount id. The problem is that a dev number
                    332:         * is not unique across multiple systems. The techique is as follows:
                    333:         * 1) Set to nblkdev,0 which will never be used otherwise
                    334:         * 2) Generate a first guess as nblkdev,nfs_mntid where nfs_mntid is
                    335:         *      NOT 0
                    336:         * 3) Loop searching the mount list for another one with same id
                    337:         *      If a match, increment val[0] and try again
                    338:         * NB: I increment val[0] { a long } instead of nfs_mntid { a u_char }
                    339:         *      so that nfs is not limited to 255 mount points
                    340:         *     Incrementing the high order bits does no real harm, since it
                    341:         *     simply makes the major dev number tick up. The upper bound is
                    342:         *     set to major dev 127 to avoid any sign extention problems
                    343:         */
                    344:        mp->mnt_stat.f_fsid.val[0] = makedev(nblkdev, 0);
                    345:        mp->mnt_stat.f_fsid.val[1] = MOUNT_NFS;
                    346:        if (++nfs_mntid == 0)
                    347:                ++nfs_mntid;
                    348:        tfsid.val[0] = makedev(nblkdev, nfs_mntid);
                    349:        tfsid.val[1] = MOUNT_NFS;
                    350:        while (rootfs && getvfs(&tfsid)) {
                    351:                tfsid.val[0]++;
                    352:                nfs_mntid++;
                    353:        }
                    354:        if (major(tfsid.val[0]) > 127) {
                    355:                error = ENOENT;
                    356:                goto bad;
                    357:        }
                    358:        mp->mnt_stat.f_fsid.val[0] = tfsid.val[0];
                    359:        nmp->nm_mountp = mp;
                    360:        nmp->nm_flag = argp->flags;
                    361:        nmp->nm_rto = NFS_TIMEO;
                    362:        nmp->nm_rtt = -1;
                    363:        nmp->nm_rttvar = nmp->nm_rto << 1;
                    364:        nmp->nm_retry = NFS_RETRANS;
                    365:        nmp->nm_wsize = NFS_WSIZE;
                    366:        nmp->nm_rsize = NFS_RSIZE;
                    367:        bcopy((caddr_t)argp->fh, (caddr_t)&nmp->nm_fh, sizeof(nfsv2fh_t));
                    368:        bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
                    369:        bcopy(pth, mp->mnt_stat.f_mntonname, MNAMELEN);
                    370:        nmp->nm_nam = nam;
                    371: 
                    372:        if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
                    373:                nmp->nm_rto = argp->timeo;
                    374:                /* NFS timeouts are specified in 1/10 sec. */
                    375:                nmp->nm_rto = (nmp->nm_rto * 10) / NFS_HZ;
                    376:                if (nmp->nm_rto < NFS_MINTIMEO)
                    377:                        nmp->nm_rto = NFS_MINTIMEO;
                    378:                else if (nmp->nm_rto > NFS_MAXTIMEO)
                    379:                        nmp->nm_rto = NFS_MAXTIMEO;
                    380:                nmp->nm_rttvar = nmp->nm_rto << 1;
                    381:        }
                    382: 
                    383:        if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
                    384:                nmp->nm_retry = argp->retrans;
                    385:                if (nmp->nm_retry > NFS_MAXREXMIT)
                    386:                        nmp->nm_retry = NFS_MAXREXMIT;
                    387:        }
                    388: 
                    389:        if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
                    390:                nmp->nm_wsize = argp->wsize;
                    391:                /* Round down to multiple of blocksize */
                    392:                nmp->nm_wsize &= ~0x1ff;
                    393:                if (nmp->nm_wsize <= 0)
                    394:                        nmp->nm_wsize = 512;
                    395:                else if (nmp->nm_wsize > NFS_MAXDATA)
                    396:                        nmp->nm_wsize = NFS_MAXDATA;
                    397:        }
                    398:        if (nmp->nm_wsize > MAXBSIZE)
                    399:                nmp->nm_wsize = MAXBSIZE;
                    400: 
                    401:        if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
                    402:                nmp->nm_rsize = argp->rsize;
                    403:                /* Round down to multiple of blocksize */
                    404:                nmp->nm_rsize &= ~0x1ff;
                    405:                if (nmp->nm_rsize <= 0)
                    406:                        nmp->nm_rsize = 512;
                    407:                else if (nmp->nm_rsize > NFS_MAXDATA)
                    408:                        nmp->nm_rsize = NFS_MAXDATA;
                    409:        }
                    410:        if (nmp->nm_rsize > MAXBSIZE)
                    411:                nmp->nm_rsize = MAXBSIZE;
                    412:        /* Set up the sockets and per-host congestion */
                    413:        nmp->nm_sotype = argp->sotype;
                    414:        nmp->nm_soproto = argp->proto;
                    415:        if (error = nfs_connect(nmp))
                    416:                goto bad;
                    417: 
                    418:        if (error = nfs_statfs(mp, &mp->mnt_stat, p))
                    419:                goto bad;
                    420:        /*
                    421:         * A reference count is needed on the nfsnode representing the
                    422:         * remote root.  If this object is not persistent, then backward
                    423:         * traversals of the mount point (i.e. "..") will not work if
                    424:         * the nfsnode gets flushed out of the cache. Ufs does not have
                    425:         * this problem, because one can identify root inodes by their
                    426:         * number == ROOTINO (2).
                    427:         */
                    428:        if (error = nfs_nget(mp, &nmp->nm_fh, &np))
                    429:                goto bad;
                    430:        /*
                    431:         * Unlock it, but keep the reference count.
                    432:         */
                    433:        nfs_unlock(NFSTOV(np));
                    434:        *vpp = NFSTOV(np);
                    435: 
                    436:        return (0);
                    437: bad:
                    438:        nfs_disconnect(nmp);
                    439:        FREE(nmp, M_NFSMNT);
                    440:        m_freem(nam);
                    441:        return (error);
                    442: }
                    443: 
                    444: /*
                    445:  * unmount system call
                    446:  */
                    447: nfs_unmount(mp, mntflags, p)
                    448:        struct mount *mp;
                    449:        int mntflags;
                    450:        struct proc *p;
                    451: {
                    452:        register struct nfsmount *nmp;
                    453:        struct nfsnode *np;
                    454:        struct vnode *vp;
                    455:        int error, flags = 0;
                    456:        extern int doforce;
                    457: 
                    458:        if (mntflags & MNT_FORCE) {
                    459:                if (!doforce || mp == rootfs)
                    460:                        return (EINVAL);
                    461:                flags |= FORCECLOSE;
                    462:        }
                    463:        nmp = VFSTONFS(mp);
                    464:        /*
                    465:         * Clear out the buffer cache
                    466:         */
                    467:        mntflushbuf(mp, 0);
                    468:        if (mntinvalbuf(mp))
                    469:                return (EBUSY);
                    470:        /*
                    471:         * Goes something like this..
                    472:         * - Check for activity on the root vnode (other than ourselves).
                    473:         * - Call vflush() to clear out vnodes for this file system,
                    474:         *   except for the root vnode.
                    475:         * - Decrement reference on the vnode representing remote root.
                    476:         * - Close the socket
                    477:         * - Free up the data structures
                    478:         */
                    479:        /*
                    480:         * We need to decrement the ref. count on the nfsnode representing
                    481:         * the remote root.  See comment in mountnfs().  The VFS unmount()
                    482:         * has done vput on this vnode, otherwise we would get deadlock!
                    483:         */
                    484:        if (error = nfs_nget(mp, &nmp->nm_fh, &np))
                    485:                return(error);
                    486:        vp = NFSTOV(np);
                    487:        if (vp->v_usecount > 2) {
                    488:                vput(vp);
                    489:                return (EBUSY);
                    490:        }
                    491:        if (error = vflush(mp, vp, flags)) {
                    492:                vput(vp);
                    493:                return (error);
                    494:        }
                    495:        /*
                    496:         * Get rid of two reference counts, and unlock it on the second.
                    497:         */
                    498:        vrele(vp);
                    499:        vput(vp);
                    500:        nfs_disconnect(nmp);
                    501:        m_freem(nmp->nm_nam);
                    502:        free((caddr_t)nmp, M_NFSMNT);
                    503:        return (0);
                    504: }
                    505: 
                    506: /*
                    507:  * Return root of a filesystem
                    508:  */
                    509: nfs_root(mp, vpp)
                    510:        struct mount *mp;
                    511:        struct vnode **vpp;
                    512: {
                    513:        register struct vnode *vp;
                    514:        struct nfsmount *nmp;
                    515:        struct nfsnode *np;
                    516:        int error;
                    517: 
                    518:        nmp = VFSTONFS(mp);
                    519:        if (error = nfs_nget(mp, &nmp->nm_fh, &np))
                    520:                return (error);
                    521:        vp = NFSTOV(np);
                    522:        vp->v_type = VDIR;
                    523:        vp->v_flag = VROOT;
                    524:        *vpp = vp;
                    525:        return (0);
                    526: }
                    527: 
                    528: extern int syncprt;
                    529: 
                    530: /*
                    531:  * Flush out the buffer cache
                    532:  */
                    533: /* ARGSUSED */
                    534: nfs_sync(mp, waitfor)
                    535:        struct mount *mp;
                    536:        int waitfor;
                    537: {
                    538:        if (syncprt)
                    539:                bufstats();
                    540:        /*
                    541:         * Force stale buffer cache information to be flushed.
                    542:         */
                    543:        mntflushbuf(mp, waitfor == MNT_WAIT ? B_SYNC : 0);
                    544:        return (0);
                    545: }
                    546: 
                    547: /*
                    548:  * At this point, this should never happen
                    549:  */
                    550: /* ARGSUSED */
                    551: nfs_fhtovp(mp, fhp, vpp)
                    552:        struct mount *mp;
                    553:        struct fid *fhp;
                    554:        struct vnode **vpp;
                    555: {
                    556: 
                    557:        return (EINVAL);
                    558: }
                    559: 
                    560: /*
                    561:  * Vnode pointer to File handle, should never happen either
                    562:  */
                    563: /* ARGSUSED */
                    564: nfs_vptofh(vp, fhp)
                    565:        struct vnode *vp;
                    566:        struct fid *fhp;
                    567: {
                    568: 
                    569:        return (EINVAL);
                    570: }
                    571: 
                    572: /*
                    573:  * Vfs start routine, a no-op.
                    574:  */
                    575: /* ARGSUSED */
                    576: nfs_start(mp, flags, p)
                    577:        struct mount *mp;
                    578:        int flags;
                    579:        struct proc *p;
                    580: {
                    581: 
                    582:        return (0);
                    583: }
                    584: 
                    585: /*
                    586:  * Do operations associated with quotas, not supported
                    587:  */
                    588: nfs_quotactl(mp, cmd, uid, arg, p)
                    589:        struct mount *mp;
                    590:        int cmd;
                    591:        uid_t uid;
                    592:        caddr_t arg;
                    593:        struct proc *p;
                    594: {
                    595: #ifdef lint
                    596:        mp = mp; cmd = cmd; uid = uid; arg = arg;
                    597: #endif /* lint */
                    598:        return (EOPNOTSUPP);
                    599: }

unix.superglobalmegacorp.com

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