home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / nfs / nfs_vfsops.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-06  |  15.6 KB  |  600 lines

  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. }
  600.