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

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

unix.superglobalmegacorp.com

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