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