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