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