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