The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/nfsserver/nfs_nfsdsocket.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: f1e04ef85451d6526adbe4cd2856da25


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.