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.0/sys/fs/nfsserver/nfs_nfsdsocket.c 249592 2013-04-17 21:00:22Z ken $");
   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 to");
  680                                 printf(" increase nfsrc_floodlevel\n");
  681                         }
  682                         nd->nd_repstat = NFSERR_RESOURCE;
  683                         *repp = nfsd_errmap(nd);
  684                         if (op == NFSV4OP_SETATTR) {
  685                                 /*
  686                                  * Setattr replies require a bitmap.
  687                                  * even for errors like these.
  688                                  */
  689                                 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
  690                                 *tl = 0;
  691                         }
  692                         retops++;
  693                         break;
  694                 }
  695                 if (nfsv4_opflag[op].savereply)
  696                         nd->nd_flag |= ND_SAVEREPLY;
  697                 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]);
  698                 switch (op) {
  699                 case NFSV4OP_PUTFH:
  700                         error = nfsrv_mtofh(nd, &fh);
  701                         if (error)
  702                                 goto nfsmout;
  703                         if (!nd->nd_repstat)
  704                                 nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes,
  705                                     NULL, 0, p);
  706                         /* For now, allow this for non-export FHs */
  707                         if (!nd->nd_repstat) {
  708                                 if (vp)
  709                                         vrele(vp);
  710                                 vp = nvp;
  711                                 cur_fsid = vp->v_mount->mnt_stat.f_fsid;
  712                                 NFSVOPUNLOCK(vp, 0);
  713                                 vpnes = nes;
  714                         }
  715                         break;
  716                 case NFSV4OP_PUTPUBFH:
  717                         if (nfs_pubfhset)
  718                             nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp,
  719                                 &nes, NULL, 0, p);
  720                         else
  721                             nd->nd_repstat = NFSERR_NOFILEHANDLE;
  722                         if (!nd->nd_repstat) {
  723                                 if (vp)
  724                                         vrele(vp);
  725                                 vp = nvp;
  726                                 cur_fsid = vp->v_mount->mnt_stat.f_fsid;
  727                                 NFSVOPUNLOCK(vp, 0);
  728                                 vpnes = nes;
  729                         }
  730                         break;
  731                 case NFSV4OP_PUTROOTFH:
  732                         if (nfs_rootfhset) {
  733                                 nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp,
  734                                     &nes, NULL, 0, p);
  735                                 if (!nd->nd_repstat) {
  736                                         if (vp)
  737                                                 vrele(vp);
  738                                         vp = nvp;
  739                                         cur_fsid = vp->v_mount->mnt_stat.f_fsid;
  740                                         NFSVOPUNLOCK(vp, 0);
  741                                         vpnes = nes;
  742                                 }
  743                         } else
  744                                 nd->nd_repstat = NFSERR_NOFILEHANDLE;
  745                         break;
  746                 case NFSV4OP_SAVEFH:
  747                         if (vp && NFSVNO_EXPORTED(&vpnes)) {
  748                                 nd->nd_repstat = 0;
  749                                 /* If vp == savevp, a no-op */
  750                                 if (vp != savevp) {
  751                                         if (savevp)
  752                                                 vrele(savevp);
  753                                         VREF(vp);
  754                                         savevp = vp;
  755                                         savevpnes = vpnes;
  756                                         save_fsid = cur_fsid;
  757                                 }
  758                         } else {
  759                                 nd->nd_repstat = NFSERR_NOFILEHANDLE;
  760                         }
  761                         break;
  762                 case NFSV4OP_RESTOREFH:
  763                         if (savevp) {
  764                                 nd->nd_repstat = 0;
  765                                 /* If vp == savevp, a no-op */
  766                                 if (vp != savevp) {
  767                                         VREF(savevp);
  768                                         vrele(vp);
  769                                         vp = savevp;
  770                                         vpnes = savevpnes;
  771                                         cur_fsid = save_fsid;
  772                                 }
  773                         } else {
  774                                 nd->nd_repstat = NFSERR_RESTOREFH;
  775                         }
  776                         break;
  777                 default:
  778                     /*
  779                      * Allow a Lookup, Getattr, GetFH, Secinfo on an
  780                      * non-exported directory if
  781                      * nfs_rootfhset. Do I need to allow any other Ops?
  782                      * (You can only have a non-exported vpnes if
  783                      *  nfs_rootfhset is true. See nfsd_fhtovp())
  784                      * Allow AUTH_SYS to be used for file systems
  785                      * exported GSS only for certain Ops, to allow
  786                      * clients to do mounts more easily.
  787                      */
  788                     if (nfsv4_opflag[op].needscfh && vp) {
  789                         if (!NFSVNO_EXPORTED(&vpnes) &&
  790                             op != NFSV4OP_LOOKUP &&
  791                             op != NFSV4OP_GETATTR &&
  792                             op != NFSV4OP_GETFH &&
  793                             op != NFSV4OP_ACCESS &&
  794                             op != NFSV4OP_READLINK &&
  795                             op != NFSV4OP_SECINFO)
  796                                 nd->nd_repstat = NFSERR_NOFILEHANDLE;
  797                         else if (nfsvno_testexp(nd, &vpnes) &&
  798                             op != NFSV4OP_LOOKUP &&
  799                             op != NFSV4OP_GETFH &&
  800                             op != NFSV4OP_GETATTR &&
  801                             op != NFSV4OP_SECINFO)
  802                                 nd->nd_repstat = NFSERR_WRONGSEC;
  803                         if (nd->nd_repstat) {
  804                                 if (op == NFSV4OP_SETATTR) {
  805                                     /*
  806                                      * Setattr reply requires a bitmap
  807                                      * even for errors like these.
  808                                      */
  809                                     NFSM_BUILD(tl, u_int32_t *,
  810                                         NFSX_UNSIGNED);
  811                                     *tl = 0;
  812                                 }
  813                                 break;
  814                         }
  815                     }
  816                     if (nfsv4_opflag[op].retfh == 1) {
  817                         if (!vp) {
  818                                 nd->nd_repstat = NFSERR_NOFILEHANDLE;
  819                                 break;
  820                         }
  821                         VREF(vp);
  822                         if (nfsv4_opflag[op].modifyfs)
  823                                 vn_start_write(vp, &temp_mp, V_WAIT);
  824                         error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp,
  825                             &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes);
  826                         if (!error && !nd->nd_repstat) {
  827                             if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) {
  828                                 new_mp = nvp->v_mount;
  829                                 if (cur_fsid.val[0] !=
  830                                     new_mp->mnt_stat.f_fsid.val[0] ||
  831                                     cur_fsid.val[1] !=
  832                                     new_mp->mnt_stat.f_fsid.val[1]) {
  833                                     /* crossed a server mount point */
  834                                     nd->nd_repstat = nfsvno_checkexp(new_mp,
  835                                         nd->nd_nam, &nes, &credanon);
  836                                     if (!nd->nd_repstat)
  837                                         nd->nd_repstat = nfsd_excred(nd,
  838                                             &nes, credanon);
  839                                     if (credanon != NULL)
  840                                         crfree(credanon);
  841                                     if (!nd->nd_repstat) {
  842                                         vpnes = nes;
  843                                         cur_fsid = new_mp->mnt_stat.f_fsid;
  844                                     }
  845                                 }
  846                                 /* Lookup ops return a locked vnode */
  847                                 NFSVOPUNLOCK(nvp, 0);
  848                             }
  849                             if (!nd->nd_repstat) {
  850                                     vrele(vp);
  851                                     vp = nvp;
  852                             } else
  853                                     vrele(nvp);
  854                         }
  855                         if (nfsv4_opflag[op].modifyfs)
  856                                 vn_finished_write(temp_mp);
  857                     } else if (nfsv4_opflag[op].retfh == 2) {
  858                         if (vp == NULL || savevp == NULL) {
  859                                 nd->nd_repstat = NFSERR_NOFILEHANDLE;
  860                                 break;
  861                         } else if (cur_fsid.val[0] != save_fsid.val[0] ||
  862                             cur_fsid.val[1] != save_fsid.val[1]) {
  863                                 nd->nd_repstat = NFSERR_XDEV;
  864                                 break;
  865                         }
  866                         if (nfsv4_opflag[op].modifyfs)
  867                                 vn_start_write(savevp, &temp_mp, V_WAIT);
  868                         if (NFSVOPLOCK(savevp, LK_EXCLUSIVE) == 0) {
  869                                 VREF(vp);
  870                                 VREF(savevp);
  871                                 error = (*(nfsrv4_ops2[op]))(nd, isdgram,
  872                                     savevp, vp, p, &savevpnes, &vpnes);
  873                         } else
  874                                 nd->nd_repstat = NFSERR_PERM;
  875                         if (nfsv4_opflag[op].modifyfs)
  876                                 vn_finished_write(temp_mp);
  877                     } else {
  878                         if (nfsv4_opflag[op].retfh != 0)
  879                                 panic("nfsrvd_compound");
  880                         if (nfsv4_opflag[op].needscfh) {
  881                                 if (vp != NULL) {
  882                                         if (nfsv4_opflag[op].modifyfs)
  883                                                 vn_start_write(vp, &temp_mp,
  884                                                     V_WAIT);
  885                                         if (NFSVOPLOCK(vp, nfsv4_opflag[op].lktype)
  886                                             == 0)
  887                                                 VREF(vp);
  888                                         else
  889                                                 nd->nd_repstat = NFSERR_PERM;
  890                                 } else {
  891                                         nd->nd_repstat = NFSERR_NOFILEHANDLE;
  892                                         if (op == NFSV4OP_SETATTR) {
  893                                                 /*
  894                                                  * Setattr reply requires a
  895                                                  * bitmap even for errors like
  896                                                  * these.
  897                                                  */
  898                                                 NFSM_BUILD(tl, u_int32_t *,
  899                                                     NFSX_UNSIGNED);
  900                                                 *tl = 0;
  901                                         }
  902                                         break;
  903                                 }
  904                                 if (nd->nd_repstat == 0)
  905                                         error = (*(nfsrv4_ops0[op]))(nd,
  906                                             isdgram, vp, p, &vpnes);
  907                                 if (nfsv4_opflag[op].modifyfs)
  908                                         vn_finished_write(temp_mp);
  909                         } else {
  910                                 error = (*(nfsrv4_ops0[op]))(nd, isdgram,
  911                                     NULL, p, &vpnes);
  912                         }
  913                     }
  914                 };
  915                 if (error) {
  916                         if (error == EBADRPC || error == NFSERR_BADXDR) {
  917                                 nd->nd_repstat = NFSERR_BADXDR;
  918                         } else {
  919                                 nd->nd_repstat = error;
  920                                 printf("nfsv4 comperr0=%d\n", error);
  921                         }
  922                         error = 0;
  923                 }
  924                 retops++;
  925                 if (nd->nd_repstat) {
  926                         *repp = nfsd_errmap(nd);
  927                         break;
  928                 } else {
  929                         *repp = 0;      /* NFS4_OK */
  930                 }
  931         }
  932 nfsmout:
  933         if (error) {
  934                 if (error == EBADRPC || error == NFSERR_BADXDR)
  935                         nd->nd_repstat = NFSERR_BADXDR;
  936                 else
  937                         printf("nfsv4 comperr1=%d\n", error);
  938         }
  939         if (taglen == -1) {
  940                 NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
  941                 *tl++ = 0;
  942                 *tl = 0;
  943         } else {
  944                 *retopsp = txdr_unsigned(retops);
  945         }
  946         if (vp)
  947                 vrele(vp);
  948         if (savevp)
  949                 vrele(savevp);
  950         NFSLOCKV4ROOTMUTEX();
  951         nfsv4_relref(&nfsv4rootfs_lock);
  952         NFSUNLOCKV4ROOTMUTEX();
  953 
  954         NFSEXITCODE2(0, nd);
  955 }

Cache object: b09294b4343348e74c5cc449acf70a38


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