nfs_nfsdsocket.c revision 284216
117200Swollman/*- 22742Swollman * Copyright (c) 1989, 1993 32742Swollman * The Regents of the University of California. All rights reserved. 42742Swollman * 52742Swollman * This code is derived from software contributed to Berkeley by 62742Swollman * Rick Macklem at The University of Guelph. 714343Swollman * 82742Swollman * Redistribution and use in source and binary forms, with or without 92742Swollman * modification, are permitted provided that the following conditions 102742Swollman * are met: 112742Swollman * 1. Redistributions of source code must retain the above copyright 122742Swollman * notice, this list of conditions and the following disclaimer. 132742Swollman * 2. Redistributions in binary form must reproduce the above copyright 142742Swollman * notice, this list of conditions and the following disclaimer in the 152742Swollman * documentation and/or other materials provided with the distribution. 162742Swollman * 4. Neither the name of the University nor the names of its contributors 172742Swollman * may be used to endorse or promote products derived from this software 182742Swollman * without specific prior written permission. 192742Swollman * 202742Swollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 212742Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 222742Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 232742Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 242742Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 252742Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 262742Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 272742Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 282742Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 292742Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 302742Swollman * SUCH DAMAGE. 312742Swollman * 322742Swollman */ 332742Swollman 342742Swollman#include <sys/cdefs.h> 3514343Swollman__FBSDID("$FreeBSD: stable/10/sys/fs/nfsserver/nfs_nfsdsocket.c 284216 2015-06-10 12:17:19Z rmacklem $"); 3614343Swollman 3714343Swollman/* 3814343Swollman * Socket operations for use by the nfs server. 3917200Swollman */ 4014343Swollman 4114343Swollman#ifndef APPLEKEXT 4214343Swollman#include <fs/nfs/nfsport.h> 4314343Swollman 4414343Swollmanextern struct nfsstats newnfsstats; 4514343Swollmanextern struct nfsrvfh nfs_pubfh, nfs_rootfh; 462742Swollmanextern int nfs_pubfhset, nfs_rootfhset; 472742Swollmanextern struct nfsv4lock nfsv4rootfs_lock; 482742Swollmanextern struct nfsrv_stablefirst nfsrv_stablefirst; 492742Swollmanextern struct nfsclienthashhead *nfsclienthash; 502742Swollmanextern int nfsrv_clienthashsize; 512742Swollmanextern int nfsrc_floodlevel, nfsrc_tcpsavedreplies; 522742Swollmanextern int nfsd_debuglevel; 532742SwollmanNFSV4ROOTLOCKMUTEX; 542742SwollmanNFSSTATESPINLOCK; 552742Swollman 569908Swollmanint (*nfsrv3_procs0[NFS_V3NPROCS])(struct nfsrv_descript *, 5714343Swollman int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = { 589908Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 599908Swollman nfsrvd_getattr, 609908Swollman nfsrvd_setattr, 619908Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 629908Swollman nfsrvd_access, 639908Swollman nfsrvd_readlink, 649908Swollman nfsrvd_read, 659908Swollman nfsrvd_write, 669908Swollman nfsrvd_create, 679908Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 6814343Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 6914343Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 709908Swollman nfsrvd_remove, 719908Swollman nfsrvd_remove, 729908Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 739908Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 749908Swollman nfsrvd_readdir, 759908Swollman nfsrvd_readdirplus, 769908Swollman nfsrvd_statfs, 772742Swollman nfsrvd_fsinfo, 782742Swollman nfsrvd_pathconf, 792742Swollman nfsrvd_commit, 802742Swollman}; 812742Swollman 822742Swollmanint (*nfsrv3_procs1[NFS_V3NPROCS])(struct nfsrv_descript *, 832742Swollman int, vnode_t , vnode_t *, fhandle_t *, 842742Swollman NFSPROC_T *, struct nfsexstuff *) = { 852742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 862742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 872742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 882742Swollman nfsrvd_lookup, 892742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 902742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 912742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 922742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 932742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 942742Swollman nfsrvd_mkdir, 952742Swollman nfsrvd_symlink, 962742Swollman nfsrvd_mknod, 972742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 982742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 992742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 1002742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 1012742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 1022742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 1032742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 1042742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 1052742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 1062742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 1072742Swollman}; 1082742Swollman 1092742Swollmanint (*nfsrv3_procs2[NFS_V3NPROCS])(struct nfsrv_descript *, 1102742Swollman int, vnode_t , vnode_t , NFSPROC_T *, 1112742Swollman struct nfsexstuff *, struct nfsexstuff *) = { 1122742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1132742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1142742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1152742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1162742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1172742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1182742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1192742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1202742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1212742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1222742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1232742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1242742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1252742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 1262742Swollman nfsrvd_rename, 1272742Swollman nfsrvd_link, 12817200Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 12917200Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 13017200Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 13117200Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 13217200Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 13317200Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 13417200Swollman}; 13517200Swollman 13617200Swollmanint (*nfsrv4_ops0[NFSV41_NOPS])(struct nfsrv_descript *, 1372742Swollman int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = { 1382742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1392742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1402742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1412742Swollman nfsrvd_access, 1422742Swollman nfsrvd_close, 1432742Swollman nfsrvd_commit, 1442742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1452742Swollman nfsrvd_delegpurge, 1462742Swollman nfsrvd_delegreturn, 1472742Swollman nfsrvd_getattr, 1482742Swollman nfsrvd_getfh, 1492742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1502742Swollman nfsrvd_lock, 1512742Swollman nfsrvd_lockt, 1522742Swollman nfsrvd_locku, 1532742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1542742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1552742Swollman nfsrvd_verify, 1562742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1572742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1582742Swollman nfsrvd_openconfirm, 1592742Swollman nfsrvd_opendowngrade, 1602742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1612742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1622742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1632742Swollman nfsrvd_read, 1642742Swollman nfsrvd_readdirplus, 1652742Swollman nfsrvd_readlink, 1662742Swollman nfsrvd_remove, 1672742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1682742Swollman nfsrvd_renew, 1692742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1702742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0, 1712742Swollman nfsrvd_secinfo, 1722742Swollman nfsrvd_setattr, 1732742Swollman nfsrvd_setclientid, 1742742Swollman nfsrvd_setclientidcfrm, 1752742Swollman nfsrvd_verify, 1762742Swollman nfsrvd_write, 1772742Swollman nfsrvd_releaselckown, 1782742Swollman nfsrvd_notsupp, 1792742Swollman nfsrvd_notsupp, 1802742Swollman nfsrvd_exchangeid, 1812742Swollman nfsrvd_createsession, 1822742Swollman nfsrvd_destroysession, 1832742Swollman nfsrvd_freestateid, 1842742Swollman nfsrvd_notsupp, 1852742Swollman nfsrvd_notsupp, 1862742Swollman nfsrvd_notsupp, 1872742Swollman nfsrvd_notsupp, 1882742Swollman nfsrvd_notsupp, 1892742Swollman nfsrvd_notsupp, 1902742Swollman nfsrvd_notsupp, 1912742Swollman nfsrvd_sequence, 1922742Swollman nfsrvd_notsupp, 1932742Swollman nfsrvd_notsupp, 1942742Swollman nfsrvd_notsupp, 1952742Swollman nfsrvd_destroyclientid, 1962742Swollman nfsrvd_reclaimcomplete, 1972742Swollman}; 1982742Swollman 1992742Swollmanint (*nfsrv4_ops1[NFSV41_NOPS])(struct nfsrv_descript *, 2002742Swollman int, vnode_t , vnode_t *, fhandle_t *, 2012742Swollman NFSPROC_T *, struct nfsexstuff *) = { 2022742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2032742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2042742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2052742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2062742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2072742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2082742Swollman nfsrvd_mknod, 2092742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2102742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2112742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2122742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2132742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2142742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2152742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2162742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2172742Swollman nfsrvd_lookup, 2182742Swollman nfsrvd_lookup, 2192742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2202742Swollman nfsrvd_open, 2212742Swollman nfsrvd_openattr, 2222742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2232742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2242742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2252742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2262742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2272742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2282742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2292742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2302742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2312742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2322742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2332742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2342742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2352742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2362742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2372742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2382742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2392742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2402742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2412742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2422742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2432742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2442742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2452742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2462742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2472742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2482742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2492742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2502742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2512742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2522742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2532742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2542742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2552742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2562742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2572742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2582742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2592742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2602742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 2612742Swollman}; 2622742Swollman 2632742Swollmanint (*nfsrv4_ops2[NFSV41_NOPS])(struct nfsrv_descript *, 2642742Swollman int, vnode_t , vnode_t , NFSPROC_T *, 2652742Swollman struct nfsexstuff *, struct nfsexstuff *) = { 2662742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2672742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2682742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2692742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2702742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2712742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2722742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2732742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2742742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2752742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2762742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2772742Swollman nfsrvd_link, 2782742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2792742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2802742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2812742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2822742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2832742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2842742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2852742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2862742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2872742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2882742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2892742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2902742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2912742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2922742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2932742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2942742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2952742Swollman nfsrvd_rename, 2962742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2972742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2982742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 2992742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3002742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3012742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3022742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3032742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3042742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3052742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3062742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3072742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3082742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3092742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3102742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3112742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3122742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3132742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3142742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3152742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3162742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3172742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3182742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3192742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3202742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3212742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3222742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3232742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3242742Swollman (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 3252742Swollman}; 3262742Swollman#endif /* !APPLEKEXT */ 3272742Swollman 3282742Swollman/* 3292742Swollman * Static array that defines which nfs rpc's are nonidempotent 3302742Swollman */ 3312742Swollmanstatic int nfsrv_nonidempotent[NFS_V3NPROCS] = { 3322742Swollman FALSE, 3332742Swollman FALSE, 3342742Swollman TRUE, 3352742Swollman FALSE, 3362742Swollman FALSE, 3372742Swollman FALSE, 3382742Swollman FALSE, 3392742Swollman TRUE, 3402742Swollman TRUE, 3412742Swollman TRUE, 3422742Swollman TRUE, 3432742Swollman TRUE, 3442742Swollman TRUE, 3452742Swollman TRUE, 3462742Swollman TRUE, 3472742Swollman TRUE, 3482742Swollman FALSE, 3492742Swollman FALSE, 3502742Swollman FALSE, 3512742Swollman FALSE, 3522742Swollman FALSE, 3532742Swollman FALSE, 3542742Swollman}; 3552742Swollman 3562742Swollman/* 3572742Swollman * This static array indicates whether or not the RPC modifies the 3582742Swollman * file system. 3592742Swollman */ 3602742Swollmanstatic int nfs_writerpc[NFS_NPROCS] = { 0, 0, 1, 0, 0, 0, 0, 3612742Swollman 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3622742Swollman 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; 3632742Swollman 3642742Swollman/* local functions */ 3652742Swollmanstatic void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, 3662742Swollman u_char *tag, int taglen, u_int32_t minorvers, NFSPROC_T *p); 3672742Swollman 3682742Swollman 3692742Swollman/* 3702742Swollman * This static array indicates which server procedures require the extra 3712742Swollman * arguments to return the current file handle for V2, 3. 3722742Swollman */ 3732742Swollmanstatic int nfs_retfh[NFS_V3NPROCS] = { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 3742742Swollman 1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 }; 3752742Swollman 3762742Swollmanextern struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS]; 3772742Swollman 3782742Swollmanstatic int nfsv3to4op[NFS_V3NPROCS] = { 3792742Swollman NFSPROC_NULL, 3802742Swollman NFSV4OP_GETATTR, 3812742Swollman NFSV4OP_SETATTR, 3822742Swollman NFSV4OP_LOOKUP, 3832742Swollman NFSV4OP_ACCESS, 3842742Swollman NFSV4OP_READLINK, 3852742Swollman NFSV4OP_READ, 3862742Swollman NFSV4OP_WRITE, 3872742Swollman NFSV4OP_V3CREATE, 3882742Swollman NFSV4OP_MKDIR, 3892742Swollman NFSV4OP_SYMLINK, 3902742Swollman NFSV4OP_MKNOD, 3912742Swollman NFSV4OP_REMOVE, 3922742Swollman NFSV4OP_RMDIR, 3932742Swollman NFSV4OP_RENAME, 3942742Swollman NFSV4OP_LINK, 3952742Swollman NFSV4OP_READDIR, 3962742Swollman NFSV4OP_READDIRPLUS, 3972742Swollman NFSV4OP_FSSTAT, 3982742Swollman NFSV4OP_FSINFO, 3992742Swollman NFSV4OP_PATHCONF, 4002742Swollman NFSV4OP_COMMIT, 4012742Swollman}; 4022742Swollman 4032742Swollman/* 4042742Swollman * Do an RPC. Basically, get the file handles translated to vnode pointers 4052742Swollman * and then call the appropriate server routine. The server routines are 4062742Swollman * split into groups, based on whether they use a file handle or file 4072742Swollman * handle plus name or ... 4089908Swollman * The NFS V4 Compound RPC is performed separately by nfsrvd_compound(). 4092742Swollman */ 4102742SwollmanAPPLESTATIC void 4112742Swollmannfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen, 4122742Swollman u_int32_t minorvers, NFSPROC_T *p) 4132742Swollman{ 4142742Swollman int error = 0, lktype; 4152742Swollman vnode_t vp; 4162742Swollman mount_t mp = NULL; 4172742Swollman struct nfsrvfh fh; 4182742Swollman struct nfsexstuff nes; 4192742Swollman 4202742Swollman /* 4212742Swollman * Get a locked vnode for the first file handle 4222742Swollman */ 4232742Swollman if (!(nd->nd_flag & ND_NFSV4)) { 4242742Swollman KASSERT(nd->nd_repstat == 0, ("nfsrvd_dorpc")); 4252742Swollman /* 4262742Swollman * For NFSv3, if the malloc/mget allocation is near limits, 4272742Swollman * return NFSERR_DELAY. 4282742Swollman */ 4292742Swollman if ((nd->nd_flag & ND_NFSV3) && nfsrv_mallocmget_limit()) { 43017200Swollman nd->nd_repstat = NFSERR_DELAY; 43117200Swollman vp = NULL; 43217200Swollman } else { 43317200Swollman error = nfsrv_mtofh(nd, &fh); 43417200Swollman if (error) { 43517200Swollman if (error != EBADRPC) 43617200Swollman printf("nfs dorpc err1=%d\n", error); 43717200Swollman nd->nd_repstat = NFSERR_GARBAGE; 43817200Swollman goto out; 43917200Swollman } 44017200Swollman if (nd->nd_procnum == NFSPROC_READ || 44117200Swollman nd->nd_procnum == NFSPROC_WRITE || 44217200Swollman nd->nd_procnum == NFSPROC_READDIR || 44317200Swollman nd->nd_procnum == NFSPROC_READLINK || 44417200Swollman nd->nd_procnum == NFSPROC_GETATTR || 44517200Swollman nd->nd_procnum == NFSPROC_ACCESS) 4462742Swollman lktype = LK_SHARED; 4472742Swollman else 4482742Swollman lktype = LK_EXCLUSIVE; 4492742Swollman if (nd->nd_flag & ND_PUBLOOKUP) 4502742Swollman nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes, 4512742Swollman &mp, nfs_writerpc[nd->nd_procnum], p); 4522742Swollman else 4532742Swollman nfsd_fhtovp(nd, &fh, lktype, &vp, &nes, 4542742Swollman &mp, nfs_writerpc[nd->nd_procnum], p); 4552742Swollman if (nd->nd_repstat == NFSERR_PROGNOTV4) 4562742Swollman goto out; 4572742Swollman } 4582742Swollman } 4592742Swollman 4602742Swollman /* 4612742Swollman * For V2 and 3, set the ND_SAVEREPLY flag for the recent request 4622742Swollman * cache, as required. 4632742Swollman * For V4, nfsrvd_compound() does this. 4642742Swollman */ 4652742Swollman if (!(nd->nd_flag & ND_NFSV4) && nfsrv_nonidempotent[nd->nd_procnum]) 4662742Swollman nd->nd_flag |= ND_SAVEREPLY; 4672742Swollman 4682742Swollman nfsrvd_rephead(nd); 4692742Swollman /* 4702742Swollman * If nd_repstat is non-zero, just fill in the reply status 4712742Swollman * to complete the RPC reply for V2. Otherwise, you must do 4722742Swollman * the RPC. 4739908Swollman */ 4742742Swollman if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) { 4752742Swollman *nd->nd_errp = nfsd_errmap(nd); 4762742Swollman NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]); 4772742Swollman if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0) 4782742Swollman vn_finished_write(mp); 4792742Swollman goto out; 4802742Swollman } 4812742Swollman 4822742Swollman /* 4832742Swollman * Now the procedure can be performed. For V4, nfsrvd_compound() 4842742Swollman * works through the sub-rpcs, otherwise just call the procedure. 4852742Swollman * The procedures are in three groups with different arguments. 4862742Swollman * The group is indicated by the value in nfs_retfh[]. 4872742Swollman */ 4882742Swollman if (nd->nd_flag & ND_NFSV4) { 4892742Swollman nfsrvd_compound(nd, isdgram, tag, taglen, minorvers, p); 4902742Swollman } else { 4912742Swollman if (nfs_retfh[nd->nd_procnum] == 1) { 4922742Swollman if (vp) 4932742Swollman NFSVOPUNLOCK(vp, 0); 4942742Swollman error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram, 4952742Swollman vp, NULL, (fhandle_t *)fh.nfsrvfh_data, p, &nes); 4962742Swollman } else if (nfs_retfh[nd->nd_procnum] == 2) { 4972742Swollman error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram, 4982742Swollman vp, NULL, p, &nes, NULL); 4992742Swollman } else { 5002742Swollman error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram, 5012742Swollman vp, p, &nes); 5022742Swollman } 5032742Swollman if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0) 5042742Swollman vn_finished_write(mp); 5052742Swollman NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]); 5062742Swollman } 5072742Swollman if (error) { 5082742Swollman if (error != EBADRPC) 5092742Swollman printf("nfs dorpc err2=%d\n", error); 5102742Swollman nd->nd_repstat = NFSERR_GARBAGE; 5112742Swollman } 5122742Swollman *nd->nd_errp = nfsd_errmap(nd); 5132742Swollman 5142742Swollman /* 5152742Swollman * Don't cache certain reply status values. 5162742Swollman */ 5172742Swollman if (nd->nd_repstat && (nd->nd_flag & ND_SAVEREPLY) && 5182742Swollman (nd->nd_repstat == NFSERR_GARBAGE || 5192742Swollman nd->nd_repstat == NFSERR_BADXDR || 5202742Swollman nd->nd_repstat == NFSERR_MOVED || 5212742Swollman nd->nd_repstat == NFSERR_DELAY || 5222742Swollman nd->nd_repstat == NFSERR_BADSEQID || 5232742Swollman nd->nd_repstat == NFSERR_RESOURCE || 5242742Swollman nd->nd_repstat == NFSERR_SERVERFAULT || 5252742Swollman nd->nd_repstat == NFSERR_STALECLIENTID || 5262742Swollman nd->nd_repstat == NFSERR_STALESTATEID || 5272742Swollman nd->nd_repstat == NFSERR_OLDSTATEID || 5282742Swollman nd->nd_repstat == NFSERR_BADSTATEID || 5292742Swollman nd->nd_repstat == NFSERR_GRACE || 5302742Swollman nd->nd_repstat == NFSERR_NOGRACE)) 5312742Swollman nd->nd_flag &= ~ND_SAVEREPLY; 5322742Swollman 5332742Swollmanout: 5342742Swollman NFSEXITCODE2(0, nd); 5352742Swollman} 5362742Swollman 5372742Swollman/* 5382742Swollman * Breaks down a compound RPC request and calls the server routines for 5392742Swollman * the subprocedures. 5402742Swollman * Some suboperations are performed directly here to simplify file handle<--> 5412742Swollman * vnode pointer handling. 5422742Swollman */ 5432742Swollmanstatic void 5442742Swollmannfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag, 5452742Swollman int taglen, u_int32_t minorvers, NFSPROC_T *p) 5462742Swollman{ 5472742Swollman int i, op, op0 = 0; 5482742Swollman u_int32_t *tl; 5492742Swollman struct nfsclient *clp, *nclp; 5502742Swollman int numops, error = 0, igotlock; 5512742Swollman u_int32_t retops = 0, *retopsp = NULL, *repp; 5522742Swollman vnode_t vp, nvp, savevp; 5532742Swollman struct nfsrvfh fh; 5542742Swollman mount_t new_mp, temp_mp = NULL; 5552742Swollman struct ucred *credanon; 5562742Swollman struct nfsexstuff nes, vpnes, savevpnes; 5572742Swollman fsid_t cur_fsid, save_fsid; 5582742Swollman static u_int64_t compref = 0; 5592742Swollman 5602742Swollman NFSVNO_EXINIT(&vpnes); 5612742Swollman NFSVNO_EXINIT(&savevpnes); 5622742Swollman /* 5632742Swollman * Put the seq# of the current compound RPC in nfsrv_descript. 5642742Swollman * (This is used by nfsrv_checkgetattr(), to see if the write 5652742Swollman * delegation was created by the same compound RPC as the one 5662742Swollman * with that Getattr in it.) 5672742Swollman * Don't worry about the 64bit number wrapping around. It ain't 5682742Swollman * gonna happen before this server gets shut down/rebooted. 5692742Swollman */ 5702742Swollman nd->nd_compref = compref++; 5712742Swollman 5722742Swollman /* 5732742Swollman * Check for and optionally get a lock on the root. This lock means that 5742742Swollman * no nfsd will be fiddling with the V4 file system and state stuff. It 5752742Swollman * is required when the V4 root is being changed, the stable storage 5762742Swollman * restart file is being updated, or callbacks are being done. 5772742Swollman * When any of the nfsd are processing an NFSv4 compound RPC, they must 5782742Swollman * either hold a reference count (nfs_usecnt) or the lock. When 5792742Swollman * nfsrv_unlock() is called to release the lock, it can optionally 5802742Swollman * also get a reference count, which saves the need for a call to 5812742Swollman * nfsrv_getref() after nfsrv_unlock(). 5822742Swollman */ 5832742Swollman /* 5842742Swollman * First, check to see if we need to wait for an update lock. 5852742Swollman */ 5862742Swollman igotlock = 0; 5872742Swollman NFSLOCKV4ROOTMUTEX(); 5882742Swollman if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK) 5892742Swollman igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL, 5902742Swollman NFSV4ROOTLOCKMUTEXPTR, NULL); 5912742Swollman else 5922742Swollman igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL, 5932742Swollman NFSV4ROOTLOCKMUTEXPTR, NULL); 5942742Swollman NFSUNLOCKV4ROOTMUTEX(); 5952742Swollman if (igotlock) { 5962742Swollman /* 5972742Swollman * If I got the lock, I can update the stable storage file. 5982742Swollman * Done when the grace period is over or a client has long 5992742Swollman * since expired. 6002742Swollman */ 6012742Swollman nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NEEDLOCK; 6022742Swollman if ((nfsrv_stablefirst.nsf_flags & 6032742Swollman (NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER) 6042742Swollman nfsrv_updatestable(p); 6052742Swollman 6062742Swollman /* 6072742Swollman * If at least one client has long since expired, search 6082742Swollman * the client list for them, write a REVOKE record on the 6092742Swollman * stable storage file and then remove them from the client 6102742Swollman * list. 6119908Swollman */ 6129908Swollman if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) { 6139908Swollman nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT; 6149908Swollman for (i = 0; i < nfsrv_clienthashsize; i++) { 6159908Swollman LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, 6169908Swollman nclp) { 6172742Swollman if (clp->lc_flags & LCL_EXPIREIT) { 6182742Swollman if (!LIST_EMPTY(&clp->lc_open) || 6192742Swollman !LIST_EMPTY(&clp->lc_deleg)) 6202742Swollman nfsrv_writestable(clp->lc_id, 6212742Swollman clp->lc_idlen, NFSNST_REVOKE, p); 6229908Swollman nfsrv_cleanclient(clp, p); 6239908Swollman nfsrv_freedeleglist(&clp->lc_deleg); 6249908Swollman nfsrv_freedeleglist(&clp->lc_olddeleg); 6259908Swollman LIST_REMOVE(clp, lc_hash); 6269908Swollman nfsrv_zapclient(clp, p); 6279908Swollman } 62817200Swollman } 62917200Swollman } 63017200Swollman } 63117200Swollman NFSLOCKV4ROOTMUTEX(); 63217200Swollman nfsv4_unlock(&nfsv4rootfs_lock, 1); 6332742Swollman NFSUNLOCKV4ROOTMUTEX(); 6342742Swollman } else { 63514343Swollman /* 63614343Swollman * If we didn't get the lock, we need to get a refcnt, 6372742Swollman * which also checks for and waits for the lock. 6382742Swollman */ 6392742Swollman NFSLOCKV4ROOTMUTEX(); 6402742Swollman nfsv4_getref(&nfsv4rootfs_lock, NULL, 6412742Swollman NFSV4ROOTLOCKMUTEXPTR, NULL); 6422742Swollman NFSUNLOCKV4ROOTMUTEX(); 6432742Swollman } 6442742Swollman 64517200Swollman /* 6462742Swollman * If flagged, search for open owners that haven't had any opens 6472742Swollman * for a long time. 6482742Swollman */ 6492742Swollman if (nfsrv_stablefirst.nsf_flags & NFSNSF_NOOPENS) { 6502742Swollman nfsrv_throwawayopens(p); 6512742Swollman } 6522742Swollman 6532742Swollman savevp = vp = NULL; 6542742Swollman save_fsid.val[0] = save_fsid.val[1] = 0; 6552742Swollman cur_fsid.val[0] = cur_fsid.val[1] = 0; 6562742Swollman 6572742Swollman /* If taglen < 0, there was a parsing error in nfsd_getminorvers(). */ 6582742Swollman if (taglen < 0) { 6592742Swollman error = EBADRPC; 6602742Swollman goto nfsmout; 6612742Swollman } 6622742Swollman 6632742Swollman (void) nfsm_strtom(nd, tag, taglen); 6642742Swollman NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED); 66517200Swollman NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 66617200Swollman if (minorvers != NFSV4_MINORVERSION && minorvers != NFSV41_MINORVERSION) 66717200Swollman nd->nd_repstat = NFSERR_MINORVERMISMATCH; 6682742Swollman if (nd->nd_repstat) 66917200Swollman numops = 0; 67017200Swollman else 6712742Swollman numops = fxdr_unsigned(int, *tl); 6722742Swollman /* 6732742Swollman * Loop around doing the sub ops. 67417200Swollman * vp - is an unlocked vnode pointer for the CFH 6752742Swollman * savevp - is an unlocked vnode pointer for the SAVEDFH 67617200Swollman * (at some future date, it might turn out to be more appropriate 6772742Swollman * to keep the file handles instead of vnode pointers?) 6782742Swollman * savevpnes and vpnes - are the export flags for the above. 67917200Swollman */ 68017200Swollman for (i = 0; i < numops; i++) { 68117200Swollman NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 68217200Swollman NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED); 68317200Swollman *repp = *tl; 68417200Swollman op = fxdr_unsigned(int, *tl); 68517200Swollman NFSD_DEBUG(4, "op=%d\n", op); 68617200Swollman if (op < NFSV4OP_ACCESS || 6872742Swollman (op >= NFSV4OP_NOPS && (nd->nd_flag & ND_NFSV41) == 0) || 6882742Swollman (op >= NFSV41_NOPS && (nd->nd_flag & ND_NFSV41) != 0)) { 6892742Swollman nd->nd_repstat = NFSERR_OPILLEGAL; 6902742Swollman *repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL); 6912742Swollman *repp = nfsd_errmap(nd); 6922742Swollman retops++; 6932742Swollman break; 6942742Swollman } else { 6952742Swollman repp++; 6962742Swollman } 6972742Swollman if (i == 0) 6982742Swollman op0 = op; 6992742Swollman if (i == numops - 1) 7002742Swollman nd->nd_flag |= ND_LASTOP; 7012742Swollman 7022742Swollman /* 7032742Swollman * Check for a referral on the current FH and, if so, return 7042742Swollman * NFSERR_MOVED for all ops that allow it, except Getattr. 7052742Swollman */ 7062742Swollman if (vp != NULL && op != NFSV4OP_GETATTR && 7072742Swollman nfsv4root_getreferral(vp, NULL, 0) != NULL && 7082742Swollman nfsrv_errmoved(op)) { 7092742Swollman nd->nd_repstat = NFSERR_MOVED; 7102742Swollman *repp = nfsd_errmap(nd); 7112742Swollman retops++; 7122742Swollman break; 7132742Swollman } 7142742Swollman 7152742Swollman /* 7162742Swollman * For NFSv4.1, check for a Sequence Operation being first 7172742Swollman * or one of the other allowed operations by itself. 7182742Swollman */ 7192742Swollman if ((nd->nd_flag & ND_NFSV41) != 0) { 7202742Swollman if (i != 0 && op == NFSV4OP_SEQUENCE) 7212742Swollman nd->nd_repstat = NFSERR_SEQUENCEPOS; 7222742Swollman else if (i == 0 && op != NFSV4OP_SEQUENCE && 7232742Swollman op != NFSV4OP_EXCHANGEID && 7242742Swollman op != NFSV4OP_CREATESESSION && 7252742Swollman op != NFSV4OP_BINDCONNTOSESS && 7262742Swollman op != NFSV4OP_DESTROYCLIENTID && 7272742Swollman op != NFSV4OP_DESTROYSESSION) 7282742Swollman nd->nd_repstat = NFSERR_OPNOTINSESS; 7292742Swollman else if (i != 0 && op0 != NFSV4OP_SEQUENCE) 7302742Swollman nd->nd_repstat = NFSERR_NOTONLYOP; 7312742Swollman if (nd->nd_repstat != 0) { 7322742Swollman *repp = nfsd_errmap(nd); 7332742Swollman retops++; 7342742Swollman break; 7352742Swollman } 7362742Swollman } 7372742Swollman 7382742Swollman nd->nd_procnum = op; 7392742Swollman /* 7402742Swollman * If over flood level, reply NFSERR_RESOURCE, if at the first 7412742Swollman * Op. (Since a client recovery from NFSERR_RESOURCE can get 7422742Swollman * really nasty for certain Op sequences, I'll play it safe 7432742Swollman * and only return the error at the beginning.) The cache 7442742Swollman * will still function over flood level, but uses lots of 7452742Swollman * mbufs.) 7462742Swollman * If nfsrv_mallocmget_limit() returns True, the system is near 7472742Swollman * to its limit for memory that malloc()/mget() can allocate. 7482742Swollman */ 7492742Swollman if (i == 0 && (nd->nd_rp == NULL || 7502742Swollman nd->nd_rp->rc_refcnt == 0) && 75117200Swollman (nfsrv_mallocmget_limit() || 7522742Swollman nfsrc_tcpsavedreplies > nfsrc_floodlevel)) { 7532742Swollman if (nfsrc_tcpsavedreplies > nfsrc_floodlevel) 7542742Swollman printf("nfsd server cache flooded, try " 75517200Swollman "increasing vfs.nfsd.tcphighwater\n"); 7562742Swollman nd->nd_repstat = NFSERR_RESOURCE; 7579908Swollman *repp = nfsd_errmap(nd); 7589908Swollman if (op == NFSV4OP_SETATTR) { 7599908Swollman /* 7609908Swollman * Setattr replies require a bitmap. 76117200Swollman * even for errors like these. 7622742Swollman */ 7632742Swollman NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); 7642742Swollman *tl = 0; 76517200Swollman } 76617200Swollman retops++; 7679908Swollman break; 76817200Swollman } 7692742Swollman if (nfsv4_opflag[op].savereply) 7702742Swollman nd->nd_flag |= ND_SAVEREPLY; 7712742Swollman NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]); 77217200Swollman switch (op) { 77317200Swollman case NFSV4OP_PUTFH: 7749908Swollman error = nfsrv_mtofh(nd, &fh); 77517200Swollman if (error) 7762742Swollman goto nfsmout; 7772742Swollman if (!nd->nd_repstat) 7782742Swollman nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes, 77917200Swollman NULL, 0, p); 78017200Swollman /* For now, allow this for non-export FHs */ 78117200Swollman if (!nd->nd_repstat) { 7822742Swollman if (vp) 78317200Swollman vrele(vp); 7842742Swollman vp = nvp; 78517200Swollman cur_fsid = vp->v_mount->mnt_stat.f_fsid; 78617200Swollman NFSVOPUNLOCK(vp, 0); 78717200Swollman vpnes = nes; 78817200Swollman } 7892742Swollman break; 7908049Swollman case NFSV4OP_PUTPUBFH: 7918049Swollman if (nfs_pubfhset) 7928049Swollman nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp, 7938049Swollman &nes, NULL, 0, p); 7942742Swollman else 7952742Swollman nd->nd_repstat = NFSERR_NOFILEHANDLE; 7962742Swollman if (!nd->nd_repstat) { 7972742Swollman if (vp) 79817200Swollman vrele(vp); 79917200Swollman vp = nvp; 8009908Swollman cur_fsid = vp->v_mount->mnt_stat.f_fsid; 8019908Swollman NFSVOPUNLOCK(vp, 0); 80217200Swollman vpnes = nes; 80317200Swollman } 80417200Swollman break; 80517200Swollman case NFSV4OP_PUTROOTFH: 80617200Swollman if (nfs_rootfhset) { 80717200Swollman nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp, 8089908Swollman &nes, NULL, 0, p); 80917200Swollman if (!nd->nd_repstat) { 8102742Swollman if (vp) 8112742Swollman vrele(vp); 8122742Swollman vp = nvp; 8139908Swollman cur_fsid = vp->v_mount->mnt_stat.f_fsid; 8142742Swollman NFSVOPUNLOCK(vp, 0); 8159908Swollman vpnes = nes; 8162742Swollman } 8179908Swollman } else 81817200Swollman nd->nd_repstat = NFSERR_NOFILEHANDLE; 8192742Swollman break; 8202742Swollman case NFSV4OP_SAVEFH: 8212742Swollman if (vp && NFSVNO_EXPORTED(&vpnes)) { 8222742Swollman nd->nd_repstat = 0; 8232742Swollman /* If vp == savevp, a no-op */ 82417200Swollman if (vp != savevp) { 8252742Swollman if (savevp) 8262742Swollman vrele(savevp); 8272742Swollman VREF(vp); 8282742Swollman savevp = vp; 8292742Swollman savevpnes = vpnes; 8302742Swollman save_fsid = cur_fsid; 8312742Swollman } 8322742Swollman } else { 8332742Swollman nd->nd_repstat = NFSERR_NOFILEHANDLE; 8349908Swollman } 8352742Swollman break; 8369908Swollman case NFSV4OP_RESTOREFH: 8372742Swollman if (savevp) { 8382742Swollman nd->nd_repstat = 0; 8392742Swollman /* If vp == savevp, a no-op */ 8402742Swollman if (vp != savevp) { 8412742Swollman VREF(savevp); 8422742Swollman vrele(vp); 8432742Swollman vp = savevp; 8442742Swollman vpnes = savevpnes; 8452742Swollman cur_fsid = save_fsid; 8462742Swollman } 8472742Swollman } else { 8482742Swollman nd->nd_repstat = NFSERR_RESTOREFH; 8492742Swollman } 8502742Swollman break; 8512742Swollman default: 8522742Swollman /* 8532742Swollman * Allow a Lookup, Getattr, GetFH, Secinfo on an 8542742Swollman * non-exported directory if 8552742Swollman * nfs_rootfhset. Do I need to allow any other Ops? 8562742Swollman * (You can only have a non-exported vpnes if 8572742Swollman * nfs_rootfhset is true. See nfsd_fhtovp()) 8582742Swollman * Allow AUTH_SYS to be used for file systems 8592742Swollman * exported GSS only for certain Ops, to allow 8602742Swollman * clients to do mounts more easily. 86117200Swollman */ 8622742Swollman if (nfsv4_opflag[op].needscfh && vp) { 86317200Swollman if (!NFSVNO_EXPORTED(&vpnes) && 8642742Swollman op != NFSV4OP_LOOKUP && 8652742Swollman op != NFSV4OP_GETATTR && 8662742Swollman op != NFSV4OP_GETFH && 8672742Swollman op != NFSV4OP_ACCESS && 8682742Swollman op != NFSV4OP_READLINK && 8692742Swollman op != NFSV4OP_SECINFO) 8702742Swollman nd->nd_repstat = NFSERR_NOFILEHANDLE; 8712742Swollman else if (nfsvno_testexp(nd, &vpnes) && 8722742Swollman op != NFSV4OP_LOOKUP && 8732742Swollman op != NFSV4OP_GETFH && 8742742Swollman op != NFSV4OP_GETATTR && 8752742Swollman op != NFSV4OP_SECINFO) 8762742Swollman nd->nd_repstat = NFSERR_WRONGSEC; 8772742Swollman if (nd->nd_repstat) { 8782742Swollman if (op == NFSV4OP_SETATTR) { 8792742Swollman /* 8802742Swollman * Setattr reply requires a bitmap 8812742Swollman * even for errors like these. 8822742Swollman */ 8832742Swollman NFSM_BUILD(tl, u_int32_t *, 8842742Swollman NFSX_UNSIGNED); 8852742Swollman *tl = 0; 8862742Swollman } 8872742Swollman break; 8882742Swollman } 8892742Swollman } 8902742Swollman if (nfsv4_opflag[op].retfh == 1) { 8912742Swollman if (!vp) { 8922742Swollman nd->nd_repstat = NFSERR_NOFILEHANDLE; 8932742Swollman break; 8942742Swollman } 8952742Swollman VREF(vp); 8962742Swollman if (nfsv4_opflag[op].modifyfs) 8972742Swollman vn_start_write(vp, &temp_mp, V_WAIT); 8982742Swollman error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp, 8992742Swollman &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes); 9002742Swollman if (!error && !nd->nd_repstat) { 9012742Swollman if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) { 90217200Swollman new_mp = nvp->v_mount; 9032742Swollman if (cur_fsid.val[0] != 9048049Swollman new_mp->mnt_stat.f_fsid.val[0] || 9058049Swollman cur_fsid.val[1] != 9062742Swollman new_mp->mnt_stat.f_fsid.val[1]) { 9072742Swollman /* crossed a server mount point */ 9082742Swollman nd->nd_repstat = nfsvno_checkexp(new_mp, 9092742Swollman nd->nd_nam, &nes, &credanon); 9102742Swollman if (!nd->nd_repstat) 91117200Swollman nd->nd_repstat = nfsd_excred(nd, 9122742Swollman &nes, credanon); 9138049Swollman if (credanon != NULL) 9148049Swollman crfree(credanon); 9152742Swollman if (!nd->nd_repstat) { 9162742Swollman vpnes = nes; 9172742Swollman cur_fsid = new_mp->mnt_stat.f_fsid; 9182742Swollman } 9192742Swollman } 9202742Swollman /* Lookup ops return a locked vnode */ 9212742Swollman NFSVOPUNLOCK(nvp, 0); 9222742Swollman } 9232742Swollman if (!nd->nd_repstat) { 9242742Swollman vrele(vp); 9252742Swollman vp = nvp; 9262742Swollman } else 9272742Swollman vrele(nvp); 9282742Swollman } 9292742Swollman if (nfsv4_opflag[op].modifyfs) 9309908Swollman vn_finished_write(temp_mp); 93117200Swollman } else if (nfsv4_opflag[op].retfh == 2) { 9322742Swollman if (vp == NULL || savevp == NULL) { 9338049Swollman nd->nd_repstat = NFSERR_NOFILEHANDLE; 9348049Swollman break; 9352742Swollman } else if (cur_fsid.val[0] != save_fsid.val[0] || 9362742Swollman cur_fsid.val[1] != save_fsid.val[1]) { 9372742Swollman nd->nd_repstat = NFSERR_XDEV; 9382742Swollman break; 9392742Swollman } 9402742Swollman if (nfsv4_opflag[op].modifyfs) 9412742Swollman vn_start_write(savevp, &temp_mp, V_WAIT); 9422742Swollman if (NFSVOPLOCK(savevp, LK_EXCLUSIVE) == 0) { 94314343Swollman VREF(vp); 94417200Swollman VREF(savevp); 9452742Swollman error = (*(nfsrv4_ops2[op]))(nd, isdgram, 9468049Swollman savevp, vp, p, &savevpnes, &vpnes); 9478049Swollman } else 9482742Swollman nd->nd_repstat = NFSERR_PERM; 9492742Swollman if (nfsv4_opflag[op].modifyfs) 9502742Swollman vn_finished_write(temp_mp); 9512742Swollman } else { 9522742Swollman if (nfsv4_opflag[op].retfh != 0) 9532742Swollman panic("nfsrvd_compound"); 9542742Swollman if (nfsv4_opflag[op].needscfh) { 9552742Swollman if (vp != NULL) { 9562742Swollman if (nfsv4_opflag[op].modifyfs) 9572742Swollman vn_start_write(vp, &temp_mp, 9582742Swollman V_WAIT); 9592742Swollman if (NFSVOPLOCK(vp, nfsv4_opflag[op].lktype) 9602742Swollman == 0) 9612742Swollman VREF(vp); 9622742Swollman else 9632742Swollman nd->nd_repstat = NFSERR_PERM; 9642742Swollman } else { 9652742Swollman nd->nd_repstat = NFSERR_NOFILEHANDLE; 9662742Swollman if (op == NFSV4OP_SETATTR) { 9672742Swollman /* 9682742Swollman * Setattr reply requires a 9692742Swollman * bitmap even for errors like 9702742Swollman * these. 9712742Swollman */ 9722742Swollman NFSM_BUILD(tl, u_int32_t *, 9732742Swollman NFSX_UNSIGNED); 9742742Swollman *tl = 0; 9752742Swollman } 9762742Swollman break; 9772742Swollman } 9782742Swollman if (nd->nd_repstat == 0) 9792742Swollman error = (*(nfsrv4_ops0[op]))(nd, 9802742Swollman isdgram, vp, p, &vpnes); 9812742Swollman if (nfsv4_opflag[op].modifyfs) 9822742Swollman vn_finished_write(temp_mp); 9832742Swollman } else { 9842742Swollman error = (*(nfsrv4_ops0[op]))(nd, isdgram, 9852742Swollman NULL, p, &vpnes); 9862742Swollman } 9872742Swollman } 9882742Swollman }; 9892742Swollman if (error) { 9902742Swollman if (error == EBADRPC || error == NFSERR_BADXDR) { 9912742Swollman nd->nd_repstat = NFSERR_BADXDR; 9922742Swollman } else { 9939908Swollman nd->nd_repstat = error; 99417200Swollman printf("nfsv4 comperr0=%d\n", error); 9952742Swollman } 9968049Swollman error = 0; 9978049Swollman } 9982742Swollman retops++; 9992742Swollman if (nd->nd_repstat) { 10002742Swollman *repp = nfsd_errmap(nd); 10012742Swollman break; 10022742Swollman } else { 10032742Swollman *repp = 0; /* NFS4_OK */ 10042742Swollman } 10059908Swollman } 100617200Swollmannfsmout: 10072742Swollman if (error) { 10088049Swollman if (error == EBADRPC || error == NFSERR_BADXDR) 10098049Swollman nd->nd_repstat = NFSERR_BADXDR; 10102742Swollman else 10112742Swollman printf("nfsv4 comperr1=%d\n", error); 10122742Swollman } 10132742Swollman if (taglen == -1) { 10142742Swollman NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 10152742Swollman *tl++ = 0; 10162742Swollman *tl = 0; 10172742Swollman } else { 10182742Swollman *retopsp = txdr_unsigned(retops); 10192742Swollman } 10202742Swollman if (vp) 10212742Swollman vrele(vp); 10222742Swollman if (savevp) 10232742Swollman vrele(savevp); 10242742Swollman NFSLOCKV4ROOTMUTEX(); 10252742Swollman nfsv4_relref(&nfsv4rootfs_lock); 10262742Swollman NFSUNLOCKV4ROOTMUTEX(); 102717200Swollman 10282742Swollman NFSEXITCODE2(0, nd); 10298049Swollman} 10308049Swollman