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/10.4/sys/fs/nfsserver/nfs_nfsdsocket.c 306663 2016-10-03 23:17:57Z rmacklem $");
   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;
   50 extern int nfsrv_clienthashsize;
   51 extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies;
   52 extern int nfsd_debuglevel;
   53 NFSV4ROOTLOCKMUTEX;
   54 NFSSTATESPINLOCK;
   55 
   56 int (*nfsrv3_procs0[NFS_V3NPROCS])(struct nfsrv_descript *,
   57     int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
   58         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
   59         nfsrvd_getattr,
   60         nfsrvd_setattr,
   61         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
   62         nfsrvd_access,
   63         nfsrvd_readlink,
   64         nfsrvd_read,
   65         nfsrvd_write,
   66         nfsrvd_create,
   67         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
   68         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
   69         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
   70         nfsrvd_remove,
   71         nfsrvd_remove,
   72         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
   73         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
   74         nfsrvd_readdir,
   75         nfsrvd_readdirplus,
   76         nfsrvd_statfs,
   77         nfsrvd_fsinfo,
   78         nfsrvd_pathconf,
   79         nfsrvd_commit,
   80 };
   81 
   82 int (*nfsrv3_procs1[NFS_V3NPROCS])(struct nfsrv_descript *,
   83     int, vnode_t , vnode_t *, fhandle_t *,
   84     NFSPROC_T *, struct nfsexstuff *) = {
   85         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
   86         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
   87         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
   88         nfsrvd_lookup,
   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         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
   93         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
   94         nfsrvd_mkdir,
   95         nfsrvd_symlink,
   96         nfsrvd_mknod,
   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         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  106         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  107 };
  108 
  109 int (*nfsrv3_procs2[NFS_V3NPROCS])(struct nfsrv_descript *,
  110     int, vnode_t , vnode_t , NFSPROC_T *,
  111     struct nfsexstuff *, struct nfsexstuff *) = {
  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         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  125         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  126         nfsrvd_rename,
  127         nfsrvd_link,
  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         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  133         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  134 };
  135 
  136 int (*nfsrv4_ops0[NFSV41_NOPS])(struct nfsrv_descript *,
  137     int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
  138         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  139         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  140         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  141         nfsrvd_access,
  142         nfsrvd_close,
  143         nfsrvd_commit,
  144         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  145         nfsrvd_delegpurge,
  146         nfsrvd_delegreturn,
  147         nfsrvd_getattr,
  148         nfsrvd_getfh,
  149         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  150         nfsrvd_lock,
  151         nfsrvd_lockt,
  152         nfsrvd_locku,
  153         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  154         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  155         nfsrvd_verify,
  156         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  157         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  158         nfsrvd_openconfirm,
  159         nfsrvd_opendowngrade,
  160         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  161         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  162         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  163         nfsrvd_read,
  164         nfsrvd_readdirplus,
  165         nfsrvd_readlink,
  166         nfsrvd_remove,
  167         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  168         nfsrvd_renew,
  169         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  170         (int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
  171         nfsrvd_secinfo,
  172         nfsrvd_setattr,
  173         nfsrvd_setclientid,
  174         nfsrvd_setclientidcfrm,
  175         nfsrvd_verify,
  176         nfsrvd_write,
  177         nfsrvd_releaselckown,
  178         nfsrvd_notsupp,
  179         nfsrvd_notsupp,
  180         nfsrvd_exchangeid,
  181         nfsrvd_createsession,
  182         nfsrvd_destroysession,
  183         nfsrvd_freestateid,
  184         nfsrvd_notsupp,
  185         nfsrvd_notsupp,
  186         nfsrvd_notsupp,
  187         nfsrvd_notsupp,
  188         nfsrvd_notsupp,
  189         nfsrvd_notsupp,
  190         nfsrvd_notsupp,
  191         nfsrvd_sequence,
  192         nfsrvd_notsupp,
  193         nfsrvd_notsupp,
  194         nfsrvd_notsupp,
  195         nfsrvd_destroyclientid,
  196         nfsrvd_reclaimcomplete,
  197 };
  198 
  199 int (*nfsrv4_ops1[NFSV41_NOPS])(struct nfsrv_descript *,
  200     int, vnode_t , vnode_t *, fhandle_t *,
  201     NFSPROC_T *, struct nfsexstuff *) = {
  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         nfsrvd_mknod,
  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         nfsrvd_lookup,
  218         nfsrvd_lookup,
  219         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  220         nfsrvd_open,
  221         nfsrvd_openattr,
  222         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  223         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  224         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  225         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  226         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  227         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  228         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  229         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  230         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  231         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  232         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  233         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  234         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  235         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  236         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  237         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  238         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  239         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  240         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  241         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  242         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  243         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  244         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  245         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  246         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  247         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  248         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  249         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  250         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  251         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  252         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  253         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  254         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  255         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  256         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  257         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  258         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  259         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  260         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
  261 };
  262 
  263 int (*nfsrv4_ops2[NFSV41_NOPS])(struct nfsrv_descript *,
  264     int, vnode_t , vnode_t , NFSPROC_T *,
  265     struct nfsexstuff *, struct nfsexstuff *) = {
  266         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  267         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  268         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  269         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  270         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  271         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  272         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  273         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  274         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  275         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  276         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  277         nfsrvd_link,
  278         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  279         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  280         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  281         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  282         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  283         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  284         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  285         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  286         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  287         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  288         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  289         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  290         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  291         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  292         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  293         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  294         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  295         nfsrvd_rename,
  296         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  297         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  298         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  299         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  300         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  301         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  302         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  303         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  304         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  305         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  306         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  307         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  308         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  309         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  310         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  311         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  312         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  313         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  314         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  315         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  316         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  317         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  318         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  319         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  320         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  321         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  322         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  323         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  324         (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
  325 };
  326 #endif  /* !APPLEKEXT */
  327 
  328 /*
  329  * Static array that defines which nfs rpc's are nonidempotent
  330  */
  331 static int nfsrv_nonidempotent[NFS_V3NPROCS] = {
  332         FALSE,
  333         FALSE,
  334         TRUE,
  335         FALSE,
  336         FALSE,
  337         FALSE,
  338         FALSE,
  339         TRUE,
  340         TRUE,
  341         TRUE,
  342         TRUE,
  343         TRUE,
  344         TRUE,
  345         TRUE,
  346         TRUE,
  347         TRUE,
  348         FALSE,
  349         FALSE,
  350         FALSE,
  351         FALSE,
  352         FALSE,
  353         FALSE,
  354 };
  355 
  356 /*
  357  * This static array indicates whether or not the RPC modifies the
  358  * file system.
  359  */
  360 static int nfs_writerpc[NFS_NPROCS] = { 0, 0, 1, 0, 0, 0, 0,
  361     1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
  362     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
  363 
  364 /* local functions */
  365 static void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
  366     u_char *tag, int taglen, u_int32_t minorvers, NFSPROC_T *p);
  367 
  368 
  369 /*
  370  * This static array indicates which server procedures require the extra
  371  * arguments to return the current file handle for V2, 3.
  372  */
  373 static int nfs_retfh[NFS_V3NPROCS] = { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
  374         1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 };
  375 
  376 extern struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS];
  377 
  378 static int nfsv3to4op[NFS_V3NPROCS] = {
  379         NFSPROC_NULL,
  380         NFSV4OP_GETATTR,
  381         NFSV4OP_SETATTR,
  382         NFSV4OP_LOOKUP,
  383         NFSV4OP_ACCESS,
  384         NFSV4OP_READLINK,
  385         NFSV4OP_READ,
  386         NFSV4OP_WRITE,
  387         NFSV4OP_V3CREATE,
  388         NFSV4OP_MKDIR,
  389         NFSV4OP_SYMLINK,
  390         NFSV4OP_MKNOD,
  391         NFSV4OP_REMOVE,
  392         NFSV4OP_RMDIR,
  393         NFSV4OP_RENAME,
  394         NFSV4OP_LINK,
  395         NFSV4OP_READDIR,
  396         NFSV4OP_READDIRPLUS,
  397         NFSV4OP_FSSTAT,
  398         NFSV4OP_FSINFO,
  399         NFSV4OP_PATHCONF,
  400         NFSV4OP_COMMIT,
  401 };
  402 
  403 /*
  404  * Do an RPC. Basically, get the file handles translated to vnode pointers
  405  * and then call the appropriate server routine. The server routines are
  406  * split into groups, based on whether they use a file handle or file
  407  * handle plus name or ...
  408  * The NFS V4 Compound RPC is performed separately by nfsrvd_compound().
  409  */
  410 APPLESTATIC void
  411 nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen,
  412     u_int32_t minorvers, NFSPROC_T *p)
  413 {
  414         int error = 0, lktype;
  415         vnode_t vp;
  416         mount_t mp = NULL;
  417         struct nfsrvfh fh;
  418         struct nfsexstuff nes;
  419 
  420         /*
  421          * Get a locked vnode for the first file handle
  422          */
  423         if (!(nd->nd_flag & ND_NFSV4)) {
  424                 KASSERT(nd->nd_repstat == 0, ("nfsrvd_dorpc"));
  425                 /*
  426                  * For NFSv3, if the malloc/mget allocation is near limits,
  427                  * return NFSERR_DELAY.
  428                  */
  429                 if ((nd->nd_flag & ND_NFSV3) && nfsrv_mallocmget_limit()) {
  430                         nd->nd_repstat = NFSERR_DELAY;
  431                         vp = NULL;
  432                 } else {
  433                         error = nfsrv_mtofh(nd, &fh);
  434                         if (error) {
  435                                 if (error != EBADRPC)
  436                                         printf("nfs dorpc err1=%d\n", error);
  437                                 nd->nd_repstat = NFSERR_GARBAGE;
  438                                 goto out;
  439                         }
  440                         if (nd->nd_procnum == NFSPROC_READ ||
  441                             nd->nd_procnum == NFSPROC_WRITE ||
  442                             nd->nd_procnum == NFSPROC_READDIR ||
  443                             nd->nd_procnum == NFSPROC_READDIRPLUS ||
  444                             nd->nd_procnum == NFSPROC_READLINK ||
  445                             nd->nd_procnum == NFSPROC_GETATTR ||
  446                             nd->nd_procnum == NFSPROC_ACCESS ||
  447                             nd->nd_procnum == NFSPROC_FSSTAT ||
  448                             nd->nd_procnum == NFSPROC_FSINFO)
  449                                 lktype = LK_SHARED;
  450                         else
  451                                 lktype = LK_EXCLUSIVE;
  452                         if (nd->nd_flag & ND_PUBLOOKUP)
  453                                 nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes,
  454                                     &mp, nfs_writerpc[nd->nd_procnum], p);
  455                         else
  456                                 nfsd_fhtovp(nd, &fh, lktype, &vp, &nes,
  457                                     &mp, nfs_writerpc[nd->nd_procnum], p);
  458                         if (nd->nd_repstat == NFSERR_PROGNOTV4)
  459                                 goto out;
  460                 }
  461         }
  462 
  463         /*
  464          * For V2 and 3, set the ND_SAVEREPLY flag for the recent request
  465          * cache, as required.
  466          * For V4, nfsrvd_compound() does this.
  467          */
  468         if (!(nd->nd_flag & ND_NFSV4) && nfsrv_nonidempotent[nd->nd_procnum])
  469                 nd->nd_flag |= ND_SAVEREPLY;
  470 
  471         nfsrvd_rephead(nd);
  472         /*
  473          * If nd_repstat is non-zero, just fill in the reply status
  474          * to complete the RPC reply for V2. Otherwise, you must do
  475          * the RPC.
  476          */
  477         if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) {
  478                 *nd->nd_errp = nfsd_errmap(nd);
  479                 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
  480                 if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
  481                         vn_finished_write(mp);
  482                 goto out;
  483         }
  484 
  485         /*
  486          * Now the procedure can be performed. For V4, nfsrvd_compound()
  487          * works through the sub-rpcs, otherwise just call the procedure.
  488          * The procedures are in three groups with different arguments.
  489          * The group is indicated by the value in nfs_retfh[].
  490          */
  491         if (nd->nd_flag & ND_NFSV4) {
  492                 nfsrvd_compound(nd, isdgram, tag, taglen, minorvers, p);
  493         } else {
  494                 if (nfs_retfh[nd->nd_procnum] == 1) {
  495                         if (vp)
  496                                 NFSVOPUNLOCK(vp, 0);
  497                         error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram,
  498                             vp, NULL, (fhandle_t *)fh.nfsrvfh_data, p, &nes);
  499                 } else if (nfs_retfh[nd->nd_procnum] == 2) {
  500                         error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram,
  501                             vp, NULL, p, &nes, NULL);
  502                 } else {
  503                         error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram,
  504                             vp, p, &nes);
  505                 }
  506                 if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
  507                         vn_finished_write(mp);
  508                 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
  509         }
  510         if (error) {
  511                 if (error != EBADRPC)
  512                         printf("nfs dorpc err2=%d\n", error);
  513                 nd->nd_repstat = NFSERR_GARBAGE;
  514         }
  515         *nd->nd_errp = nfsd_errmap(nd);
  516 
  517         /*
  518          * Don't cache certain reply status values.
  519          */
  520         if (nd->nd_repstat && (nd->nd_flag & ND_SAVEREPLY) &&
  521             (nd->nd_repstat == NFSERR_GARBAGE ||
  522              nd->nd_repstat == NFSERR_BADXDR ||
  523              nd->nd_repstat == NFSERR_MOVED ||
  524              nd->nd_repstat == NFSERR_DELAY ||
  525              nd->nd_repstat == NFSERR_BADSEQID ||
  526              nd->nd_repstat == NFSERR_RESOURCE ||
  527              nd->nd_repstat == NFSERR_SERVERFAULT ||
  528              nd->nd_repstat == NFSERR_STALECLIENTID ||
  529              nd->nd_repstat == NFSERR_STALESTATEID ||
  530              nd->nd_repstat == NFSERR_OLDSTATEID ||
  531              nd->nd_repstat == NFSERR_BADSTATEID ||
  532              nd->nd_repstat == NFSERR_GRACE ||
  533              nd->nd_repstat == NFSERR_NOGRACE))
  534                 nd->nd_flag &= ~ND_SAVEREPLY;
  535 
  536 out:
  537         NFSEXITCODE2(0, nd);
  538 }
  539 
  540 /*
  541  * Breaks down a compound RPC request and calls the server routines for
  542  * the subprocedures.
  543  * Some suboperations are performed directly here to simplify file handle<-->
  544  * vnode pointer handling.
  545  */
  546 static void
  547 nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
  548     int taglen, u_int32_t minorvers, NFSPROC_T *p)
  549 {
  550         int i, lktype, op, op0 = 0;
  551         u_int32_t *tl;
  552         struct nfsclient *clp, *nclp;
  553         int numops, error = 0, igotlock;
  554         u_int32_t retops = 0, *retopsp = NULL, *repp;
  555         vnode_t vp, nvp, savevp;
  556         struct nfsrvfh fh;
  557         mount_t new_mp, temp_mp = NULL;
  558         struct ucred *credanon;
  559         struct nfsexstuff nes, vpnes, savevpnes;
  560         fsid_t cur_fsid, save_fsid;
  561         static u_int64_t compref = 0;
  562 
  563         NFSVNO_EXINIT(&vpnes);
  564         NFSVNO_EXINIT(&savevpnes);
  565         /*
  566          * Put the seq# of the current compound RPC in nfsrv_descript.
  567          * (This is used by nfsrv_checkgetattr(), to see if the write
  568          *  delegation was created by the same compound RPC as the one
  569          *  with that Getattr in it.)
  570          * Don't worry about the 64bit number wrapping around. It ain't
  571          * gonna happen before this server gets shut down/rebooted.
  572          */
  573         nd->nd_compref = compref++;
  574 
  575         /*
  576          * Check for and optionally get a lock on the root. This lock means that
  577          * no nfsd will be fiddling with the V4 file system and state stuff. It
  578          * is required when the V4 root is being changed, the stable storage
  579          * restart file is being updated, or callbacks are being done.
  580          * When any of the nfsd are processing an NFSv4 compound RPC, they must
  581          * either hold a reference count (nfs_usecnt) or the lock. When
  582          * nfsrv_unlock() is called to release the lock, it can optionally
  583          * also get a reference count, which saves the need for a call to
  584          * nfsrv_getref() after nfsrv_unlock().
  585          */
  586         /*
  587          * First, check to see if we need to wait for an update lock.
  588          */
  589         igotlock = 0;
  590         NFSLOCKV4ROOTMUTEX();
  591         if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK)
  592                 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
  593                     NFSV4ROOTLOCKMUTEXPTR, NULL);
  594         else
  595                 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL,
  596                     NFSV4ROOTLOCKMUTEXPTR, NULL);
  597         NFSUNLOCKV4ROOTMUTEX();
  598         if (igotlock) {
  599                 /*
  600                  * If I got the lock, I can update the stable storage file.
  601                  * Done when the grace period is over or a client has long
  602                  * since expired.
  603                  */
  604                 nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NEEDLOCK;
  605                 if ((nfsrv_stablefirst.nsf_flags &
  606                     (NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER)
  607                         nfsrv_updatestable(p);
  608 
  609                 /*
  610                  * If at least one client has long since expired, search
  611                  * the client list for them, write a REVOKE record on the
  612                  * stable storage file and then remove them from the client
  613                  * list.
  614                  */
  615                 if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) {
  616                         nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT;
  617                         for (i = 0; i < nfsrv_clienthashsize; i++) {
  618                             LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash,
  619                                 nclp) {
  620                                 if (clp->lc_flags & LCL_EXPIREIT) {
  621                                     if (!LIST_EMPTY(&clp->lc_open) ||
  622                                         !LIST_EMPTY(&clp->lc_deleg))
  623                                         nfsrv_writestable(clp->lc_id,
  624                                             clp->lc_idlen, NFSNST_REVOKE, p);
  625                                     nfsrv_cleanclient(clp, p);
  626                                     nfsrv_freedeleglist(&clp->lc_deleg);
  627                                     nfsrv_freedeleglist(&clp->lc_olddeleg);
  628                                     LIST_REMOVE(clp, lc_hash);
  629                                     nfsrv_zapclient(clp, p);
  630                                 }
  631                             }
  632                         }
  633                 }
  634                 NFSLOCKV4ROOTMUTEX();
  635                 nfsv4_unlock(&nfsv4rootfs_lock, 1);
  636                 NFSUNLOCKV4ROOTMUTEX();
  637         } else {
  638                 /*
  639                  * If we didn't get the lock, we need to get a refcnt,
  640                  * which also checks for and waits for the lock.
  641                  */
  642                 NFSLOCKV4ROOTMUTEX();
  643                 nfsv4_getref(&nfsv4rootfs_lock, NULL,
  644                     NFSV4ROOTLOCKMUTEXPTR, NULL);
  645                 NFSUNLOCKV4ROOTMUTEX();
  646         }
  647 
  648         /*
  649          * If flagged, search for open owners that haven't had any opens
  650          * for a long time.
  651          */
  652         if (nfsrv_stablefirst.nsf_flags & NFSNSF_NOOPENS) {
  653                 nfsrv_throwawayopens(p);
  654         }
  655 
  656         savevp = vp = NULL;
  657         save_fsid.val[0] = save_fsid.val[1] = 0;
  658         cur_fsid.val[0] = cur_fsid.val[1] = 0;
  659 
  660         /* If taglen < 0, there was a parsing error in nfsd_getminorvers(). */
  661         if (taglen < 0) {
  662                 error = EBADRPC;
  663                 goto nfsmout;
  664         }
  665 
  666         (void) nfsm_strtom(nd, tag, taglen);
  667         NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED);
  668         NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  669         if (minorvers != NFSV4_MINORVERSION && minorvers != NFSV41_MINORVERSION)
  670                 nd->nd_repstat = NFSERR_MINORVERMISMATCH;
  671         if (nd->nd_repstat)
  672                 numops = 0;
  673         else
  674                 numops = fxdr_unsigned(int, *tl);
  675         /*
  676          * Loop around doing the sub ops.
  677          * vp - is an unlocked vnode pointer for the CFH
  678          * savevp - is an unlocked vnode pointer for the SAVEDFH
  679          * (at some future date, it might turn out to be more appropriate
  680          *  to keep the file handles instead of vnode pointers?)
  681          * savevpnes and vpnes - are the export flags for the above.
  682          */
  683         for (i = 0; i < numops; i++) {
  684                 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
  685                 NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED);
  686                 *repp = *tl;
  687                 op = fxdr_unsigned(int, *tl);
  688                 NFSD_DEBUG(4, "op=%d\n", op);
  689                 if (op < NFSV4OP_ACCESS ||
  690                     (op >= NFSV4OP_NOPS && (nd->nd_flag & ND_NFSV41) == 0) ||
  691                     (op >= NFSV41_NOPS && (nd->nd_flag & ND_NFSV41) != 0)) {
  692                         nd->nd_repstat = NFSERR_OPILLEGAL;
  693                         *repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL);
  694                         *repp = nfsd_errmap(nd);
  695                         retops++;
  696                         break;
  697                 } else {
  698                         repp++;
  699                 }
  700                 if (i == 0)
  701                         op0 = op;
  702                 if (i == numops - 1)
  703                         nd->nd_flag |= ND_LASTOP;
  704 
  705                 /*
  706                  * Check for a referral on the current FH and, if so, return
  707                  * NFSERR_MOVED for all ops that allow it, except Getattr.
  708                  */
  709                 if (vp != NULL && op != NFSV4OP_GETATTR &&
  710                     nfsv4root_getreferral(vp, NULL, 0) != NULL &&
  711                     nfsrv_errmoved(op)) {
  712                         nd->nd_repstat = NFSERR_MOVED;
  713                         *repp = nfsd_errmap(nd);
  714                         retops++;
  715                         break;
  716                 }
  717 
  718                 /*
  719                  * For NFSv4.1, check for a Sequence Operation being first
  720                  * or one of the other allowed operations by itself.
  721                  */
  722                 if ((nd->nd_flag & ND_NFSV41) != 0) {
  723                         if (i != 0 && op == NFSV4OP_SEQUENCE)
  724                                 nd->nd_repstat = NFSERR_SEQUENCEPOS;
  725                         else if (i == 0 && op != NFSV4OP_SEQUENCE &&
  726                             op != NFSV4OP_EXCHANGEID &&
  727                             op != NFSV4OP_CREATESESSION &&
  728                             op != NFSV4OP_BINDCONNTOSESS &&
  729                             op != NFSV4OP_DESTROYCLIENTID &&
  730                             op != NFSV4OP_DESTROYSESSION)
  731                                 nd->nd_repstat = NFSERR_OPNOTINSESS;
  732                         else if (i != 0 && op0 != NFSV4OP_SEQUENCE)
  733                                 nd->nd_repstat = NFSERR_NOTONLYOP;
  734                         if (nd->nd_repstat != 0) {
  735                                 *repp = nfsd_errmap(nd);
  736                                 retops++;
  737                                 break;
  738                         }
  739                 }
  740 
  741                 nd->nd_procnum = op;
  742                 /*
  743                  * If over flood level, reply NFSERR_RESOURCE, if at the first
  744                  * Op. (Since a client recovery from NFSERR_RESOURCE can get
  745                  * really nasty for certain Op sequences, I'll play it safe
  746                  * and only return the error at the beginning.) The cache
  747                  * will still function over flood level, but uses lots of
  748                  * mbufs.)
  749                  * If nfsrv_mallocmget_limit() returns True, the system is near
  750                  * to its limit for memory that malloc()/mget() can allocate.
  751                  */
  752                 if (i == 0 && (nd->nd_rp == NULL ||
  753                     nd->nd_rp->rc_refcnt == 0) &&
  754                     (nfsrv_mallocmget_limit() ||
  755                      nfsrc_tcpsavedreplies > nfsrc_floodlevel)) {
  756                         if (nfsrc_tcpsavedreplies > nfsrc_floodlevel)
  757                                 printf("nfsd server cache flooded, try "
  758                                     "increasing vfs.nfsd.tcphighwater\n");
  759                         nd->nd_repstat = NFSERR_RESOURCE;
  760                         *repp = nfsd_errmap(nd);
  761                         if (op == NFSV4OP_SETATTR) {
  762                                 /*
  763                                  * Setattr replies require a bitmap.
  764                                  * even for errors like these.
  765                                  */
  766                                 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  767                                 *tl = 0;
  768                         }
  769                         retops++;
  770                         break;
  771                 }
  772                 if (nfsv4_opflag[op].savereply)
  773                         nd->nd_flag |= ND_SAVEREPLY;
  774                 /*
  775                  * For now, newnfsstats.srvrpccnt[] doesn't have entries
  776                  * for the NFSv4.1 operations.
  777                  */
  778                 if (nd->nd_procnum < NFSV4OP_NOPS)
  779                         NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]);
  780                 switch (op) {
  781                 case NFSV4OP_PUTFH:
  782                         error = nfsrv_mtofh(nd, &fh);
  783                         if (error)
  784                                 goto nfsmout;
  785                         if (!nd->nd_repstat)
  786                                 nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes,
  787                                     NULL, 0, p);
  788                         /* For now, allow this for non-export FHs */
  789                         if (!nd->nd_repstat) {
  790                                 if (vp)
  791                                         vrele(vp);
  792                                 vp = nvp;
  793                                 cur_fsid = vp->v_mount->mnt_stat.f_fsid;
  794                                 NFSVOPUNLOCK(vp, 0);
  795                                 vpnes = nes;
  796                         }
  797                         break;
  798                 case NFSV4OP_PUTPUBFH:
  799                         if (nfs_pubfhset)
  800                             nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp,
  801                                 &nes, NULL, 0, p);
  802                         else
  803                             nd->nd_repstat = NFSERR_NOFILEHANDLE;
  804                         if (!nd->nd_repstat) {
  805                                 if (vp)
  806                                         vrele(vp);
  807                                 vp = nvp;
  808                                 cur_fsid = vp->v_mount->mnt_stat.f_fsid;
  809                                 NFSVOPUNLOCK(vp, 0);
  810                                 vpnes = nes;
  811                         }
  812                         break;
  813                 case NFSV4OP_PUTROOTFH:
  814                         if (nfs_rootfhset) {
  815                                 nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp,
  816                                     &nes, NULL, 0, p);
  817                                 if (!nd->nd_repstat) {
  818                                         if (vp)
  819                                                 vrele(vp);
  820                                         vp = nvp;
  821                                         cur_fsid = vp->v_mount->mnt_stat.f_fsid;
  822                                         NFSVOPUNLOCK(vp, 0);
  823                                         vpnes = nes;
  824                                 }
  825                         } else
  826                                 nd->nd_repstat = NFSERR_NOFILEHANDLE;
  827                         break;
  828                 case NFSV4OP_SAVEFH:
  829                         if (vp && NFSVNO_EXPORTED(&vpnes)) {
  830                                 nd->nd_repstat = 0;
  831                                 /* If vp == savevp, a no-op */
  832                                 if (vp != savevp) {
  833                                         if (savevp)
  834                                                 vrele(savevp);
  835                                         VREF(vp);
  836                                         savevp = vp;
  837                                         savevpnes = vpnes;
  838                                         save_fsid = cur_fsid;
  839                                 }
  840                         } else {
  841                                 nd->nd_repstat = NFSERR_NOFILEHANDLE;
  842                         }
  843                         break;
  844                 case NFSV4OP_RESTOREFH:
  845                         if (savevp) {
  846                                 nd->nd_repstat = 0;
  847                                 /* If vp == savevp, a no-op */
  848                                 if (vp != savevp) {
  849                                         VREF(savevp);
  850                                         vrele(vp);
  851                                         vp = savevp;
  852                                         vpnes = savevpnes;
  853                                         cur_fsid = save_fsid;
  854                                 }
  855                         } else {
  856                                 nd->nd_repstat = NFSERR_RESTOREFH;
  857                         }
  858                         break;
  859                 default:
  860                     /*
  861                      * Allow a Lookup, Getattr, GetFH, Secinfo on an
  862                      * non-exported directory if
  863                      * nfs_rootfhset. Do I need to allow any other Ops?
  864                      * (You can only have a non-exported vpnes if
  865                      *  nfs_rootfhset is true. See nfsd_fhtovp())
  866                      * Allow AUTH_SYS to be used for file systems
  867                      * exported GSS only for certain Ops, to allow
  868                      * clients to do mounts more easily.
  869                      */
  870                     if (nfsv4_opflag[op].needscfh && vp) {
  871                         if (!NFSVNO_EXPORTED(&vpnes) &&
  872                             op != NFSV4OP_LOOKUP &&
  873                             op != NFSV4OP_GETATTR &&
  874                             op != NFSV4OP_GETFH &&
  875                             op != NFSV4OP_ACCESS &&
  876                             op != NFSV4OP_READLINK &&
  877                             op != NFSV4OP_SECINFO)
  878                                 nd->nd_repstat = NFSERR_NOFILEHANDLE;
  879                         else if (nfsvno_testexp(nd, &vpnes) &&
  880                             op != NFSV4OP_LOOKUP &&
  881                             op != NFSV4OP_GETFH &&
  882                             op != NFSV4OP_GETATTR &&
  883                             op != NFSV4OP_SECINFO)
  884                                 nd->nd_repstat = NFSERR_WRONGSEC;
  885                         if (nd->nd_repstat) {
  886                                 if (op == NFSV4OP_SETATTR) {
  887                                     /*
  888                                      * Setattr reply requires a bitmap
  889                                      * even for errors like these.
  890                                      */
  891                                     NFSM_BUILD(tl, u_int32_t *,
  892                                         NFSX_UNSIGNED);
  893                                     *tl = 0;
  894                                 }
  895                                 break;
  896                         }
  897                     }
  898                     if (nfsv4_opflag[op].retfh == 1) {
  899                         if (!vp) {
  900                                 nd->nd_repstat = NFSERR_NOFILEHANDLE;
  901                                 break;
  902                         }
  903                         VREF(vp);
  904                         if (nfsv4_opflag[op].modifyfs)
  905                                 vn_start_write(vp, &temp_mp, V_WAIT);
  906                         error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp,
  907                             &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes);
  908                         if (!error && !nd->nd_repstat) {
  909                             if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) {
  910                                 new_mp = nvp->v_mount;
  911                                 if (cur_fsid.val[0] !=
  912                                     new_mp->mnt_stat.f_fsid.val[0] ||
  913                                     cur_fsid.val[1] !=
  914                                     new_mp->mnt_stat.f_fsid.val[1]) {
  915                                     /* crossed a server mount point */
  916                                     nd->nd_repstat = nfsvno_checkexp(new_mp,
  917                                         nd->nd_nam, &nes, &credanon);
  918                                     if (!nd->nd_repstat)
  919                                         nd->nd_repstat = nfsd_excred(nd,
  920                                             &nes, credanon);
  921                                     if (credanon != NULL)
  922                                         crfree(credanon);
  923                                     if (!nd->nd_repstat) {
  924                                         vpnes = nes;
  925                                         cur_fsid = new_mp->mnt_stat.f_fsid;
  926                                     }
  927                                 }
  928                                 /* Lookup ops return a locked vnode */
  929                                 NFSVOPUNLOCK(nvp, 0);
  930                             }
  931                             if (!nd->nd_repstat) {
  932                                     vrele(vp);
  933                                     vp = nvp;
  934                             } else
  935                                     vrele(nvp);
  936                         }
  937                         if (nfsv4_opflag[op].modifyfs)
  938                                 vn_finished_write(temp_mp);
  939                     } else if (nfsv4_opflag[op].retfh == 2) {
  940                         if (vp == NULL || savevp == NULL) {
  941                                 nd->nd_repstat = NFSERR_NOFILEHANDLE;
  942                                 break;
  943                         } else if (cur_fsid.val[0] != save_fsid.val[0] ||
  944                             cur_fsid.val[1] != save_fsid.val[1]) {
  945                                 nd->nd_repstat = NFSERR_XDEV;
  946                                 break;
  947                         }
  948                         if (nfsv4_opflag[op].modifyfs)
  949                                 vn_start_write(savevp, &temp_mp, V_WAIT);
  950                         if (NFSVOPLOCK(savevp, LK_EXCLUSIVE) == 0) {
  951                                 VREF(vp);
  952                                 VREF(savevp);
  953                                 error = (*(nfsrv4_ops2[op]))(nd, isdgram,
  954                                     savevp, vp, p, &savevpnes, &vpnes);
  955                         } else
  956                                 nd->nd_repstat = NFSERR_PERM;
  957                         if (nfsv4_opflag[op].modifyfs)
  958                                 vn_finished_write(temp_mp);
  959                     } else {
  960                         if (nfsv4_opflag[op].retfh != 0)
  961                                 panic("nfsrvd_compound");
  962                         if (nfsv4_opflag[op].needscfh) {
  963                                 if (vp != NULL) {
  964                                         lktype = nfsv4_opflag[op].lktype;
  965                                         if (nfsv4_opflag[op].modifyfs) {
  966                                                 vn_start_write(vp, &temp_mp,
  967                                                     V_WAIT);
  968                                                 if (op == NFSV4OP_WRITE &&
  969                                                     MNT_SHARED_WRITES(temp_mp))
  970                                                         lktype = LK_SHARED;
  971                                         }
  972                                         if (NFSVOPLOCK(vp, lktype) == 0)
  973                                                 VREF(vp);
  974                                         else
  975                                                 nd->nd_repstat = NFSERR_PERM;
  976                                 } else {
  977                                         nd->nd_repstat = NFSERR_NOFILEHANDLE;
  978                                         if (op == NFSV4OP_SETATTR) {
  979                                                 /*
  980                                                  * Setattr reply requires a
  981                                                  * bitmap even for errors like
  982                                                  * these.
  983                                                  */
  984                                                 NFSM_BUILD(tl, u_int32_t *,
  985                                                     NFSX_UNSIGNED);
  986                                                 *tl = 0;
  987                                         }
  988                                         break;
  989                                 }
  990                                 if (nd->nd_repstat == 0)
  991                                         error = (*(nfsrv4_ops0[op]))(nd,
  992                                             isdgram, vp, p, &vpnes);
  993                                 if (nfsv4_opflag[op].modifyfs)
  994                                         vn_finished_write(temp_mp);
  995                         } else {
  996                                 error = (*(nfsrv4_ops0[op]))(nd, isdgram,
  997                                     NULL, p, &vpnes);
  998                         }
  999                     }
 1000                 };
 1001                 if (error) {
 1002                         if (error == EBADRPC || error == NFSERR_BADXDR) {
 1003                                 nd->nd_repstat = NFSERR_BADXDR;
 1004                         } else {
 1005                                 nd->nd_repstat = error;
 1006                                 printf("nfsv4 comperr0=%d\n", error);
 1007                         }
 1008                         error = 0;
 1009                 }
 1010                 retops++;
 1011                 if (nd->nd_repstat) {
 1012                         *repp = nfsd_errmap(nd);
 1013                         break;
 1014                 } else {
 1015                         *repp = 0;      /* NFS4_OK */
 1016                 }
 1017         }
 1018 nfsmout:
 1019         if (error) {
 1020                 if (error == EBADRPC || error == NFSERR_BADXDR)
 1021                         nd->nd_repstat = NFSERR_BADXDR;
 1022                 else
 1023                         printf("nfsv4 comperr1=%d\n", error);
 1024         }
 1025         if (taglen == -1) {
 1026                 NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
 1027                 *tl++ = 0;
 1028                 *tl = 0;
 1029         } else {
 1030                 *retopsp = txdr_unsigned(retops);
 1031         }
 1032         if (vp)
 1033                 vrele(vp);
 1034         if (savevp)
 1035                 vrele(savevp);
 1036         NFSLOCKV4ROOTMUTEX();
 1037         nfsv4_relref(&nfsv4rootfs_lock);
 1038         NFSUNLOCKV4ROOTMUTEX();
 1039 
 1040         NFSEXITCODE2(0, nd);
 1041 }

Cache object: c6396f1c9e48737a834f5097775eb5be


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