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$");
   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_WRITE ||
  383                             nd->nd_procnum == NFSPROC_READDIR ||
  384                             nd->nd_procnum == NFSPROC_READLINK ||
  385                             nd->nd_procnum == NFSPROC_GETATTR ||
  386                             nd->nd_procnum == NFSPROC_ACCESS)
  387                                 lktype = LK_SHARED;
  388                         else
  389                                 lktype = LK_EXCLUSIVE;
  390                         if (nd->nd_flag & ND_PUBLOOKUP)
  391                                 nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes,
  392                                     &mp, nfs_writerpc[nd->nd_procnum], p);
  393                         else
  394                                 nfsd_fhtovp(nd, &fh, lktype, &vp, &nes,
  395                                     &mp, nfs_writerpc[nd->nd_procnum], p);
  396                         if (nd->nd_repstat == NFSERR_PROGNOTV4)
  397                                 goto out;
  398                 }
  399         }
  400 
  401         /*
  402          * For V2 and 3, set the ND_SAVEREPLY flag for the recent request
  403          * cache, as required.
  404          * For V4, nfsrvd_compound() does this.
  405          */
  406         if (!(nd->nd_flag & ND_NFSV4) && nfsrv_nonidempotent[nd->nd_procnum])
  407                 nd->nd_flag |= ND_SAVEREPLY;
  408 
  409         nfsrvd_rephead(nd);
  410         /*
  411          * If nd_repstat is non-zero, just fill in the reply status
  412          * to complete the RPC reply for V2. Otherwise, you must do
  413          * the RPC.
  414          */
  415         if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) {
  416                 *nd->nd_errp = nfsd_errmap(nd);
  417                 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
  418                 if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
  419                         vn_finished_write(mp);
  420                 goto out;
  421         }
  422 
  423         /*
  424          * Now the procedure can be performed. For V4, nfsrvd_compound()
  425          * works through the sub-rpcs, otherwise just call the procedure.
  426          * The procedures are in three groups with different arguments.
  427          * The group is indicated by the value in nfs_retfh[].
  428          */
  429         if (nd->nd_flag & ND_NFSV4) {
  430                 nfsrvd_compound(nd, isdgram, p);
  431         } else {
  432                 if (nfs_retfh[nd->nd_procnum] == 1) {
  433                         if (vp)
  434                                 NFSVOPUNLOCK(vp, 0);
  435                         error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram,
  436                             vp, NULL, (fhandle_t *)fh.nfsrvfh_data, p, &nes);
  437                 } else if (nfs_retfh[nd->nd_procnum] == 2) {
  438                         error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram,
  439                             vp, NULL, p, &nes, NULL);
  440                 } else {
  441                         error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram,
  442                             vp, p, &nes);
  443                 }
  444                 if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
  445                         vn_finished_write(mp);
  446                 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
  447         }
  448         if (error) {
  449                 if (error != EBADRPC)
  450                         printf("nfs dorpc err2=%d\n", error);
  451                 nd->nd_repstat = NFSERR_GARBAGE;
  452         }
  453         *nd->nd_errp = nfsd_errmap(nd);
  454 
  455         /*
  456          * Don't cache certain reply status values.
  457          */
  458         if (nd->nd_repstat && (nd->nd_flag & ND_SAVEREPLY) &&
  459             (nd->nd_repstat == NFSERR_GARBAGE ||
  460              nd->nd_repstat == NFSERR_BADXDR ||
  461              nd->nd_repstat == NFSERR_MOVED ||
  462              nd->nd_repstat == NFSERR_DELAY ||
  463              nd->nd_repstat == NFSERR_BADSEQID ||
  464              nd->nd_repstat == NFSERR_RESOURCE ||
  465              nd->nd_repstat == NFSERR_SERVERFAULT ||
  466              nd->nd_repstat == NFSERR_STALECLIENTID ||
  467              nd->nd_repstat == NFSERR_STALESTATEID ||
  468              nd->nd_repstat == NFSERR_OLDSTATEID ||
  469              nd->nd_repstat == NFSERR_BADSTATEID ||
  470              nd->nd_repstat == NFSERR_GRACE ||
  471              nd->nd_repstat == NFSERR_NOGRACE))
  472                 nd->nd_flag &= ~ND_SAVEREPLY;
  473 
  474 out:
  475         NFSEXITCODE2(0, nd);
  476 }
  477 
  478 /*
  479  * Breaks down a compound RPC request and calls the server routines for
  480  * the subprocedures.
  481  * Some suboperations are performed directly here to simplify file handle<-->
  482  * vnode pointer handling.
  483  */
  484 static void
  485 nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
  486     NFSPROC_T *p)
  487 {
  488         int i, op;
  489         u_int32_t *tl;
  490         struct nfsclient *clp, *nclp;
  491         int numops, taglen = -1, error = 0, igotlock;
  492         u_int32_t minorvers, retops = 0, *retopsp = NULL, *repp;
  493         u_char tag[NFSV4_SMALLSTR + 1], *tagstr;
  494         vnode_t vp, nvp, savevp;
  495         struct nfsrvfh fh;
  496         mount_t new_mp, temp_mp = NULL;
  497         struct ucred *credanon;
  498         struct nfsexstuff nes, vpnes, savevpnes;
  499         fsid_t cur_fsid, save_fsid;
  500         static u_int64_t compref = 0;
  501 
  502         NFSVNO_EXINIT(&vpnes);
  503         NFSVNO_EXINIT(&savevpnes);
  504         /*
  505          * Put the seq# of the current compound RPC in nfsrv_descript.
  506          * (This is used by nfsrv_checkgetattr(), to see if the write
  507          *  delegation was created by the same compound RPC as the one
  508          *  with that Getattr in it.)
  509          * Don't worry about the 64bit number wrapping around. It ain't
  510          * gonna happen before this server gets shut down/rebooted.
  511          */
  512         nd->nd_compref = compref++;
  513 
  514         /*
  515          * Check for and optionally get a lock on the root. This lock means that
  516          * no nfsd will be fiddling with the V4 file system and state stuff. It
  517          * is required when the V4 root is being changed, the stable storage
  518          * restart file is being updated, or callbacks are being done.
  519          * When any of the nfsd are processing an NFSv4 compound RPC, they must
  520          * either hold a reference count (nfs_usecnt) or the lock. When
  521          * nfsrv_unlock() is called to release the lock, it can optionally
  522          * also get a reference count, which saves the need for a call to
  523          * nfsrv_getref() after nfsrv_unlock().
  524          */
  525         /*
  526          * First, check to see if we need to wait for an update lock.
  527          */
  528         igotlock = 0;
  529         NFSLOCKV4ROOTMUTEX();
  530         if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK)
  531                 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
  532                     NFSV4ROOTLOCKMUTEXPTR, NULL);
  533         else
  534                 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL,
  535                     NFSV4ROOTLOCKMUTEXPTR, NULL);
  536         NFSUNLOCKV4ROOTMUTEX();
  537         if (igotlock) {
  538                 /*
  539                  * If I got the lock, I can update the stable storage file.
  540                  * Done when the grace period is over or a client has long
  541                  * since expired.
  542                  */
  543                 nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NEEDLOCK;
  544                 if ((nfsrv_stablefirst.nsf_flags &
  545                     (NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER)
  546                         nfsrv_updatestable(p);
  547 
  548                 /*
  549                  * If at least one client has long since expired, search
  550                  * the client list for them, write a REVOKE record on the
  551                  * stable storage file and then remove them from the client
  552                  * list.
  553                  */
  554                 if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) {
  555                         nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT;
  556                         for (i = 0; i < NFSCLIENTHASHSIZE; i++) {
  557                             LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash,
  558                                 nclp) {
  559                                 if (clp->lc_flags & LCL_EXPIREIT) {
  560                                     if (!LIST_EMPTY(&clp->lc_open) ||
  561                                         !LIST_EMPTY(&clp->lc_deleg))
  562                                         nfsrv_writestable(clp->lc_id,
  563                                             clp->lc_idlen, NFSNST_REVOKE, p);
  564                                     nfsrv_cleanclient(clp, p);
  565                                     nfsrv_freedeleglist(&clp->lc_deleg);
  566                                     nfsrv_freedeleglist(&clp->lc_olddeleg);
  567                                     LIST_REMOVE(clp, lc_hash);
  568                                     nfsrv_zapclient(clp, p);
  569                                 }
  570                             }
  571                         }
  572                 }
  573                 NFSLOCKV4ROOTMUTEX();
  574                 nfsv4_unlock(&nfsv4rootfs_lock, 1);
  575                 NFSUNLOCKV4ROOTMUTEX();
  576         } else {
  577                 /*
  578                  * If we didn't get the lock, we need to get a refcnt,
  579                  * which also checks for and waits for the lock.
  580                  */
  581                 NFSLOCKV4ROOTMUTEX();
  582                 nfsv4_getref(&nfsv4rootfs_lock, NULL,
  583                     NFSV4ROOTLOCKMUTEXPTR, NULL);
  584                 NFSUNLOCKV4ROOTMUTEX();
  585         }
  586 
  587         /*
  588          * If flagged, search for open owners that haven't had any opens
  589          * for a long time.
  590          */
  591         if (nfsrv_stablefirst.nsf_flags & NFSNSF_NOOPENS) {
  592                 nfsrv_throwawayopens(p);
  593         }
  594 
  595         savevp = vp = NULL;
  596         save_fsid.val[0] = save_fsid.val[1] = 0;
  597         cur_fsid.val[0] = cur_fsid.val[1] = 0;
  598         NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  599         taglen = fxdr_unsigned(int, *tl);
  600         if (taglen < 0) {
  601                 error = EBADRPC;
  602                 goto nfsmout;
  603         }
  604         if (taglen <= NFSV4_SMALLSTR)
  605                 tagstr = tag;
  606         else
  607                 tagstr = malloc(taglen + 1, M_TEMP, M_WAITOK);
  608         error = nfsrv_mtostr(nd, tagstr, taglen);
  609         if (error) {
  610                 if (taglen > NFSV4_SMALLSTR)
  611                         free(tagstr, M_TEMP);
  612                 taglen = -1;
  613                 goto nfsmout;
  614         }
  615         (void) nfsm_strtom(nd, tag, taglen);
  616         if (taglen > NFSV4_SMALLSTR) {
  617                 free(tagstr, M_TEMP);
  618         }
  619         NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED);
  620         NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  621         minorvers = fxdr_unsigned(u_int32_t, *tl++);
  622         if (minorvers != NFSV4_MINORVERSION)
  623                 nd->nd_repstat = NFSERR_MINORVERMISMATCH;
  624         if (nd->nd_repstat)
  625                 numops = 0;
  626         else
  627                 numops = fxdr_unsigned(int, *tl);
  628         /*
  629          * Loop around doing the sub ops.
  630          * vp - is an unlocked vnode pointer for the CFH
  631          * savevp - is an unlocked vnode pointer for the SAVEDFH
  632          * (at some future date, it might turn out to be more appropriate
  633          *  to keep the file handles instead of vnode pointers?)
  634          * savevpnes and vpnes - are the export flags for the above.
  635          */
  636         for (i = 0; i < numops; i++) {
  637                 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  638                 NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED);
  639                 *repp = *tl;
  640                 op = fxdr_unsigned(int, *tl);
  641                 if (op < NFSV4OP_ACCESS || op >= NFSV4OP_NOPS) {
  642                         nd->nd_repstat = NFSERR_OPILLEGAL;
  643                         *repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL);
  644                         *repp = nfsd_errmap(nd);
  645                         retops++;
  646                         break;
  647                 } else {
  648                         repp++;
  649                 }
  650 
  651                 /*
  652                  * Check for a referral on the current FH and, if so, return
  653                  * NFSERR_MOVED for all ops that allow it, except Getattr.
  654                  */
  655                 if (vp != NULL && op != NFSV4OP_GETATTR &&
  656                     nfsv4root_getreferral(vp, NULL, 0) != NULL &&
  657                     nfsrv_errmoved(op)) {
  658                         nd->nd_repstat = NFSERR_MOVED;
  659                         *repp = nfsd_errmap(nd);
  660                         retops++;
  661                         break;
  662                 }
  663 
  664                 nd->nd_procnum = op;
  665                 /*
  666                  * If over flood level, reply NFSERR_RESOURCE, if at the first
  667                  * Op. (Since a client recovery from NFSERR_RESOURCE can get
  668                  * really nasty for certain Op sequences, I'll play it safe
  669                  * and only return the error at the beginning.) The cache
  670                  * will still function over flood level, but uses lots of
  671                  * mbufs.)
  672                  * If nfsrv_mallocmget_limit() returns True, the system is near
  673                  * to its limit for memory that malloc()/mget() can allocate.
  674                  */
  675                 if (i == 0 && nd->nd_rp->rc_refcnt == 0 &&
  676                     (nfsrv_mallocmget_limit() ||
  677                      nfsrc_tcpsavedreplies > nfsrc_floodlevel)) {
  678                         if (nfsrc_tcpsavedreplies > nfsrc_floodlevel)
  679                                 printf("nfsd server cache flooded, try "
  680                                     "increasing vfs.nfsd.tcphighwater\n");
  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: 4e409b41566be72e4aa889dc283206d7


[ 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.