|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.