Home | History | Annotate | Line # | Download | only in server
nfs_nfsdsocket.c revision 1.1.1.1.4.2
      1  1.1.1.1.4.2  rmind /*	$NetBSD: nfs_nfsdsocket.c,v 1.1.1.1.4.2 2014/05/18 17:46:06 rmind Exp $	*/
      2  1.1.1.1.4.2  rmind /*-
      3  1.1.1.1.4.2  rmind  * Copyright (c) 1989, 1993
      4  1.1.1.1.4.2  rmind  *	The Regents of the University of California.  All rights reserved.
      5  1.1.1.1.4.2  rmind  *
      6  1.1.1.1.4.2  rmind  * This code is derived from software contributed to Berkeley by
      7  1.1.1.1.4.2  rmind  * Rick Macklem at The University of Guelph.
      8  1.1.1.1.4.2  rmind  *
      9  1.1.1.1.4.2  rmind  * Redistribution and use in source and binary forms, with or without
     10  1.1.1.1.4.2  rmind  * modification, are permitted provided that the following conditions
     11  1.1.1.1.4.2  rmind  * are met:
     12  1.1.1.1.4.2  rmind  * 1. Redistributions of source code must retain the above copyright
     13  1.1.1.1.4.2  rmind  *    notice, this list of conditions and the following disclaimer.
     14  1.1.1.1.4.2  rmind  * 2. Redistributions in binary form must reproduce the above copyright
     15  1.1.1.1.4.2  rmind  *    notice, this list of conditions and the following disclaimer in the
     16  1.1.1.1.4.2  rmind  *    documentation and/or other materials provided with the distribution.
     17  1.1.1.1.4.2  rmind  * 4. Neither the name of the University nor the names of its contributors
     18  1.1.1.1.4.2  rmind  *    may be used to endorse or promote products derived from this software
     19  1.1.1.1.4.2  rmind  *    without specific prior written permission.
     20  1.1.1.1.4.2  rmind  *
     21  1.1.1.1.4.2  rmind  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  1.1.1.1.4.2  rmind  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  1.1.1.1.4.2  rmind  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  1.1.1.1.4.2  rmind  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  1.1.1.1.4.2  rmind  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  1.1.1.1.4.2  rmind  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  1.1.1.1.4.2  rmind  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  1.1.1.1.4.2  rmind  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  1.1.1.1.4.2  rmind  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  1.1.1.1.4.2  rmind  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  1.1.1.1.4.2  rmind  * SUCH DAMAGE.
     32  1.1.1.1.4.2  rmind  *
     33  1.1.1.1.4.2  rmind  */
     34  1.1.1.1.4.2  rmind 
     35  1.1.1.1.4.2  rmind #include <sys/cdefs.h>
     36  1.1.1.1.4.2  rmind /* __FBSDID("FreeBSD: head/sys/fs/nfsserver/nfs_nfsdsocket.c 249592 2013-04-17 21:00:22Z ken "); */
     37  1.1.1.1.4.2  rmind __RCSID("$NetBSD: nfs_nfsdsocket.c,v 1.1.1.1.4.2 2014/05/18 17:46:06 rmind Exp $");
     38  1.1.1.1.4.2  rmind 
     39  1.1.1.1.4.2  rmind /*
     40  1.1.1.1.4.2  rmind  * Socket operations for use by the nfs server.
     41  1.1.1.1.4.2  rmind  */
     42  1.1.1.1.4.2  rmind 
     43  1.1.1.1.4.2  rmind #ifndef APPLEKEXT
     44  1.1.1.1.4.2  rmind #include <fs/nfs/nfsport.h>
     45  1.1.1.1.4.2  rmind 
     46  1.1.1.1.4.2  rmind extern struct nfsstats newnfsstats;
     47  1.1.1.1.4.2  rmind extern struct nfsrvfh nfs_pubfh, nfs_rootfh;
     48  1.1.1.1.4.2  rmind extern int nfs_pubfhset, nfs_rootfhset;
     49  1.1.1.1.4.2  rmind extern struct nfsv4lock nfsv4rootfs_lock;
     50  1.1.1.1.4.2  rmind extern struct nfsrv_stablefirst nfsrv_stablefirst;
     51  1.1.1.1.4.2  rmind extern struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE];
     52  1.1.1.1.4.2  rmind extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies;
     53  1.1.1.1.4.2  rmind NFSV4ROOTLOCKMUTEX;
     54  1.1.1.1.4.2  rmind NFSSTATESPINLOCK;
     55  1.1.1.1.4.2  rmind 
     56  1.1.1.1.4.2  rmind int (*nfsrv3_procs0[NFS_V3NPROCS])(struct nfsrv_descript *,
     57  1.1.1.1.4.2  rmind     int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
     58  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
     59  1.1.1.1.4.2  rmind 	nfsrvd_getattr,
     60  1.1.1.1.4.2  rmind 	nfsrvd_setattr,
     61  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
     62  1.1.1.1.4.2  rmind 	nfsrvd_access,
     63  1.1.1.1.4.2  rmind 	nfsrvd_readlink,
     64  1.1.1.1.4.2  rmind 	nfsrvd_read,
     65  1.1.1.1.4.2  rmind 	nfsrvd_write,
     66  1.1.1.1.4.2  rmind 	nfsrvd_create,
     67  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
     68  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
     69  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
     70  1.1.1.1.4.2  rmind 	nfsrvd_remove,
     71  1.1.1.1.4.2  rmind 	nfsrvd_remove,
     72  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
     73  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
     74  1.1.1.1.4.2  rmind 	nfsrvd_readdir,
     75  1.1.1.1.4.2  rmind 	nfsrvd_readdirplus,
     76  1.1.1.1.4.2  rmind 	nfsrvd_statfs,
     77  1.1.1.1.4.2  rmind 	nfsrvd_fsinfo,
     78  1.1.1.1.4.2  rmind 	nfsrvd_pathconf,
     79  1.1.1.1.4.2  rmind 	nfsrvd_commit,
     80  1.1.1.1.4.2  rmind };
     81  1.1.1.1.4.2  rmind 
     82  1.1.1.1.4.2  rmind int (*nfsrv3_procs1[NFS_V3NPROCS])(struct nfsrv_descript *,
     83  1.1.1.1.4.2  rmind     int, vnode_t , vnode_t *, fhandle_t *,
     84  1.1.1.1.4.2  rmind     NFSPROC_T *, struct nfsexstuff *) = {
     85  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
     86  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
     87  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
     88  1.1.1.1.4.2  rmind 	nfsrvd_lookup,
     89  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
     90  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
     91  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
     92  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
     93  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
     94  1.1.1.1.4.2  rmind 	nfsrvd_mkdir,
     95  1.1.1.1.4.2  rmind 	nfsrvd_symlink,
     96  1.1.1.1.4.2  rmind 	nfsrvd_mknod,
     97  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
     98  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
     99  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    100  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    101  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    102  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    103  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    104  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    105  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    106  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    107  1.1.1.1.4.2  rmind };
    108  1.1.1.1.4.2  rmind 
    109  1.1.1.1.4.2  rmind int (*nfsrv3_procs2[NFS_V3NPROCS])(struct nfsrv_descript *,
    110  1.1.1.1.4.2  rmind     int, vnode_t , vnode_t , NFSPROC_T *,
    111  1.1.1.1.4.2  rmind     struct nfsexstuff *, struct nfsexstuff *) = {
    112  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    113  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    114  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    115  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    116  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    117  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    118  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    119  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    120  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    121  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    122  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    123  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    124  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    125  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    126  1.1.1.1.4.2  rmind 	nfsrvd_rename,
    127  1.1.1.1.4.2  rmind 	nfsrvd_link,
    128  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    129  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    130  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    131  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    132  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    133  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    134  1.1.1.1.4.2  rmind };
    135  1.1.1.1.4.2  rmind 
    136  1.1.1.1.4.2  rmind int (*nfsrv4_ops0[NFSV4OP_NOPS])(struct nfsrv_descript *,
    137  1.1.1.1.4.2  rmind     int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
    138  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    139  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    140  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    141  1.1.1.1.4.2  rmind 	nfsrvd_access,
    142  1.1.1.1.4.2  rmind 	nfsrvd_close,
    143  1.1.1.1.4.2  rmind 	nfsrvd_commit,
    144  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    145  1.1.1.1.4.2  rmind 	nfsrvd_delegpurge,
    146  1.1.1.1.4.2  rmind 	nfsrvd_delegreturn,
    147  1.1.1.1.4.2  rmind 	nfsrvd_getattr,
    148  1.1.1.1.4.2  rmind 	nfsrvd_getfh,
    149  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    150  1.1.1.1.4.2  rmind 	nfsrvd_lock,
    151  1.1.1.1.4.2  rmind 	nfsrvd_lockt,
    152  1.1.1.1.4.2  rmind 	nfsrvd_locku,
    153  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    154  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    155  1.1.1.1.4.2  rmind 	nfsrvd_verify,
    156  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    157  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    158  1.1.1.1.4.2  rmind 	nfsrvd_openconfirm,
    159  1.1.1.1.4.2  rmind 	nfsrvd_opendowngrade,
    160  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    161  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    162  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    163  1.1.1.1.4.2  rmind 	nfsrvd_read,
    164  1.1.1.1.4.2  rmind 	nfsrvd_readdirplus,
    165  1.1.1.1.4.2  rmind 	nfsrvd_readlink,
    166  1.1.1.1.4.2  rmind 	nfsrvd_remove,
    167  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    168  1.1.1.1.4.2  rmind 	nfsrvd_renew,
    169  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    170  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
    171  1.1.1.1.4.2  rmind 	nfsrvd_secinfo,
    172  1.1.1.1.4.2  rmind 	nfsrvd_setattr,
    173  1.1.1.1.4.2  rmind 	nfsrvd_setclientid,
    174  1.1.1.1.4.2  rmind 	nfsrvd_setclientidcfrm,
    175  1.1.1.1.4.2  rmind 	nfsrvd_verify,
    176  1.1.1.1.4.2  rmind 	nfsrvd_write,
    177  1.1.1.1.4.2  rmind 	nfsrvd_releaselckown,
    178  1.1.1.1.4.2  rmind };
    179  1.1.1.1.4.2  rmind 
    180  1.1.1.1.4.2  rmind int (*nfsrv4_ops1[NFSV4OP_NOPS])(struct nfsrv_descript *,
    181  1.1.1.1.4.2  rmind     int, vnode_t , vnode_t *, fhandle_t *,
    182  1.1.1.1.4.2  rmind     NFSPROC_T *, struct nfsexstuff *) = {
    183  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    184  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    185  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    186  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    187  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    188  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    189  1.1.1.1.4.2  rmind 	nfsrvd_mknod,
    190  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    191  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    192  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    193  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    194  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    195  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    196  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    197  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    198  1.1.1.1.4.2  rmind 	nfsrvd_lookup,
    199  1.1.1.1.4.2  rmind 	nfsrvd_lookup,
    200  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    201  1.1.1.1.4.2  rmind 	nfsrvd_open,
    202  1.1.1.1.4.2  rmind 	nfsrvd_openattr,
    203  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    204  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    205  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    206  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    207  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    208  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    209  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    210  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    211  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    212  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    213  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    214  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    215  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    216  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    217  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    218  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    219  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    220  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    221  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    222  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
    223  1.1.1.1.4.2  rmind };
    224  1.1.1.1.4.2  rmind 
    225  1.1.1.1.4.2  rmind int (*nfsrv4_ops2[NFSV4OP_NOPS])(struct nfsrv_descript *,
    226  1.1.1.1.4.2  rmind     int, vnode_t , vnode_t , NFSPROC_T *,
    227  1.1.1.1.4.2  rmind     struct nfsexstuff *, struct nfsexstuff *) = {
    228  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    229  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    230  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    231  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    232  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    233  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    234  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    235  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    236  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    237  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    238  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    239  1.1.1.1.4.2  rmind 	nfsrvd_link,
    240  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    241  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    242  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    243  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    244  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    245  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    246  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    247  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    248  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    249  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    250  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    251  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    252  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    253  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    254  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    255  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    256  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    257  1.1.1.1.4.2  rmind 	nfsrvd_rename,
    258  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    259  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    260  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    261  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    262  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    263  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    264  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    265  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    266  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    267  1.1.1.1.4.2  rmind 	(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
    268  1.1.1.1.4.2  rmind };
    269  1.1.1.1.4.2  rmind #endif	/* !APPLEKEXT */
    270  1.1.1.1.4.2  rmind 
    271  1.1.1.1.4.2  rmind /*
    272  1.1.1.1.4.2  rmind  * Static array that defines which nfs rpc's are nonidempotent
    273  1.1.1.1.4.2  rmind  */
    274  1.1.1.1.4.2  rmind static int nfsrv_nonidempotent[NFS_V3NPROCS] = {
    275  1.1.1.1.4.2  rmind 	FALSE,
    276  1.1.1.1.4.2  rmind 	FALSE,
    277  1.1.1.1.4.2  rmind 	TRUE,
    278  1.1.1.1.4.2  rmind 	FALSE,
    279  1.1.1.1.4.2  rmind 	FALSE,
    280  1.1.1.1.4.2  rmind 	FALSE,
    281  1.1.1.1.4.2  rmind 	FALSE,
    282  1.1.1.1.4.2  rmind 	TRUE,
    283  1.1.1.1.4.2  rmind 	TRUE,
    284  1.1.1.1.4.2  rmind 	TRUE,
    285  1.1.1.1.4.2  rmind 	TRUE,
    286  1.1.1.1.4.2  rmind 	TRUE,
    287  1.1.1.1.4.2  rmind 	TRUE,
    288  1.1.1.1.4.2  rmind 	TRUE,
    289  1.1.1.1.4.2  rmind 	TRUE,
    290  1.1.1.1.4.2  rmind 	TRUE,
    291  1.1.1.1.4.2  rmind 	FALSE,
    292  1.1.1.1.4.2  rmind 	FALSE,
    293  1.1.1.1.4.2  rmind 	FALSE,
    294  1.1.1.1.4.2  rmind 	FALSE,
    295  1.1.1.1.4.2  rmind 	FALSE,
    296  1.1.1.1.4.2  rmind 	FALSE,
    297  1.1.1.1.4.2  rmind };
    298  1.1.1.1.4.2  rmind 
    299  1.1.1.1.4.2  rmind /*
    300  1.1.1.1.4.2  rmind  * This static array indicates whether or not the RPC modifies the
    301  1.1.1.1.4.2  rmind  * file system.
    302  1.1.1.1.4.2  rmind  */
    303  1.1.1.1.4.2  rmind static int nfs_writerpc[NFS_NPROCS] = { 0, 0, 1, 0, 0, 0, 0,
    304  1.1.1.1.4.2  rmind     1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
    305  1.1.1.1.4.2  rmind     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
    306  1.1.1.1.4.2  rmind 
    307  1.1.1.1.4.2  rmind /* local functions */
    308  1.1.1.1.4.2  rmind static void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
    309  1.1.1.1.4.2  rmind     NFSPROC_T *p);
    310  1.1.1.1.4.2  rmind 
    311  1.1.1.1.4.2  rmind 
    312  1.1.1.1.4.2  rmind /*
    313  1.1.1.1.4.2  rmind  * This static array indicates which server procedures require the extra
    314  1.1.1.1.4.2  rmind  * arguments to return the current file handle for V2, 3.
    315  1.1.1.1.4.2  rmind  */
    316  1.1.1.1.4.2  rmind static int nfs_retfh[NFS_V3NPROCS] = { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
    317  1.1.1.1.4.2  rmind 	1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 };
    318  1.1.1.1.4.2  rmind 
    319  1.1.1.1.4.2  rmind extern struct nfsv4_opflag nfsv4_opflag[NFSV4OP_NOPS];
    320  1.1.1.1.4.2  rmind 
    321  1.1.1.1.4.2  rmind static int nfsv3to4op[NFS_V3NPROCS] = {
    322  1.1.1.1.4.2  rmind 	NFSPROC_NULL,
    323  1.1.1.1.4.2  rmind 	NFSV4OP_GETATTR,
    324  1.1.1.1.4.2  rmind 	NFSV4OP_SETATTR,
    325  1.1.1.1.4.2  rmind 	NFSV4OP_LOOKUP,
    326  1.1.1.1.4.2  rmind 	NFSV4OP_ACCESS,
    327  1.1.1.1.4.2  rmind 	NFSV4OP_READLINK,
    328  1.1.1.1.4.2  rmind 	NFSV4OP_READ,
    329  1.1.1.1.4.2  rmind 	NFSV4OP_WRITE,
    330  1.1.1.1.4.2  rmind 	NFSV4OP_V3CREATE,
    331  1.1.1.1.4.2  rmind 	NFSV4OP_MKDIR,
    332  1.1.1.1.4.2  rmind 	NFSV4OP_SYMLINK,
    333  1.1.1.1.4.2  rmind 	NFSV4OP_MKNOD,
    334  1.1.1.1.4.2  rmind 	NFSV4OP_REMOVE,
    335  1.1.1.1.4.2  rmind 	NFSV4OP_RMDIR,
    336  1.1.1.1.4.2  rmind 	NFSV4OP_RENAME,
    337  1.1.1.1.4.2  rmind 	NFSV4OP_LINK,
    338  1.1.1.1.4.2  rmind 	NFSV4OP_READDIR,
    339  1.1.1.1.4.2  rmind 	NFSV4OP_READDIRPLUS,
    340  1.1.1.1.4.2  rmind 	NFSV4OP_FSSTAT,
    341  1.1.1.1.4.2  rmind 	NFSV4OP_FSINFO,
    342  1.1.1.1.4.2  rmind 	NFSV4OP_PATHCONF,
    343  1.1.1.1.4.2  rmind 	NFSV4OP_COMMIT,
    344  1.1.1.1.4.2  rmind };
    345  1.1.1.1.4.2  rmind 
    346  1.1.1.1.4.2  rmind /*
    347  1.1.1.1.4.2  rmind  * Do an RPC. Basically, get the file handles translated to vnode pointers
    348  1.1.1.1.4.2  rmind  * and then call the appropriate server routine. The server routines are
    349  1.1.1.1.4.2  rmind  * split into groups, based on whether they use a file handle or file
    350  1.1.1.1.4.2  rmind  * handle plus name or ...
    351  1.1.1.1.4.2  rmind  * The NFS V4 Compound RPC is performed separately by nfsrvd_compound().
    352  1.1.1.1.4.2  rmind  */
    353  1.1.1.1.4.2  rmind APPLESTATIC void
    354  1.1.1.1.4.2  rmind nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
    355  1.1.1.1.4.2  rmind     NFSPROC_T *p)
    356  1.1.1.1.4.2  rmind {
    357  1.1.1.1.4.2  rmind 	int error = 0, lktype;
    358  1.1.1.1.4.2  rmind 	vnode_t vp;
    359  1.1.1.1.4.2  rmind 	mount_t mp = NULL;
    360  1.1.1.1.4.2  rmind 	struct nfsrvfh fh;
    361  1.1.1.1.4.2  rmind 	struct nfsexstuff nes;
    362  1.1.1.1.4.2  rmind 
    363  1.1.1.1.4.2  rmind 	/*
    364  1.1.1.1.4.2  rmind 	 * Get a locked vnode for the first file handle
    365  1.1.1.1.4.2  rmind 	 */
    366  1.1.1.1.4.2  rmind 	if (!(nd->nd_flag & ND_NFSV4)) {
    367  1.1.1.1.4.2  rmind 		KASSERT(nd->nd_repstat == 0, ("nfsrvd_dorpc"));
    368  1.1.1.1.4.2  rmind 		/*
    369  1.1.1.1.4.2  rmind 		 * For NFSv3, if the malloc/mget allocation is near limits,
    370  1.1.1.1.4.2  rmind 		 * return NFSERR_DELAY.
    371  1.1.1.1.4.2  rmind 		 */
    372  1.1.1.1.4.2  rmind 		if ((nd->nd_flag & ND_NFSV3) && nfsrv_mallocmget_limit()) {
    373  1.1.1.1.4.2  rmind 			nd->nd_repstat = NFSERR_DELAY;
    374  1.1.1.1.4.2  rmind 			vp = NULL;
    375  1.1.1.1.4.2  rmind 		} else {
    376  1.1.1.1.4.2  rmind 			error = nfsrv_mtofh(nd, &fh);
    377  1.1.1.1.4.2  rmind 			if (error) {
    378  1.1.1.1.4.2  rmind 				if (error != EBADRPC)
    379  1.1.1.1.4.2  rmind 					printf("nfs dorpc err1=%d\n", error);
    380  1.1.1.1.4.2  rmind 				nd->nd_repstat = NFSERR_GARBAGE;
    381  1.1.1.1.4.2  rmind 				goto out;
    382  1.1.1.1.4.2  rmind 			}
    383  1.1.1.1.4.2  rmind 			if (nd->nd_procnum == NFSPROC_READ ||
    384  1.1.1.1.4.2  rmind 			    nd->nd_procnum == NFSPROC_WRITE ||
    385  1.1.1.1.4.2  rmind 			    nd->nd_procnum == NFSPROC_READDIR ||
    386  1.1.1.1.4.2  rmind 			    nd->nd_procnum == NFSPROC_READLINK ||
    387  1.1.1.1.4.2  rmind 			    nd->nd_procnum == NFSPROC_GETATTR ||
    388  1.1.1.1.4.2  rmind 			    nd->nd_procnum == NFSPROC_ACCESS)
    389  1.1.1.1.4.2  rmind 				lktype = LK_SHARED;
    390  1.1.1.1.4.2  rmind 			else
    391  1.1.1.1.4.2  rmind 				lktype = LK_EXCLUSIVE;
    392  1.1.1.1.4.2  rmind 			if (nd->nd_flag & ND_PUBLOOKUP)
    393  1.1.1.1.4.2  rmind 				nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes,
    394  1.1.1.1.4.2  rmind 				    &mp, nfs_writerpc[nd->nd_procnum], p);
    395  1.1.1.1.4.2  rmind 			else
    396  1.1.1.1.4.2  rmind 				nfsd_fhtovp(nd, &fh, lktype, &vp, &nes,
    397  1.1.1.1.4.2  rmind 				    &mp, nfs_writerpc[nd->nd_procnum], p);
    398  1.1.1.1.4.2  rmind 			if (nd->nd_repstat == NFSERR_PROGNOTV4)
    399  1.1.1.1.4.2  rmind 				goto out;
    400  1.1.1.1.4.2  rmind 		}
    401  1.1.1.1.4.2  rmind 	}
    402  1.1.1.1.4.2  rmind 
    403  1.1.1.1.4.2  rmind 	/*
    404  1.1.1.1.4.2  rmind 	 * For V2 and 3, set the ND_SAVEREPLY flag for the recent request
    405  1.1.1.1.4.2  rmind 	 * cache, as required.
    406  1.1.1.1.4.2  rmind 	 * For V4, nfsrvd_compound() does this.
    407  1.1.1.1.4.2  rmind 	 */
    408  1.1.1.1.4.2  rmind 	if (!(nd->nd_flag & ND_NFSV4) && nfsrv_nonidempotent[nd->nd_procnum])
    409  1.1.1.1.4.2  rmind 		nd->nd_flag |= ND_SAVEREPLY;
    410  1.1.1.1.4.2  rmind 
    411  1.1.1.1.4.2  rmind 	nfsrvd_rephead(nd);
    412  1.1.1.1.4.2  rmind 	/*
    413  1.1.1.1.4.2  rmind 	 * If nd_repstat is non-zero, just fill in the reply status
    414  1.1.1.1.4.2  rmind 	 * to complete the RPC reply for V2. Otherwise, you must do
    415  1.1.1.1.4.2  rmind 	 * the RPC.
    416  1.1.1.1.4.2  rmind 	 */
    417  1.1.1.1.4.2  rmind 	if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) {
    418  1.1.1.1.4.2  rmind 		*nd->nd_errp = nfsd_errmap(nd);
    419  1.1.1.1.4.2  rmind 		NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
    420  1.1.1.1.4.2  rmind 		if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
    421  1.1.1.1.4.2  rmind 			vn_finished_write(mp);
    422  1.1.1.1.4.2  rmind 		goto out;
    423  1.1.1.1.4.2  rmind 	}
    424  1.1.1.1.4.2  rmind 
    425  1.1.1.1.4.2  rmind 	/*
    426  1.1.1.1.4.2  rmind 	 * Now the procedure can be performed. For V4, nfsrvd_compound()
    427  1.1.1.1.4.2  rmind 	 * works through the sub-rpcs, otherwise just call the procedure.
    428  1.1.1.1.4.2  rmind 	 * The procedures are in three groups with different arguments.
    429  1.1.1.1.4.2  rmind 	 * The group is indicated by the value in nfs_retfh[].
    430  1.1.1.1.4.2  rmind 	 */
    431  1.1.1.1.4.2  rmind 	if (nd->nd_flag & ND_NFSV4) {
    432  1.1.1.1.4.2  rmind 		nfsrvd_compound(nd, isdgram, p);
    433  1.1.1.1.4.2  rmind 	} else {
    434  1.1.1.1.4.2  rmind 		if (nfs_retfh[nd->nd_procnum] == 1) {
    435  1.1.1.1.4.2  rmind 			if (vp)
    436  1.1.1.1.4.2  rmind 				NFSVOPUNLOCK(vp, 0);
    437  1.1.1.1.4.2  rmind 			error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram,
    438  1.1.1.1.4.2  rmind 			    vp, NULL, (fhandle_t *)fh.nfsrvfh_data, p, &nes);
    439  1.1.1.1.4.2  rmind 		} else if (nfs_retfh[nd->nd_procnum] == 2) {
    440  1.1.1.1.4.2  rmind 			error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram,
    441  1.1.1.1.4.2  rmind 			    vp, NULL, p, &nes, NULL);
    442  1.1.1.1.4.2  rmind 		} else {
    443  1.1.1.1.4.2  rmind 			error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram,
    444  1.1.1.1.4.2  rmind 			    vp, p, &nes);
    445  1.1.1.1.4.2  rmind 		}
    446  1.1.1.1.4.2  rmind 		if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
    447  1.1.1.1.4.2  rmind 			vn_finished_write(mp);
    448  1.1.1.1.4.2  rmind 		NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
    449  1.1.1.1.4.2  rmind 	}
    450  1.1.1.1.4.2  rmind 	if (error) {
    451  1.1.1.1.4.2  rmind 		if (error != EBADRPC)
    452  1.1.1.1.4.2  rmind 			printf("nfs dorpc err2=%d\n", error);
    453  1.1.1.1.4.2  rmind 		nd->nd_repstat = NFSERR_GARBAGE;
    454  1.1.1.1.4.2  rmind 	}
    455  1.1.1.1.4.2  rmind 	*nd->nd_errp = nfsd_errmap(nd);
    456  1.1.1.1.4.2  rmind 
    457  1.1.1.1.4.2  rmind 	/*
    458  1.1.1.1.4.2  rmind 	 * Don't cache certain reply status values.
    459  1.1.1.1.4.2  rmind 	 */
    460  1.1.1.1.4.2  rmind 	if (nd->nd_repstat && (nd->nd_flag & ND_SAVEREPLY) &&
    461  1.1.1.1.4.2  rmind 	    (nd->nd_repstat == NFSERR_GARBAGE ||
    462  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_BADXDR ||
    463  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_MOVED ||
    464  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_DELAY ||
    465  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_BADSEQID ||
    466  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_RESOURCE ||
    467  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_SERVERFAULT ||
    468  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_STALECLIENTID ||
    469  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_STALESTATEID ||
    470  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_OLDSTATEID ||
    471  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_BADSTATEID ||
    472  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_GRACE ||
    473  1.1.1.1.4.2  rmind 	     nd->nd_repstat == NFSERR_NOGRACE))
    474  1.1.1.1.4.2  rmind 		nd->nd_flag &= ~ND_SAVEREPLY;
    475  1.1.1.1.4.2  rmind 
    476  1.1.1.1.4.2  rmind out:
    477  1.1.1.1.4.2  rmind 	NFSEXITCODE2(0, nd);
    478  1.1.1.1.4.2  rmind }
    479  1.1.1.1.4.2  rmind 
    480  1.1.1.1.4.2  rmind /*
    481  1.1.1.1.4.2  rmind  * Breaks down a compound RPC request and calls the server routines for
    482  1.1.1.1.4.2  rmind  * the subprocedures.
    483  1.1.1.1.4.2  rmind  * Some suboperations are performed directly here to simplify file handle<-->
    484  1.1.1.1.4.2  rmind  * vnode pointer handling.
    485  1.1.1.1.4.2  rmind  */
    486  1.1.1.1.4.2  rmind static void
    487  1.1.1.1.4.2  rmind nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
    488  1.1.1.1.4.2  rmind     NFSPROC_T *p)
    489  1.1.1.1.4.2  rmind {
    490  1.1.1.1.4.2  rmind 	int i, op;
    491  1.1.1.1.4.2  rmind 	u_int32_t *tl;
    492  1.1.1.1.4.2  rmind 	struct nfsclient *clp, *nclp;
    493  1.1.1.1.4.2  rmind 	int numops, taglen = -1, error = 0, igotlock;
    494  1.1.1.1.4.2  rmind 	u_int32_t minorvers, retops = 0, *retopsp = NULL, *repp;
    495  1.1.1.1.4.2  rmind 	u_char tag[NFSV4_SMALLSTR + 1], *tagstr;
    496  1.1.1.1.4.2  rmind 	vnode_t vp, nvp, savevp;
    497  1.1.1.1.4.2  rmind 	struct nfsrvfh fh;
    498  1.1.1.1.4.2  rmind 	mount_t new_mp, temp_mp = NULL;
    499  1.1.1.1.4.2  rmind 	struct ucred *credanon;
    500  1.1.1.1.4.2  rmind 	struct nfsexstuff nes, vpnes, savevpnes;
    501  1.1.1.1.4.2  rmind 	fsid_t cur_fsid, save_fsid;
    502  1.1.1.1.4.2  rmind 	static u_int64_t compref = 0;
    503  1.1.1.1.4.2  rmind 
    504  1.1.1.1.4.2  rmind 	NFSVNO_EXINIT(&vpnes);
    505  1.1.1.1.4.2  rmind 	NFSVNO_EXINIT(&savevpnes);
    506  1.1.1.1.4.2  rmind 	/*
    507  1.1.1.1.4.2  rmind 	 * Put the seq# of the current compound RPC in nfsrv_descript.
    508  1.1.1.1.4.2  rmind 	 * (This is used by nfsrv_checkgetattr(), to see if the write
    509  1.1.1.1.4.2  rmind 	 *  delegation was created by the same compound RPC as the one
    510  1.1.1.1.4.2  rmind 	 *  with that Getattr in it.)
    511  1.1.1.1.4.2  rmind 	 * Don't worry about the 64bit number wrapping around. It ain't
    512  1.1.1.1.4.2  rmind 	 * gonna happen before this server gets shut down/rebooted.
    513  1.1.1.1.4.2  rmind 	 */
    514  1.1.1.1.4.2  rmind 	nd->nd_compref = compref++;
    515  1.1.1.1.4.2  rmind 
    516  1.1.1.1.4.2  rmind 	/*
    517  1.1.1.1.4.2  rmind 	 * Check for and optionally get a lock on the root. This lock means that
    518  1.1.1.1.4.2  rmind 	 * no nfsd will be fiddling with the V4 file system and state stuff. It
    519  1.1.1.1.4.2  rmind 	 * is required when the V4 root is being changed, the stable storage
    520  1.1.1.1.4.2  rmind 	 * restart file is being updated, or callbacks are being done.
    521  1.1.1.1.4.2  rmind 	 * When any of the nfsd are processing an NFSv4 compound RPC, they must
    522  1.1.1.1.4.2  rmind 	 * either hold a reference count (nfs_usecnt) or the lock. When
    523  1.1.1.1.4.2  rmind 	 * nfsrv_unlock() is called to release the lock, it can optionally
    524  1.1.1.1.4.2  rmind 	 * also get a reference count, which saves the need for a call to
    525  1.1.1.1.4.2  rmind 	 * nfsrv_getref() after nfsrv_unlock().
    526  1.1.1.1.4.2  rmind 	 */
    527  1.1.1.1.4.2  rmind 	/*
    528  1.1.1.1.4.2  rmind 	 * First, check to see if we need to wait for an update lock.
    529  1.1.1.1.4.2  rmind 	 */
    530  1.1.1.1.4.2  rmind 	igotlock = 0;
    531  1.1.1.1.4.2  rmind 	NFSLOCKV4ROOTMUTEX();
    532  1.1.1.1.4.2  rmind 	if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK)
    533  1.1.1.1.4.2  rmind 		igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
    534  1.1.1.1.4.2  rmind 		    NFSV4ROOTLOCKMUTEXPTR, NULL);
    535  1.1.1.1.4.2  rmind 	else
    536  1.1.1.1.4.2  rmind 		igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL,
    537  1.1.1.1.4.2  rmind 		    NFSV4ROOTLOCKMUTEXPTR, NULL);
    538  1.1.1.1.4.2  rmind 	NFSUNLOCKV4ROOTMUTEX();
    539  1.1.1.1.4.2  rmind 	if (igotlock) {
    540  1.1.1.1.4.2  rmind 		/*
    541  1.1.1.1.4.2  rmind 		 * If I got the lock, I can update the stable storage file.
    542  1.1.1.1.4.2  rmind 		 * Done when the grace period is over or a client has long
    543  1.1.1.1.4.2  rmind 		 * since expired.
    544  1.1.1.1.4.2  rmind 		 */
    545  1.1.1.1.4.2  rmind 		nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NEEDLOCK;
    546  1.1.1.1.4.2  rmind 		if ((nfsrv_stablefirst.nsf_flags &
    547  1.1.1.1.4.2  rmind 		    (NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER)
    548  1.1.1.1.4.2  rmind 			nfsrv_updatestable(p);
    549  1.1.1.1.4.2  rmind 
    550  1.1.1.1.4.2  rmind 		/*
    551  1.1.1.1.4.2  rmind 		 * If at least one client has long since expired, search
    552  1.1.1.1.4.2  rmind 		 * the client list for them, write a REVOKE record on the
    553  1.1.1.1.4.2  rmind 		 * stable storage file and then remove them from the client
    554  1.1.1.1.4.2  rmind 		 * list.
    555  1.1.1.1.4.2  rmind 		 */
    556  1.1.1.1.4.2  rmind 		if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) {
    557  1.1.1.1.4.2  rmind 			nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT;
    558  1.1.1.1.4.2  rmind 			for (i = 0; i < NFSCLIENTHASHSIZE; i++) {
    559  1.1.1.1.4.2  rmind 			    LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash,
    560  1.1.1.1.4.2  rmind 				nclp) {
    561  1.1.1.1.4.2  rmind 				if (clp->lc_flags & LCL_EXPIREIT) {
    562  1.1.1.1.4.2  rmind 				    if (!LIST_EMPTY(&clp->lc_open) ||
    563  1.1.1.1.4.2  rmind 					!LIST_EMPTY(&clp->lc_deleg))
    564  1.1.1.1.4.2  rmind 					nfsrv_writestable(clp->lc_id,
    565  1.1.1.1.4.2  rmind 					    clp->lc_idlen, NFSNST_REVOKE, p);
    566  1.1.1.1.4.2  rmind 				    nfsrv_cleanclient(clp, p);
    567  1.1.1.1.4.2  rmind 				    nfsrv_freedeleglist(&clp->lc_deleg);
    568  1.1.1.1.4.2  rmind 				    nfsrv_freedeleglist(&clp->lc_olddeleg);
    569  1.1.1.1.4.2  rmind 				    LIST_REMOVE(clp, lc_hash);
    570  1.1.1.1.4.2  rmind 				    nfsrv_zapclient(clp, p);
    571  1.1.1.1.4.2  rmind 				}
    572  1.1.1.1.4.2  rmind 			    }
    573  1.1.1.1.4.2  rmind 			}
    574  1.1.1.1.4.2  rmind 		}
    575  1.1.1.1.4.2  rmind 		NFSLOCKV4ROOTMUTEX();
    576  1.1.1.1.4.2  rmind 		nfsv4_unlock(&nfsv4rootfs_lock, 1);
    577  1.1.1.1.4.2  rmind 		NFSUNLOCKV4ROOTMUTEX();
    578  1.1.1.1.4.2  rmind 	} else {
    579  1.1.1.1.4.2  rmind 		/*
    580  1.1.1.1.4.2  rmind 		 * If we didn't get the lock, we need to get a refcnt,
    581  1.1.1.1.4.2  rmind 		 * which also checks for and waits for the lock.
    582  1.1.1.1.4.2  rmind 		 */
    583  1.1.1.1.4.2  rmind 		NFSLOCKV4ROOTMUTEX();
    584  1.1.1.1.4.2  rmind 		nfsv4_getref(&nfsv4rootfs_lock, NULL,
    585  1.1.1.1.4.2  rmind 		    NFSV4ROOTLOCKMUTEXPTR, NULL);
    586  1.1.1.1.4.2  rmind 		NFSUNLOCKV4ROOTMUTEX();
    587  1.1.1.1.4.2  rmind 	}
    588  1.1.1.1.4.2  rmind 
    589  1.1.1.1.4.2  rmind 	/*
    590  1.1.1.1.4.2  rmind 	 * If flagged, search for open owners that haven't had any opens
    591  1.1.1.1.4.2  rmind 	 * for a long time.
    592  1.1.1.1.4.2  rmind 	 */
    593  1.1.1.1.4.2  rmind 	if (nfsrv_stablefirst.nsf_flags & NFSNSF_NOOPENS) {
    594  1.1.1.1.4.2  rmind 		nfsrv_throwawayopens(p);
    595  1.1.1.1.4.2  rmind 	}
    596  1.1.1.1.4.2  rmind 
    597  1.1.1.1.4.2  rmind 	savevp = vp = NULL;
    598  1.1.1.1.4.2  rmind 	save_fsid.val[0] = save_fsid.val[1] = 0;
    599  1.1.1.1.4.2  rmind 	cur_fsid.val[0] = cur_fsid.val[1] = 0;
    600  1.1.1.1.4.2  rmind 	NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
    601  1.1.1.1.4.2  rmind 	taglen = fxdr_unsigned(int, *tl);
    602  1.1.1.1.4.2  rmind 	if (taglen < 0) {
    603  1.1.1.1.4.2  rmind 		error = EBADRPC;
    604  1.1.1.1.4.2  rmind 		goto nfsmout;
    605  1.1.1.1.4.2  rmind 	}
    606  1.1.1.1.4.2  rmind 	if (taglen <= NFSV4_SMALLSTR)
    607  1.1.1.1.4.2  rmind 		tagstr = tag;
    608  1.1.1.1.4.2  rmind 	else
    609  1.1.1.1.4.2  rmind 		tagstr = malloc(taglen + 1, M_TEMP, M_WAITOK);
    610  1.1.1.1.4.2  rmind 	error = nfsrv_mtostr(nd, tagstr, taglen);
    611  1.1.1.1.4.2  rmind 	if (error) {
    612  1.1.1.1.4.2  rmind 		if (taglen > NFSV4_SMALLSTR)
    613  1.1.1.1.4.2  rmind 			free(tagstr, M_TEMP);
    614  1.1.1.1.4.2  rmind 		taglen = -1;
    615  1.1.1.1.4.2  rmind 		goto nfsmout;
    616  1.1.1.1.4.2  rmind 	}
    617  1.1.1.1.4.2  rmind 	(void) nfsm_strtom(nd, tag, taglen);
    618  1.1.1.1.4.2  rmind 	if (taglen > NFSV4_SMALLSTR) {
    619  1.1.1.1.4.2  rmind 		free(tagstr, M_TEMP);
    620  1.1.1.1.4.2  rmind 	}
    621  1.1.1.1.4.2  rmind 	NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED);
    622  1.1.1.1.4.2  rmind 	NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
    623  1.1.1.1.4.2  rmind 	minorvers = fxdr_unsigned(u_int32_t, *tl++);
    624  1.1.1.1.4.2  rmind 	if (minorvers != NFSV4_MINORVERSION)
    625  1.1.1.1.4.2  rmind 		nd->nd_repstat = NFSERR_MINORVERMISMATCH;
    626  1.1.1.1.4.2  rmind 	if (nd->nd_repstat)
    627  1.1.1.1.4.2  rmind 		numops = 0;
    628  1.1.1.1.4.2  rmind 	else
    629  1.1.1.1.4.2  rmind 		numops = fxdr_unsigned(int, *tl);
    630  1.1.1.1.4.2  rmind 	/*
    631  1.1.1.1.4.2  rmind 	 * Loop around doing the sub ops.
    632  1.1.1.1.4.2  rmind 	 * vp - is an unlocked vnode pointer for the CFH
    633  1.1.1.1.4.2  rmind 	 * savevp - is an unlocked vnode pointer for the SAVEDFH
    634  1.1.1.1.4.2  rmind 	 * (at some future date, it might turn out to be more appropriate
    635  1.1.1.1.4.2  rmind 	 *  to keep the file handles instead of vnode pointers?)
    636  1.1.1.1.4.2  rmind 	 * savevpnes and vpnes - are the export flags for the above.
    637  1.1.1.1.4.2  rmind 	 */
    638  1.1.1.1.4.2  rmind 	for (i = 0; i < numops; i++) {
    639  1.1.1.1.4.2  rmind 		NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
    640  1.1.1.1.4.2  rmind 		NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED);
    641  1.1.1.1.4.2  rmind 		*repp = *tl;
    642  1.1.1.1.4.2  rmind 		op = fxdr_unsigned(int, *tl);
    643  1.1.1.1.4.2  rmind 		if (op < NFSV4OP_ACCESS || op >= NFSV4OP_NOPS) {
    644  1.1.1.1.4.2  rmind 			nd->nd_repstat = NFSERR_OPILLEGAL;
    645  1.1.1.1.4.2  rmind 			*repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL);
    646  1.1.1.1.4.2  rmind 			*repp = nfsd_errmap(nd);
    647  1.1.1.1.4.2  rmind 			retops++;
    648  1.1.1.1.4.2  rmind 			break;
    649  1.1.1.1.4.2  rmind 		} else {
    650  1.1.1.1.4.2  rmind 			repp++;
    651  1.1.1.1.4.2  rmind 		}
    652  1.1.1.1.4.2  rmind 
    653  1.1.1.1.4.2  rmind 		/*
    654  1.1.1.1.4.2  rmind 		 * Check for a referral on the current FH and, if so, return
    655  1.1.1.1.4.2  rmind 		 * NFSERR_MOVED for all ops that allow it, except Getattr.
    656  1.1.1.1.4.2  rmind 		 */
    657  1.1.1.1.4.2  rmind 		if (vp != NULL && op != NFSV4OP_GETATTR &&
    658  1.1.1.1.4.2  rmind 		    nfsv4root_getreferral(vp, NULL, 0) != NULL &&
    659  1.1.1.1.4.2  rmind 		    nfsrv_errmoved(op)) {
    660  1.1.1.1.4.2  rmind 			nd->nd_repstat = NFSERR_MOVED;
    661  1.1.1.1.4.2  rmind 			*repp = nfsd_errmap(nd);
    662  1.1.1.1.4.2  rmind 			retops++;
    663  1.1.1.1.4.2  rmind 			break;
    664  1.1.1.1.4.2  rmind 		}
    665  1.1.1.1.4.2  rmind 
    666  1.1.1.1.4.2  rmind 		nd->nd_procnum = op;
    667  1.1.1.1.4.2  rmind 		/*
    668  1.1.1.1.4.2  rmind 		 * If over flood level, reply NFSERR_RESOURCE, if at the first
    669  1.1.1.1.4.2  rmind 		 * Op. (Since a client recovery from NFSERR_RESOURCE can get
    670  1.1.1.1.4.2  rmind 		 * really nasty for certain Op sequences, I'll play it safe
    671  1.1.1.1.4.2  rmind 		 * and only return the error at the beginning.) The cache
    672  1.1.1.1.4.2  rmind 		 * will still function over flood level, but uses lots of
    673  1.1.1.1.4.2  rmind 		 * mbufs.)
    674  1.1.1.1.4.2  rmind 		 * If nfsrv_mallocmget_limit() returns True, the system is near
    675  1.1.1.1.4.2  rmind 		 * to its limit for memory that malloc()/mget() can allocate.
    676  1.1.1.1.4.2  rmind 		 */
    677  1.1.1.1.4.2  rmind 		if (i == 0 && nd->nd_rp->rc_refcnt == 0 &&
    678  1.1.1.1.4.2  rmind 		    (nfsrv_mallocmget_limit() ||
    679  1.1.1.1.4.2  rmind 		     nfsrc_tcpsavedreplies > nfsrc_floodlevel)) {
    680  1.1.1.1.4.2  rmind 			if (nfsrc_tcpsavedreplies > nfsrc_floodlevel) {
    681  1.1.1.1.4.2  rmind 				printf("nfsd server cache flooded, try to");
    682  1.1.1.1.4.2  rmind 				printf(" increase nfsrc_floodlevel\n");
    683  1.1.1.1.4.2  rmind 			}
    684  1.1.1.1.4.2  rmind 			nd->nd_repstat = NFSERR_RESOURCE;
    685  1.1.1.1.4.2  rmind 			*repp = nfsd_errmap(nd);
    686  1.1.1.1.4.2  rmind 			if (op == NFSV4OP_SETATTR) {
    687  1.1.1.1.4.2  rmind 				/*
    688  1.1.1.1.4.2  rmind 				 * Setattr replies require a bitmap.
    689  1.1.1.1.4.2  rmind 				 * even for errors like these.
    690  1.1.1.1.4.2  rmind 				 */
    691  1.1.1.1.4.2  rmind 				NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
    692  1.1.1.1.4.2  rmind 				*tl = 0;
    693  1.1.1.1.4.2  rmind 			}
    694  1.1.1.1.4.2  rmind 			retops++;
    695  1.1.1.1.4.2  rmind 			break;
    696  1.1.1.1.4.2  rmind 		}
    697  1.1.1.1.4.2  rmind 		if (nfsv4_opflag[op].savereply)
    698  1.1.1.1.4.2  rmind 			nd->nd_flag |= ND_SAVEREPLY;
    699  1.1.1.1.4.2  rmind 		NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]);
    700  1.1.1.1.4.2  rmind 		switch (op) {
    701  1.1.1.1.4.2  rmind 		case NFSV4OP_PUTFH:
    702  1.1.1.1.4.2  rmind 			error = nfsrv_mtofh(nd, &fh);
    703  1.1.1.1.4.2  rmind 			if (error)
    704  1.1.1.1.4.2  rmind 				goto nfsmout;
    705  1.1.1.1.4.2  rmind 			if (!nd->nd_repstat)
    706  1.1.1.1.4.2  rmind 				nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes,
    707  1.1.1.1.4.2  rmind 				    NULL, 0, p);
    708  1.1.1.1.4.2  rmind 			/* For now, allow this for non-export FHs */
    709  1.1.1.1.4.2  rmind 			if (!nd->nd_repstat) {
    710  1.1.1.1.4.2  rmind 				if (vp)
    711  1.1.1.1.4.2  rmind 					vrele(vp);
    712  1.1.1.1.4.2  rmind 				vp = nvp;
    713  1.1.1.1.4.2  rmind 				cur_fsid = vp->v_mount->mnt_stat.f_fsid;
    714  1.1.1.1.4.2  rmind 				NFSVOPUNLOCK(vp, 0);
    715  1.1.1.1.4.2  rmind 				vpnes = nes;
    716  1.1.1.1.4.2  rmind 			}
    717  1.1.1.1.4.2  rmind 			break;
    718  1.1.1.1.4.2  rmind 		case NFSV4OP_PUTPUBFH:
    719  1.1.1.1.4.2  rmind 			if (nfs_pubfhset)
    720  1.1.1.1.4.2  rmind 			    nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp,
    721  1.1.1.1.4.2  rmind 				&nes, NULL, 0, p);
    722  1.1.1.1.4.2  rmind 			else
    723  1.1.1.1.4.2  rmind 			    nd->nd_repstat = NFSERR_NOFILEHANDLE;
    724  1.1.1.1.4.2  rmind 			if (!nd->nd_repstat) {
    725  1.1.1.1.4.2  rmind 				if (vp)
    726  1.1.1.1.4.2  rmind 					vrele(vp);
    727  1.1.1.1.4.2  rmind 				vp = nvp;
    728  1.1.1.1.4.2  rmind 				cur_fsid = vp->v_mount->mnt_stat.f_fsid;
    729  1.1.1.1.4.2  rmind 				NFSVOPUNLOCK(vp, 0);
    730  1.1.1.1.4.2  rmind 				vpnes = nes;
    731  1.1.1.1.4.2  rmind 			}
    732  1.1.1.1.4.2  rmind 			break;
    733  1.1.1.1.4.2  rmind 		case NFSV4OP_PUTROOTFH:
    734  1.1.1.1.4.2  rmind 			if (nfs_rootfhset) {
    735  1.1.1.1.4.2  rmind 				nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp,
    736  1.1.1.1.4.2  rmind 				    &nes, NULL, 0, p);
    737  1.1.1.1.4.2  rmind 				if (!nd->nd_repstat) {
    738  1.1.1.1.4.2  rmind 					if (vp)
    739  1.1.1.1.4.2  rmind 						vrele(vp);
    740  1.1.1.1.4.2  rmind 					vp = nvp;
    741  1.1.1.1.4.2  rmind 					cur_fsid = vp->v_mount->mnt_stat.f_fsid;
    742  1.1.1.1.4.2  rmind 					NFSVOPUNLOCK(vp, 0);
    743  1.1.1.1.4.2  rmind 					vpnes = nes;
    744  1.1.1.1.4.2  rmind 				}
    745  1.1.1.1.4.2  rmind 			} else
    746  1.1.1.1.4.2  rmind 				nd->nd_repstat = NFSERR_NOFILEHANDLE;
    747  1.1.1.1.4.2  rmind 			break;
    748  1.1.1.1.4.2  rmind 		case NFSV4OP_SAVEFH:
    749  1.1.1.1.4.2  rmind 			if (vp && NFSVNO_EXPORTED(&vpnes)) {
    750  1.1.1.1.4.2  rmind 				nd->nd_repstat = 0;
    751  1.1.1.1.4.2  rmind 				/* If vp == savevp, a no-op */
    752  1.1.1.1.4.2  rmind 				if (vp != savevp) {
    753  1.1.1.1.4.2  rmind 					if (savevp)
    754  1.1.1.1.4.2  rmind 						vrele(savevp);
    755  1.1.1.1.4.2  rmind 					VREF(vp);
    756  1.1.1.1.4.2  rmind 					savevp = vp;
    757  1.1.1.1.4.2  rmind 					savevpnes = vpnes;
    758  1.1.1.1.4.2  rmind 					save_fsid = cur_fsid;
    759  1.1.1.1.4.2  rmind 				}
    760  1.1.1.1.4.2  rmind 			} else {
    761  1.1.1.1.4.2  rmind 				nd->nd_repstat = NFSERR_NOFILEHANDLE;
    762  1.1.1.1.4.2  rmind 			}
    763  1.1.1.1.4.2  rmind 			break;
    764  1.1.1.1.4.2  rmind 		case NFSV4OP_RESTOREFH:
    765  1.1.1.1.4.2  rmind 			if (savevp) {
    766  1.1.1.1.4.2  rmind 				nd->nd_repstat = 0;
    767  1.1.1.1.4.2  rmind 				/* If vp == savevp, a no-op */
    768  1.1.1.1.4.2  rmind 				if (vp != savevp) {
    769  1.1.1.1.4.2  rmind 					VREF(savevp);
    770  1.1.1.1.4.2  rmind 					vrele(vp);
    771  1.1.1.1.4.2  rmind 					vp = savevp;
    772  1.1.1.1.4.2  rmind 					vpnes = savevpnes;
    773  1.1.1.1.4.2  rmind 					cur_fsid = save_fsid;
    774  1.1.1.1.4.2  rmind 				}
    775  1.1.1.1.4.2  rmind 			} else {
    776  1.1.1.1.4.2  rmind 				nd->nd_repstat = NFSERR_RESTOREFH;
    777  1.1.1.1.4.2  rmind 			}
    778  1.1.1.1.4.2  rmind 			break;
    779  1.1.1.1.4.2  rmind 		default:
    780  1.1.1.1.4.2  rmind 		    /*
    781  1.1.1.1.4.2  rmind 		     * Allow a Lookup, Getattr, GetFH, Secinfo on an
    782  1.1.1.1.4.2  rmind 		     * non-exported directory if
    783  1.1.1.1.4.2  rmind 		     * nfs_rootfhset. Do I need to allow any other Ops?
    784  1.1.1.1.4.2  rmind 		     * (You can only have a non-exported vpnes if
    785  1.1.1.1.4.2  rmind 		     *  nfs_rootfhset is true. See nfsd_fhtovp())
    786  1.1.1.1.4.2  rmind 		     * Allow AUTH_SYS to be used for file systems
    787  1.1.1.1.4.2  rmind 		     * exported GSS only for certain Ops, to allow
    788  1.1.1.1.4.2  rmind 		     * clients to do mounts more easily.
    789  1.1.1.1.4.2  rmind 		     */
    790  1.1.1.1.4.2  rmind 		    if (nfsv4_opflag[op].needscfh && vp) {
    791  1.1.1.1.4.2  rmind 			if (!NFSVNO_EXPORTED(&vpnes) &&
    792  1.1.1.1.4.2  rmind 			    op != NFSV4OP_LOOKUP &&
    793  1.1.1.1.4.2  rmind 			    op != NFSV4OP_GETATTR &&
    794  1.1.1.1.4.2  rmind 			    op != NFSV4OP_GETFH &&
    795  1.1.1.1.4.2  rmind 			    op != NFSV4OP_ACCESS &&
    796  1.1.1.1.4.2  rmind 			    op != NFSV4OP_READLINK &&
    797  1.1.1.1.4.2  rmind 			    op != NFSV4OP_SECINFO)
    798  1.1.1.1.4.2  rmind 				nd->nd_repstat = NFSERR_NOFILEHANDLE;
    799  1.1.1.1.4.2  rmind 			else if (nfsvno_testexp(nd, &vpnes) &&
    800  1.1.1.1.4.2  rmind 			    op != NFSV4OP_LOOKUP &&
    801  1.1.1.1.4.2  rmind 			    op != NFSV4OP_GETFH &&
    802  1.1.1.1.4.2  rmind 			    op != NFSV4OP_GETATTR &&
    803  1.1.1.1.4.2  rmind 			    op != NFSV4OP_SECINFO)
    804  1.1.1.1.4.2  rmind 				nd->nd_repstat = NFSERR_WRONGSEC;
    805  1.1.1.1.4.2  rmind 			if (nd->nd_repstat) {
    806  1.1.1.1.4.2  rmind 				if (op == NFSV4OP_SETATTR) {
    807  1.1.1.1.4.2  rmind 				    /*
    808  1.1.1.1.4.2  rmind 				     * Setattr reply requires a bitmap
    809  1.1.1.1.4.2  rmind 				     * even for errors like these.
    810  1.1.1.1.4.2  rmind 				     */
    811  1.1.1.1.4.2  rmind 				    NFSM_BUILD(tl, u_int32_t *,
    812  1.1.1.1.4.2  rmind 					NFSX_UNSIGNED);
    813  1.1.1.1.4.2  rmind 				    *tl = 0;
    814  1.1.1.1.4.2  rmind 				}
    815  1.1.1.1.4.2  rmind 				break;
    816  1.1.1.1.4.2  rmind 			}
    817  1.1.1.1.4.2  rmind 		    }
    818  1.1.1.1.4.2  rmind 		    if (nfsv4_opflag[op].retfh == 1) {
    819  1.1.1.1.4.2  rmind 			if (!vp) {
    820  1.1.1.1.4.2  rmind 				nd->nd_repstat = NFSERR_NOFILEHANDLE;
    821  1.1.1.1.4.2  rmind 				break;
    822  1.1.1.1.4.2  rmind 			}
    823  1.1.1.1.4.2  rmind 			VREF(vp);
    824  1.1.1.1.4.2  rmind 			if (nfsv4_opflag[op].modifyfs)
    825  1.1.1.1.4.2  rmind 				vn_start_write(vp, &temp_mp, V_WAIT);
    826  1.1.1.1.4.2  rmind 			error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp,
    827  1.1.1.1.4.2  rmind 			    &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes);
    828  1.1.1.1.4.2  rmind 			if (!error && !nd->nd_repstat) {
    829  1.1.1.1.4.2  rmind 			    if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) {
    830  1.1.1.1.4.2  rmind 				new_mp = nvp->v_mount;
    831  1.1.1.1.4.2  rmind 				if (cur_fsid.val[0] !=
    832  1.1.1.1.4.2  rmind 				    new_mp->mnt_stat.f_fsid.val[0] ||
    833  1.1.1.1.4.2  rmind 				    cur_fsid.val[1] !=
    834  1.1.1.1.4.2  rmind 				    new_mp->mnt_stat.f_fsid.val[1]) {
    835  1.1.1.1.4.2  rmind 				    /* crossed a server mount point */
    836  1.1.1.1.4.2  rmind 				    nd->nd_repstat = nfsvno_checkexp(new_mp,
    837  1.1.1.1.4.2  rmind 					nd->nd_nam, &nes, &credanon);
    838  1.1.1.1.4.2  rmind 				    if (!nd->nd_repstat)
    839  1.1.1.1.4.2  rmind 					nd->nd_repstat = nfsd_excred(nd,
    840  1.1.1.1.4.2  rmind 					    &nes, credanon);
    841  1.1.1.1.4.2  rmind 				    if (credanon != NULL)
    842  1.1.1.1.4.2  rmind 					crfree(credanon);
    843  1.1.1.1.4.2  rmind 				    if (!nd->nd_repstat) {
    844  1.1.1.1.4.2  rmind 					vpnes = nes;
    845  1.1.1.1.4.2  rmind 					cur_fsid = new_mp->mnt_stat.f_fsid;
    846  1.1.1.1.4.2  rmind 				    }
    847  1.1.1.1.4.2  rmind 				}
    848  1.1.1.1.4.2  rmind 				/* Lookup ops return a locked vnode */
    849  1.1.1.1.4.2  rmind 				NFSVOPUNLOCK(nvp, 0);
    850  1.1.1.1.4.2  rmind 			    }
    851  1.1.1.1.4.2  rmind 			    if (!nd->nd_repstat) {
    852  1.1.1.1.4.2  rmind 				    vrele(vp);
    853  1.1.1.1.4.2  rmind 				    vp = nvp;
    854  1.1.1.1.4.2  rmind 			    } else
    855  1.1.1.1.4.2  rmind 				    vrele(nvp);
    856  1.1.1.1.4.2  rmind 			}
    857  1.1.1.1.4.2  rmind 			if (nfsv4_opflag[op].modifyfs)
    858  1.1.1.1.4.2  rmind 				vn_finished_write(temp_mp);
    859  1.1.1.1.4.2  rmind 		    } else if (nfsv4_opflag[op].retfh == 2) {
    860  1.1.1.1.4.2  rmind 			if (vp == NULL || savevp == NULL) {
    861  1.1.1.1.4.2  rmind 				nd->nd_repstat = NFSERR_NOFILEHANDLE;
    862  1.1.1.1.4.2  rmind 				break;
    863  1.1.1.1.4.2  rmind 			} else if (cur_fsid.val[0] != save_fsid.val[0] ||
    864  1.1.1.1.4.2  rmind 			    cur_fsid.val[1] != save_fsid.val[1]) {
    865  1.1.1.1.4.2  rmind 				nd->nd_repstat = NFSERR_XDEV;
    866  1.1.1.1.4.2  rmind 				break;
    867  1.1.1.1.4.2  rmind 			}
    868  1.1.1.1.4.2  rmind 			if (nfsv4_opflag[op].modifyfs)
    869  1.1.1.1.4.2  rmind 				vn_start_write(savevp, &temp_mp, V_WAIT);
    870  1.1.1.1.4.2  rmind 			if (NFSVOPLOCK(savevp, LK_EXCLUSIVE) == 0) {
    871  1.1.1.1.4.2  rmind 				VREF(vp);
    872  1.1.1.1.4.2  rmind 				VREF(savevp);
    873  1.1.1.1.4.2  rmind 				error = (*(nfsrv4_ops2[op]))(nd, isdgram,
    874  1.1.1.1.4.2  rmind 				    savevp, vp, p, &savevpnes, &vpnes);
    875  1.1.1.1.4.2  rmind 			} else
    876  1.1.1.1.4.2  rmind 				nd->nd_repstat = NFSERR_PERM;
    877  1.1.1.1.4.2  rmind 			if (nfsv4_opflag[op].modifyfs)
    878  1.1.1.1.4.2  rmind 				vn_finished_write(temp_mp);
    879  1.1.1.1.4.2  rmind 		    } else {
    880  1.1.1.1.4.2  rmind 			if (nfsv4_opflag[op].retfh != 0)
    881  1.1.1.1.4.2  rmind 				panic("nfsrvd_compound");
    882  1.1.1.1.4.2  rmind 			if (nfsv4_opflag[op].needscfh) {
    883  1.1.1.1.4.2  rmind 				if (vp != NULL) {
    884  1.1.1.1.4.2  rmind 					if (nfsv4_opflag[op].modifyfs)
    885  1.1.1.1.4.2  rmind 						vn_start_write(vp, &temp_mp,
    886  1.1.1.1.4.2  rmind 						    V_WAIT);
    887  1.1.1.1.4.2  rmind 					if (NFSVOPLOCK(vp, nfsv4_opflag[op].lktype)
    888  1.1.1.1.4.2  rmind 					    == 0)
    889  1.1.1.1.4.2  rmind 						VREF(vp);
    890  1.1.1.1.4.2  rmind 					else
    891  1.1.1.1.4.2  rmind 						nd->nd_repstat = NFSERR_PERM;
    892  1.1.1.1.4.2  rmind 				} else {
    893  1.1.1.1.4.2  rmind 					nd->nd_repstat = NFSERR_NOFILEHANDLE;
    894  1.1.1.1.4.2  rmind 					if (op == NFSV4OP_SETATTR) {
    895  1.1.1.1.4.2  rmind 						/*
    896  1.1.1.1.4.2  rmind 						 * Setattr reply requires a
    897  1.1.1.1.4.2  rmind 						 * bitmap even for errors like
    898  1.1.1.1.4.2  rmind 						 * these.
    899  1.1.1.1.4.2  rmind 						 */
    900  1.1.1.1.4.2  rmind 						NFSM_BUILD(tl, u_int32_t *,
    901  1.1.1.1.4.2  rmind 						    NFSX_UNSIGNED);
    902  1.1.1.1.4.2  rmind 						*tl = 0;
    903  1.1.1.1.4.2  rmind 					}
    904  1.1.1.1.4.2  rmind 					break;
    905  1.1.1.1.4.2  rmind 				}
    906  1.1.1.1.4.2  rmind 				if (nd->nd_repstat == 0)
    907  1.1.1.1.4.2  rmind 					error = (*(nfsrv4_ops0[op]))(nd,
    908  1.1.1.1.4.2  rmind 					    isdgram, vp, p, &vpnes);
    909  1.1.1.1.4.2  rmind 				if (nfsv4_opflag[op].modifyfs)
    910  1.1.1.1.4.2  rmind 					vn_finished_write(temp_mp);
    911  1.1.1.1.4.2  rmind 			} else {
    912  1.1.1.1.4.2  rmind 				error = (*(nfsrv4_ops0[op]))(nd, isdgram,
    913  1.1.1.1.4.2  rmind 				    NULL, p, &vpnes);
    914  1.1.1.1.4.2  rmind 			}
    915  1.1.1.1.4.2  rmind 		    }
    916  1.1.1.1.4.2  rmind 		};
    917  1.1.1.1.4.2  rmind 		if (error) {
    918  1.1.1.1.4.2  rmind 			if (error == EBADRPC || error == NFSERR_BADXDR) {
    919  1.1.1.1.4.2  rmind 				nd->nd_repstat = NFSERR_BADXDR;
    920  1.1.1.1.4.2  rmind 			} else {
    921  1.1.1.1.4.2  rmind 				nd->nd_repstat = error;
    922  1.1.1.1.4.2  rmind 				printf("nfsv4 comperr0=%d\n", error);
    923  1.1.1.1.4.2  rmind 			}
    924  1.1.1.1.4.2  rmind 			error = 0;
    925  1.1.1.1.4.2  rmind 		}
    926  1.1.1.1.4.2  rmind 		retops++;
    927  1.1.1.1.4.2  rmind 		if (nd->nd_repstat) {
    928  1.1.1.1.4.2  rmind 			*repp = nfsd_errmap(nd);
    929  1.1.1.1.4.2  rmind 			break;
    930  1.1.1.1.4.2  rmind 		} else {
    931  1.1.1.1.4.2  rmind 			*repp = 0;	/* NFS4_OK */
    932  1.1.1.1.4.2  rmind 		}
    933  1.1.1.1.4.2  rmind 	}
    934  1.1.1.1.4.2  rmind nfsmout:
    935  1.1.1.1.4.2  rmind 	if (error) {
    936  1.1.1.1.4.2  rmind 		if (error == EBADRPC || error == NFSERR_BADXDR)
    937  1.1.1.1.4.2  rmind 			nd->nd_repstat = NFSERR_BADXDR;
    938  1.1.1.1.4.2  rmind 		else
    939  1.1.1.1.4.2  rmind 			printf("nfsv4 comperr1=%d\n", error);
    940  1.1.1.1.4.2  rmind 	}
    941  1.1.1.1.4.2  rmind 	if (taglen == -1) {
    942  1.1.1.1.4.2  rmind 		NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
    943  1.1.1.1.4.2  rmind 		*tl++ = 0;
    944  1.1.1.1.4.2  rmind 		*tl = 0;
    945  1.1.1.1.4.2  rmind 	} else {
    946  1.1.1.1.4.2  rmind 		*retopsp = txdr_unsigned(retops);
    947  1.1.1.1.4.2  rmind 	}
    948  1.1.1.1.4.2  rmind 	if (vp)
    949  1.1.1.1.4.2  rmind 		vrele(vp);
    950  1.1.1.1.4.2  rmind 	if (savevp)
    951  1.1.1.1.4.2  rmind 		vrele(savevp);
    952  1.1.1.1.4.2  rmind 	NFSLOCKV4ROOTMUTEX();
    953  1.1.1.1.4.2  rmind 	nfsv4_relref(&nfsv4rootfs_lock);
    954  1.1.1.1.4.2  rmind 	NFSUNLOCKV4ROOTMUTEX();
    955  1.1.1.1.4.2  rmind 
    956  1.1.1.1.4.2  rmind 	NFSEXITCODE2(0, nd);
    957  1.1.1.1.4.2  rmind }
    958