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