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