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