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 #include <security/mac/mac_framework.h> 46 47 extern struct nfsrvfh nfs_pubfh; 48 extern int nfs_pubfhset; 49 extern struct nfsv4lock nfsv4rootfs_lock; 50 extern int nfsrv_clienthashsize; 51 extern int nfsd_debuglevel; 52 extern int nfsrv_layouthighwater; 53 extern volatile int nfsrv_layoutcnt; 54 NFSV4ROOTLOCKMUTEX; 55 NFSSTATESPINLOCK; 56 57 NFSD_VNET_DECLARE(struct nfsrv_stablefirst, nfsrv_stablefirst); 58 NFSD_VNET_DECLARE(struct nfsclienthashhead *, nfsclienthash); 59 NFSD_VNET_DECLARE(int, nfsrc_floodlevel); 60 NFSD_VNET_DECLARE(int, nfsrc_tcpsavedreplies); 61 NFSD_VNET_DECLARE(struct nfsrvfh, nfs_rootfh); 62 NFSD_VNET_DECLARE(int, nfs_rootfhset); 63 NFSD_VNET_DECLARE(struct nfsstatsv1 *, nfsstatsv1_p); 64 65 int (*nfsrv3_procs0[NFS_V3NPROCS])(struct nfsrv_descript *, 66 int, vnode_t , struct nfsexstuff *) = { 67 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 68 nfsrvd_getattr, 69 nfsrvd_setattr, 70 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 71 nfsrvd_access, 72 nfsrvd_readlink, 73 nfsrvd_read, 74 nfsrvd_write, 75 nfsrvd_create, 76 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 77 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 78 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 79 nfsrvd_remove, 80 nfsrvd_remove, 81 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 82 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 83 nfsrvd_readdir, 84 nfsrvd_readdirplus, 85 nfsrvd_statfs, 86 nfsrvd_fsinfo, 87 nfsrvd_pathconf, 88 nfsrvd_commit, 89 }; 90 91 int (*nfsrv3_procs1[NFS_V3NPROCS])(struct nfsrv_descript *, 92 int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *) = { 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_lookup, 97 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 98 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 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 nfsrvd_mkdir, 103 nfsrvd_symlink, 104 nfsrvd_mknod, 105 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 106 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 107 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 108 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 109 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 110 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 111 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 112 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 113 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 114 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 115 }; 116 117 int (*nfsrv3_procs2[NFS_V3NPROCS])(struct nfsrv_descript *, 118 int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *) = { 119 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 120 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 121 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 122 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 123 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 124 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 125 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 126 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 127 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 128 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 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 nfsrvd_rename, 134 nfsrvd_link, 135 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 136 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 137 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 138 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 139 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 140 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 141 }; 142 143 int (*nfsrv4_ops0[NFSV42_NOPS])(struct nfsrv_descript *, 144 int, vnode_t , struct nfsexstuff *) = { 145 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 146 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 147 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 148 nfsrvd_access, 149 nfsrvd_close, 150 nfsrvd_commit, 151 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 152 nfsrvd_delegpurge, 153 nfsrvd_delegreturn, 154 nfsrvd_getattr, 155 nfsrvd_getfh, 156 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 157 nfsrvd_lock, 158 nfsrvd_lockt, 159 nfsrvd_locku, 160 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 161 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 162 nfsrvd_verify, 163 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 164 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 165 nfsrvd_openconfirm, 166 nfsrvd_opendowngrade, 167 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 168 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 169 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 170 nfsrvd_read, 171 nfsrvd_readdirplus, 172 nfsrvd_readlink, 173 nfsrvd_remove, 174 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 175 nfsrvd_renew, 176 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 177 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 178 nfsrvd_secinfo, 179 nfsrvd_setattr, 180 nfsrvd_setclientid, 181 nfsrvd_setclientidcfrm, 182 nfsrvd_verify, 183 nfsrvd_write, 184 nfsrvd_releaselckown, 185 nfsrvd_notsupp, 186 nfsrvd_bindconnsess, 187 nfsrvd_exchangeid, 188 nfsrvd_createsession, 189 nfsrvd_destroysession, 190 nfsrvd_freestateid, 191 nfsrvd_notsupp, 192 nfsrvd_getdevinfo, 193 nfsrvd_notsupp, 194 nfsrvd_layoutcommit, 195 nfsrvd_layoutget, 196 nfsrvd_layoutreturn, 197 nfsrvd_secinfononame, 198 nfsrvd_sequence, 199 nfsrvd_notsupp, 200 nfsrvd_teststateid, 201 nfsrvd_notsupp, 202 nfsrvd_destroyclientid, 203 nfsrvd_reclaimcomplete, 204 nfsrvd_allocate, 205 (int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0, 206 nfsrvd_notsupp, 207 nfsrvd_deallocate, 208 nfsrvd_ioadvise, 209 nfsrvd_layouterror, 210 nfsrvd_layoutstats, 211 nfsrvd_notsupp, 212 nfsrvd_notsupp, 213 nfsrvd_notsupp, 214 nfsrvd_seek, 215 nfsrvd_notsupp, 216 nfsrvd_notsupp, 217 nfsrvd_getxattr, 218 nfsrvd_setxattr, 219 nfsrvd_listxattr, 220 nfsrvd_rmxattr, 221 }; 222 223 int (*nfsrv4_ops1[NFSV42_NOPS])(struct nfsrv_descript *, 224 int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *) = { 225 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 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 nfsrvd_mknod, 232 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 233 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 234 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 235 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 236 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 237 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 238 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 239 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 240 nfsrvd_lookup, 241 nfsrvd_lookup, 242 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 243 nfsrvd_open, 244 nfsrvd_openattr, 245 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 246 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 247 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 248 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 249 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 250 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 251 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 252 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 253 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 254 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 255 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 256 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 257 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 258 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 259 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 260 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 261 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 262 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 263 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 264 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 265 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 266 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 267 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 268 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 269 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 270 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 271 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 272 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 273 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 274 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 275 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 276 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 277 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 278 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 279 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 280 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 281 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 282 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 283 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 284 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 285 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 286 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 287 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 288 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 289 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 290 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 291 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 292 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 293 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 294 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 295 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 296 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 297 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 298 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 299 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 300 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, struct nfsexstuff *))0, 301 }; 302 303 int (*nfsrv4_ops2[NFSV42_NOPS])(struct nfsrv_descript *, 304 int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *) = { 305 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 306 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 307 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 308 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 309 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 310 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 311 (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 nfsrvd_link, 317 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 318 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 319 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 320 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 321 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 322 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 323 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 324 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 325 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 326 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 327 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 328 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 329 (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 nfsrvd_rename, 335 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 336 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 337 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 338 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 339 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 340 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 341 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 342 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 343 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 344 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 345 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 346 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 347 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 348 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 349 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 350 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 351 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 352 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 353 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 354 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 355 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 356 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 357 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 358 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 359 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 360 (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 nfsrvd_copy_file_range, 366 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 367 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 368 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 369 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 370 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 371 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 372 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 373 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 374 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 375 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 376 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 377 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 378 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 379 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 380 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , struct nfsexstuff *, struct nfsexstuff *))0, 381 }; 382 383 /* 384 * Static array that defines which nfs rpc's are nonidempotent 385 */ 386 static int nfsrv_nonidempotent[NFS_V3NPROCS] = { 387 FALSE, 388 FALSE, 389 TRUE, 390 FALSE, 391 FALSE, 392 FALSE, 393 FALSE, 394 TRUE, 395 TRUE, 396 TRUE, 397 TRUE, 398 TRUE, 399 TRUE, 400 TRUE, 401 TRUE, 402 TRUE, 403 FALSE, 404 FALSE, 405 FALSE, 406 FALSE, 407 FALSE, 408 FALSE, 409 }; 410 411 /* 412 * This static array indicates whether or not the RPC modifies the 413 * file system. 414 */ 415 int nfsrv_writerpc[NFS_NPROCS] = { 0, 0, 1, 0, 0, 0, 0, 416 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 417 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; 418 419 SYSCTL_DECL(_vfs_nfsd); 420 static int nfs_minminorv4 = NFSV4_MINORVERSION; 421 SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_min_minorversion4, CTLFLAG_RWTUN, 422 &nfs_minminorv4, 0, 423 "The lowest minor version of NFSv4 handled by the server"); 424 425 static int nfs_maxminorv4 = NFSV42_MINORVERSION; 426 SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_max_minorversion4, CTLFLAG_RWTUN, 427 &nfs_maxminorv4, 0, 428 "The highest minor version of NFSv4 handled by the server"); 429 430 /* local functions */ 431 static void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, 432 u_char *tag, int taglen, u_int32_t minorvers); 433 434 /* 435 * This static array indicates which server procedures require the extra 436 * arguments to return the current file handle for V2, 3. 437 */ 438 static int nfs_retfh[NFS_V3NPROCS] = { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 439 1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 }; 440 441 extern struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS]; 442 443 static int nfsv3to4op[NFS_V3NPROCS] = { 444 NFSPROC_NULL, 445 NFSV4OP_GETATTR, 446 NFSV4OP_SETATTR, 447 NFSV4OP_LOOKUP, 448 NFSV4OP_ACCESS, 449 NFSV4OP_READLINK, 450 NFSV4OP_READ, 451 NFSV4OP_WRITE, 452 NFSV4OP_V3CREATE, 453 NFSV4OP_MKDIR, 454 NFSV4OP_SYMLINK, 455 NFSV4OP_MKNOD, 456 NFSV4OP_REMOVE, 457 NFSV4OP_RMDIR, 458 NFSV4OP_RENAME, 459 NFSV4OP_LINK, 460 NFSV4OP_READDIR, 461 NFSV4OP_READDIRPLUS, 462 NFSV4OP_FSSTAT, 463 NFSV4OP_FSINFO, 464 NFSV4OP_PATHCONF, 465 NFSV4OP_COMMIT, 466 }; 467 468 static struct mtx nfsrvd_statmtx; 469 MTX_SYSINIT(nfsst, &nfsrvd_statmtx, "NFSstat", MTX_DEF); 470 471 static struct ucred *nfsrv_createrootcred(void); 472 473 static void 474 nfsrvd_statstart(int op, struct bintime *now) 475 { 476 if (op > (NFSV42_NOPS + NFSV4OP_FAKENOPS)) { 477 printf("%s: op %d invalid\n", __func__, op); 478 return; 479 } 480 481 mtx_lock(&nfsrvd_statmtx); 482 if (NFSD_VNET(nfsstatsv1_p)->srvstartcnt == 483 NFSD_VNET(nfsstatsv1_p)->srvdonecnt) { 484 if (now != NULL) 485 NFSD_VNET(nfsstatsv1_p)->busyfrom = *now; 486 else 487 binuptime(&NFSD_VNET(nfsstatsv1_p)->busyfrom); 488 489 } 490 NFSD_VNET(nfsstatsv1_p)->srvrpccnt[op]++; 491 NFSD_VNET(nfsstatsv1_p)->srvstartcnt++; 492 mtx_unlock(&nfsrvd_statmtx); 493 494 } 495 496 static void 497 nfsrvd_statend(int op, uint64_t bytes, struct bintime *now, 498 struct bintime *then) 499 { 500 struct bintime dt, lnow; 501 502 if (op > (NFSV42_NOPS + NFSV4OP_FAKENOPS)) { 503 printf("%s: op %d invalid\n", __func__, op); 504 return; 505 } 506 507 if (now == NULL) { 508 now = &lnow; 509 binuptime(now); 510 } 511 512 mtx_lock(&nfsrvd_statmtx); 513 514 NFSD_VNET(nfsstatsv1_p)->srvbytes[op] += bytes; 515 NFSD_VNET(nfsstatsv1_p)->srvops[op]++; 516 517 if (then != NULL) { 518 dt = *now; 519 bintime_sub(&dt, then); 520 bintime_add(&NFSD_VNET(nfsstatsv1_p)->srvduration[op], &dt); 521 } 522 523 dt = *now; 524 bintime_sub(&dt, &NFSD_VNET(nfsstatsv1_p)->busyfrom); 525 bintime_add(&NFSD_VNET(nfsstatsv1_p)->busytime, &dt); 526 NFSD_VNET(nfsstatsv1_p)->busyfrom = *now; 527 528 NFSD_VNET(nfsstatsv1_p)->srvdonecnt++; 529 530 mtx_unlock(&nfsrvd_statmtx); 531 } 532 533 /* 534 * Do an RPC. Basically, get the file handles translated to vnode pointers 535 * and then call the appropriate server routine. The server routines are 536 * split into groups, based on whether they use a file handle or file 537 * handle plus name or ... 538 * The NFS V4 Compound RPC is performed separately by nfsrvd_compound(). 539 */ 540 void 541 nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen, 542 u_int32_t minorvers) 543 { 544 int error = 0, lktype; 545 vnode_t vp; 546 mount_t mp; 547 struct nfsrvfh fh; 548 struct nfsexstuff nes; 549 struct mbuf *md; 550 char *dpos; 551 552 /* 553 * Save the current position in the request mbuf list so 554 * that a rollback to this location can be done upon an 555 * ERELOOKUP error return from an RPC function. 556 */ 557 md = nd->nd_md; 558 dpos = nd->nd_dpos; 559 tryagain: 560 mp = NULL; 561 562 /* 563 * Get a locked vnode for the first file handle 564 */ 565 if (!(nd->nd_flag & ND_NFSV4)) { 566 KASSERT(nd->nd_repstat == 0, ("nfsrvd_dorpc")); 567 /* 568 * For NFSv3, if the malloc/mget allocation is near limits, 569 * return NFSERR_DELAY. 570 */ 571 if ((nd->nd_flag & ND_NFSV3) && nfsrv_mallocmget_limit()) { 572 nd->nd_repstat = NFSERR_DELAY; 573 vp = NULL; 574 } else { 575 error = nfsrv_mtofh(nd, &fh); 576 if (error) { 577 if (error != EBADRPC) 578 printf("nfs dorpc err1=%d\n", error); 579 nd->nd_repstat = NFSERR_GARBAGE; 580 goto out; 581 } 582 if (nd->nd_procnum == NFSPROC_READ || 583 nd->nd_procnum == NFSPROC_WRITE || 584 nd->nd_procnum == NFSPROC_READDIR || 585 nd->nd_procnum == NFSPROC_READDIRPLUS || 586 nd->nd_procnum == NFSPROC_READLINK || 587 nd->nd_procnum == NFSPROC_GETATTR || 588 nd->nd_procnum == NFSPROC_ACCESS || 589 nd->nd_procnum == NFSPROC_FSSTAT || 590 nd->nd_procnum == NFSPROC_FSINFO) 591 lktype = LK_SHARED; 592 else 593 lktype = LK_EXCLUSIVE; 594 if (nd->nd_flag & ND_PUBLOOKUP) 595 nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes, 596 &mp, nfsrv_writerpc[nd->nd_procnum], -1); 597 else 598 nfsd_fhtovp(nd, &fh, lktype, &vp, &nes, 599 &mp, nfsrv_writerpc[nd->nd_procnum], -1); 600 if (nd->nd_repstat == NFSERR_PROGNOTV4) 601 goto out; 602 } 603 } 604 605 /* 606 * For V2 and 3, set the ND_SAVEREPLY flag for the recent request 607 * cache, as required. 608 * For V4, nfsrvd_compound() does this. 609 */ 610 if (!(nd->nd_flag & ND_NFSV4) && nfsrv_nonidempotent[nd->nd_procnum]) 611 nd->nd_flag |= ND_SAVEREPLY; 612 613 nfsrvd_rephead(nd); 614 /* 615 * If nd_repstat is non-zero, just fill in the reply status 616 * to complete the RPC reply for V2. Otherwise, you must do 617 * the RPC. 618 */ 619 if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) { 620 *nd->nd_errp = nfsd_errmap(nd); 621 nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], /*now*/ NULL); 622 nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0, 623 /*now*/ NULL, /*then*/ NULL); 624 vn_finished_write(mp); 625 goto out; 626 } 627 628 /* 629 * Now the procedure can be performed. For V4, nfsrvd_compound() 630 * works through the sub-rpcs, otherwise just call the procedure. 631 * The procedures are in three groups with different arguments. 632 * The group is indicated by the value in nfs_retfh[]. 633 */ 634 if (nd->nd_flag & ND_NFSV4) { 635 nfsrvd_compound(nd, isdgram, tag, taglen, minorvers); 636 } else { 637 struct bintime start_time; 638 639 binuptime(&start_time); 640 nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], &start_time); 641 642 if (nfs_retfh[nd->nd_procnum] == 1) { 643 if (vp) 644 NFSVOPUNLOCK(vp); 645 error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram, 646 vp, NULL, (fhandle_t *)fh.nfsrvfh_data, &nes); 647 } else if (nfs_retfh[nd->nd_procnum] == 2) { 648 error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram, 649 vp, NULL, &nes, NULL); 650 } else { 651 error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram, 652 vp, &nes); 653 } 654 vn_finished_write(mp); 655 656 if (error == 0 && nd->nd_repstat == ERELOOKUP) { 657 /* 658 * Roll back to the beginning of the RPC request 659 * arguments. 660 */ 661 nd->nd_md = md; 662 nd->nd_dpos = dpos; 663 664 /* Free the junk RPC reply and redo the RPC. */ 665 m_freem(nd->nd_mreq); 666 nd->nd_mreq = nd->nd_mb = NULL; 667 nd->nd_repstat = 0; 668 goto tryagain; 669 } 670 671 nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0, 672 /*now*/ NULL, /*then*/ &start_time); 673 } 674 if (error) { 675 if (error != EBADRPC) 676 printf("nfs dorpc err2=%d\n", error); 677 nd->nd_repstat = NFSERR_GARBAGE; 678 } 679 *nd->nd_errp = nfsd_errmap(nd); 680 681 /* 682 * Don't cache certain reply status values. 683 */ 684 if (nd->nd_repstat && (nd->nd_flag & ND_SAVEREPLY) && 685 (nd->nd_repstat == NFSERR_GARBAGE || 686 nd->nd_repstat == NFSERR_BADXDR || 687 nd->nd_repstat == NFSERR_MOVED || 688 nd->nd_repstat == NFSERR_DELAY || 689 nd->nd_repstat == NFSERR_BADSEQID || 690 nd->nd_repstat == NFSERR_RESOURCE || 691 nd->nd_repstat == NFSERR_SERVERFAULT || 692 nd->nd_repstat == NFSERR_STALECLIENTID || 693 nd->nd_repstat == NFSERR_STALESTATEID || 694 nd->nd_repstat == NFSERR_OLDSTATEID || 695 nd->nd_repstat == NFSERR_BADSTATEID || 696 nd->nd_repstat == NFSERR_GRACE || 697 nd->nd_repstat == NFSERR_NOGRACE)) 698 nd->nd_flag &= ~ND_SAVEREPLY; 699 700 out: 701 NFSEXITCODE2(0, nd); 702 } 703 704 /* 705 * Breaks down a compound RPC request and calls the server routines for 706 * the subprocedures. 707 * Some suboperations are performed directly here to simplify file handle<--> 708 * vnode pointer handling. 709 */ 710 static void 711 nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag, 712 int taglen, u_int32_t minorvers) 713 { 714 int i, lktype, op, op0 = 0, rstat, statsinprog = 0; 715 u_int32_t *tl; 716 struct nfsclient *clp, *nclp; 717 int error = 0, igotlock, nextop, numops, savefhcnt; 718 u_int32_t retops = 0, *retopsp = NULL, *repp; 719 vnode_t vp, nvp, savevp; 720 struct nfsrvfh fh; 721 mount_t new_mp, temp_mp = NULL; 722 struct ucred *credanon, *rootcred, *savecred; 723 struct nfsexstuff nes, vpnes, savevpnes; 724 fsid_t cur_fsid, save_fsid; 725 static u_int64_t compref = 0; 726 struct bintime start_time; 727 struct thread *p; 728 struct mbuf *mb, *md; 729 char *bpos, *dpos; 730 int bextpg, bextpgsiz; 731 732 p = curthread; 733 rootcred = savecred = NULL; 734 735 /* Check for and optionally clear the no space flags for DSs. */ 736 nfsrv_checknospc(); 737 738 NFSVNO_EXINIT(&vpnes); 739 NFSVNO_EXINIT(&savevpnes); 740 /* 741 * Put the seq# of the current compound RPC in nfsrv_descript. 742 * (This is used by nfsrv_checkgetattr(), to see if the write 743 * delegation was created by the same compound RPC as the one 744 * with that Getattr in it.) 745 * Don't worry about the 64bit number wrapping around. It ain't 746 * gonna happen before this server gets shut down/rebooted. 747 */ 748 nd->nd_compref = compref++; 749 750 /* 751 * Check for and optionally get a lock on the root. This lock means that 752 * no nfsd will be fiddling with the V4 file system and state stuff. It 753 * is required when the V4 root is being changed, the stable storage 754 * restart file is being updated, or callbacks are being done. 755 * When any of the nfsd are processing an NFSv4 compound RPC, they must 756 * either hold a reference count (nfs_usecnt) or the lock. When 757 * nfsrv_unlock() is called to release the lock, it can optionally 758 * also get a reference count, which saves the need for a call to 759 * nfsrv_getref() after nfsrv_unlock(). 760 */ 761 /* 762 * First, check to see if we need to wait for an update lock. 763 */ 764 igotlock = 0; 765 NFSLOCKV4ROOTMUTEX(); 766 if (NFSD_VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_NEEDLOCK) 767 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL, 768 NFSV4ROOTLOCKMUTEXPTR, NULL); 769 else 770 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL, 771 NFSV4ROOTLOCKMUTEXPTR, NULL); 772 NFSUNLOCKV4ROOTMUTEX(); 773 if (igotlock) { 774 /* 775 * If I got the lock, I can update the stable storage file. 776 * Done when the grace period is over or a client has long 777 * since expired. 778 */ 779 NFSD_VNET(nfsrv_stablefirst).nsf_flags &= ~NFSNSF_NEEDLOCK; 780 if ((NFSD_VNET(nfsrv_stablefirst).nsf_flags & 781 (NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER) 782 nfsrv_updatestable(p); 783 784 /* 785 * If at least one client has long since expired, search 786 * the client list for them, write a REVOKE record on the 787 * stable storage file and then remove them from the client 788 * list. 789 */ 790 if (NFSD_VNET(nfsrv_stablefirst).nsf_flags & 791 NFSNSF_EXPIREDCLIENT) { 792 NFSD_VNET(nfsrv_stablefirst).nsf_flags &= 793 ~NFSNSF_EXPIREDCLIENT; 794 for (i = 0; i < nfsrv_clienthashsize; i++) { 795 LIST_FOREACH_SAFE(clp, &NFSD_VNET(nfsclienthash)[i], 796 lc_hash, nclp) { 797 if (clp->lc_flags & LCL_EXPIREIT) { 798 if (!LIST_EMPTY(&clp->lc_open) || 799 !LIST_EMPTY(&clp->lc_deleg)) 800 nfsrv_writestable(clp->lc_id, 801 clp->lc_idlen, NFSNST_REVOKE, p); 802 nfsrv_cleanclient(clp, p); 803 nfsrv_freedeleglist(&clp->lc_deleg); 804 nfsrv_freedeleglist(&clp->lc_olddeleg); 805 LIST_REMOVE(clp, lc_hash); 806 nfsrv_zapclient(clp, p); 807 } 808 } 809 } 810 } 811 NFSLOCKV4ROOTMUTEX(); 812 nfsv4_unlock(&nfsv4rootfs_lock, 1); 813 NFSUNLOCKV4ROOTMUTEX(); 814 } else { 815 /* 816 * If we didn't get the lock, we need to get a refcnt, 817 * which also checks for and waits for the lock. 818 */ 819 NFSLOCKV4ROOTMUTEX(); 820 nfsv4_getref(&nfsv4rootfs_lock, NULL, 821 NFSV4ROOTLOCKMUTEXPTR, NULL); 822 NFSUNLOCKV4ROOTMUTEX(); 823 } 824 825 /* 826 * If flagged, search for open owners that haven't had any opens 827 * for a long time. 828 */ 829 if (NFSD_VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_NOOPENS) { 830 nfsrv_throwawayopens(p); 831 } 832 833 /* Do a CBLAYOUTRECALL callback if over the high water mark. */ 834 if (nfsrv_layoutcnt > nfsrv_layouthighwater) 835 nfsrv_recalloldlayout(p); 836 837 savevp = vp = NULL; 838 save_fsid.val[0] = save_fsid.val[1] = 0; 839 cur_fsid.val[0] = cur_fsid.val[1] = 0; 840 nextop = -1; 841 savefhcnt = 0; 842 843 /* If taglen < 0, there was a parsing error in nfsd_getminorvers(). */ 844 if (taglen < 0) { 845 error = EBADRPC; 846 goto nfsmout; 847 } 848 849 (void) nfsm_strtom(nd, tag, taglen); 850 NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED); 851 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 852 if ((minorvers != NFSV4_MINORVERSION && 853 minorvers != NFSV41_MINORVERSION && 854 minorvers != NFSV42_MINORVERSION) || 855 minorvers < nfs_minminorv4 || minorvers > nfs_maxminorv4) 856 nd->nd_repstat = NFSERR_MINORVERMISMATCH; 857 if (nd->nd_repstat) 858 numops = 0; 859 else 860 numops = fxdr_unsigned(int, *tl); 861 /* 862 * Loop around doing the sub ops. 863 * vp - is an unlocked vnode pointer for the CFH 864 * savevp - is an unlocked vnode pointer for the SAVEDFH 865 * (at some future date, it might turn out to be more appropriate 866 * to keep the file handles instead of vnode pointers?) 867 * savevpnes and vpnes - are the export flags for the above. 868 */ 869 for (i = 0; i < numops; i++) { 870 NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED); 871 if (savefhcnt > 0) { 872 op = NFSV4OP_SAVEFH; 873 *repp = txdr_unsigned(op); 874 savefhcnt--; 875 } else if (nextop == -1) { 876 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 877 *repp = *tl; 878 op = fxdr_unsigned(int, *tl); 879 } else { 880 op = nextop; 881 *repp = txdr_unsigned(op); 882 nextop = -1; 883 } 884 NFSD_DEBUG(4, "op=%d\n", op); 885 if (op < NFSV4OP_ACCESS || op >= NFSV42_NOPS || 886 (op >= NFSV4OP_NOPS && (nd->nd_flag & ND_NFSV41) == 0) || 887 (op >= NFSV41_NOPS && (nd->nd_flag & ND_NFSV42) == 0)) { 888 nd->nd_repstat = NFSERR_OPILLEGAL; 889 *repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL); 890 *repp = nfsd_errmap(nd); 891 retops++; 892 break; 893 } else { 894 repp++; 895 } 896 897 binuptime(&start_time); 898 nfsrvd_statstart(op, &start_time); 899 statsinprog = 1; 900 901 if (i == 0) 902 op0 = op; 903 if (i == numops - 1) 904 nd->nd_flag |= ND_LASTOP; 905 906 /* 907 * Check for a referral on the current FH and, if so, return 908 * NFSERR_MOVED for all ops that allow it, except Getattr. 909 */ 910 if (vp != NULL && op != NFSV4OP_GETATTR && 911 nfsv4root_getreferral(vp, NULL, 0) != NULL && 912 nfsrv_errmoved(op)) { 913 nd->nd_repstat = NFSERR_MOVED; 914 *repp = nfsd_errmap(nd); 915 retops++; 916 break; 917 } 918 919 /* 920 * For NFSv4.1, check for a Sequence Operation being first 921 * or one of the other allowed operations by itself. 922 */ 923 if ((nd->nd_flag & ND_NFSV41) != 0) { 924 if (i != 0 && op == NFSV4OP_SEQUENCE) 925 nd->nd_repstat = NFSERR_SEQUENCEPOS; 926 else if (i == 0 && op != NFSV4OP_SEQUENCE && 927 op != NFSV4OP_EXCHANGEID && 928 op != NFSV4OP_CREATESESSION && 929 op != NFSV4OP_BINDCONNTOSESS && 930 op != NFSV4OP_DESTROYCLIENTID && 931 op != NFSV4OP_DESTROYSESSION) 932 nd->nd_repstat = NFSERR_OPNOTINSESS; 933 else if (i != 0 && op0 != NFSV4OP_SEQUENCE) 934 nd->nd_repstat = NFSERR_NOTONLYOP; 935 if (nd->nd_repstat != 0) { 936 *repp = nfsd_errmap(nd); 937 retops++; 938 break; 939 } 940 } 941 942 nd->nd_procnum = op; 943 /* 944 * If over flood level, reply NFSERR_RESOURCE, if at the first 945 * Op. (Since a client recovery from NFSERR_RESOURCE can get 946 * really nasty for certain Op sequences, I'll play it safe 947 * and only return the error at the beginning.) The cache 948 * will still function over flood level, but uses lots of 949 * mbufs.) 950 * If nfsrv_mallocmget_limit() returns True, the system is near 951 * to its limit for memory that malloc()/mget() can allocate. 952 */ 953 if (i == 0 && (nd->nd_rp == NULL || 954 nd->nd_rp->rc_refcnt == 0) && 955 (nfsrv_mallocmget_limit() || 956 NFSD_VNET(nfsrc_tcpsavedreplies) > 957 NFSD_VNET(nfsrc_floodlevel))) { 958 if (NFSD_VNET(nfsrc_tcpsavedreplies) > 959 NFSD_VNET(nfsrc_floodlevel)) 960 printf("nfsd server cache flooded, try " 961 "increasing vfs.nfsd.tcphighwater\n"); 962 nd->nd_repstat = NFSERR_RESOURCE; 963 *repp = nfsd_errmap(nd); 964 if (op == NFSV4OP_SETATTR) { 965 /* 966 * Setattr replies require a bitmap. 967 * even for errors like these. 968 */ 969 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); 970 *tl = 0; 971 } 972 retops++; 973 break; 974 } 975 976 /* 977 * Check for the case of SP4_MACH_CRED and an operation in 978 * the allow set. For these operations, replace nd_cred with 979 * root credentials so that the operation will not fail due 980 * to credentials. 981 * NB: ND_MACHCRED is set by Sequence when the ClientID 982 * specifies LCL_MACHCRED and the RPC is being performed 983 * via krb5i or krb5p using the machine principal. 984 */ 985 if ((nd->nd_flag & ND_MACHCRED) != 0) { 986 if (NFSISSET_OPBIT(&nd->nd_allowops, op)) { 987 /* Replace nd_cred with root creds. */ 988 if (rootcred == NULL) 989 rootcred = nfsrv_createrootcred(); 990 if (savecred == NULL) 991 savecred = nd->nd_cred; 992 nd->nd_cred = rootcred; 993 } else if (savecred != NULL) { 994 nd->nd_cred = savecred; 995 savecred = NULL; 996 } 997 } 998 999 if (nfsv4_opflag[op].savereply) 1000 nd->nd_flag |= ND_SAVEREPLY; 1001 switch (op) { 1002 case NFSV4OP_PUTFH: 1003 error = nfsrv_mtofh(nd, &fh); 1004 if (error) 1005 goto nfsmout; 1006 if ((nd->nd_flag & ND_LASTOP) == 0) { 1007 /* 1008 * Pre-parse the next op#. If it is 1009 * SaveFH, count it and skip to the 1010 * next op#, if not the last op#. 1011 * nextop is used to determine if 1012 * NFSERR_WRONGSEC can be returned, 1013 * per RFC5661 Sec. 2.6. 1014 */ 1015 do { 1016 NFSM_DISSECT(tl, uint32_t *, 1017 NFSX_UNSIGNED); 1018 nextop = fxdr_unsigned(int, *tl); 1019 if (nextop == NFSV4OP_SAVEFH && 1020 i < numops - 1) 1021 savefhcnt++; 1022 } while (nextop == NFSV4OP_SAVEFH && 1023 i < numops - 1); 1024 } 1025 if (!nd->nd_repstat) 1026 nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes, 1027 NULL, 0, nextop); 1028 /* For now, allow this for non-export FHs */ 1029 if (!nd->nd_repstat) { 1030 if (vp) 1031 vrele(vp); 1032 vp = nvp; 1033 cur_fsid = vp->v_mount->mnt_stat.f_fsid; 1034 NFSVOPUNLOCK(vp); 1035 vpnes = nes; 1036 } 1037 break; 1038 case NFSV4OP_PUTPUBFH: 1039 if (nfs_pubfhset) { 1040 if ((nd->nd_flag & ND_LASTOP) == 0) { 1041 /* 1042 * Pre-parse the next op#. If it is 1043 * SaveFH, count it and skip to the 1044 * next op#, if not the last op#. 1045 * nextop is used to determine if 1046 * NFSERR_WRONGSEC can be returned, 1047 * per RFC5661 Sec. 2.6. 1048 */ 1049 do { 1050 NFSM_DISSECT(tl, uint32_t *, 1051 NFSX_UNSIGNED); 1052 nextop = fxdr_unsigned(int, 1053 *tl); 1054 if (nextop == NFSV4OP_SAVEFH && 1055 i < numops - 1) 1056 savefhcnt++; 1057 } while (nextop == NFSV4OP_SAVEFH && 1058 i < numops - 1); 1059 } 1060 nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp, 1061 &nes, NULL, 0, nextop); 1062 } else 1063 nd->nd_repstat = NFSERR_NOFILEHANDLE; 1064 if (!nd->nd_repstat) { 1065 if (vp) 1066 vrele(vp); 1067 vp = nvp; 1068 cur_fsid = vp->v_mount->mnt_stat.f_fsid; 1069 NFSVOPUNLOCK(vp); 1070 vpnes = nes; 1071 } 1072 break; 1073 case NFSV4OP_PUTROOTFH: 1074 if (NFSD_VNET(nfs_rootfhset)) { 1075 if ((nd->nd_flag & ND_LASTOP) == 0) { 1076 /* 1077 * Pre-parse the next op#. If it is 1078 * SaveFH, count it and skip to the 1079 * next op#, if not the last op#. 1080 * nextop is used to determine if 1081 * NFSERR_WRONGSEC can be returned, 1082 * per RFC5661 Sec. 2.6. 1083 */ 1084 do { 1085 NFSM_DISSECT(tl, uint32_t *, 1086 NFSX_UNSIGNED); 1087 nextop = fxdr_unsigned(int, 1088 *tl); 1089 if (nextop == NFSV4OP_SAVEFH && 1090 i < numops - 1) 1091 savefhcnt++; 1092 } while (nextop == NFSV4OP_SAVEFH && 1093 i < numops - 1); 1094 } 1095 nfsd_fhtovp(nd, &NFSD_VNET(nfs_rootfh), 1096 LK_SHARED, &nvp, &nes, NULL, 0, nextop); 1097 if (!nd->nd_repstat) { 1098 if (vp) 1099 vrele(vp); 1100 vp = nvp; 1101 cur_fsid = vp->v_mount->mnt_stat.f_fsid; 1102 NFSVOPUNLOCK(vp); 1103 vpnes = nes; 1104 } 1105 } else 1106 nd->nd_repstat = NFSERR_NOFILEHANDLE; 1107 break; 1108 case NFSV4OP_SAVEFH: 1109 if (vp && NFSVNO_EXPORTED(&vpnes)) { 1110 nd->nd_repstat = 0; 1111 /* If vp == savevp, a no-op */ 1112 if (vp != savevp) { 1113 if (savevp) 1114 vrele(savevp); 1115 VREF(vp); 1116 savevp = vp; 1117 savevpnes = vpnes; 1118 save_fsid = cur_fsid; 1119 } 1120 if ((nd->nd_flag & ND_CURSTATEID) != 0) { 1121 nd->nd_savedcurstateid = 1122 nd->nd_curstateid; 1123 nd->nd_flag |= ND_SAVEDCURSTATEID; 1124 } 1125 } else { 1126 nd->nd_repstat = NFSERR_NOFILEHANDLE; 1127 } 1128 break; 1129 case NFSV4OP_RESTOREFH: 1130 if (savevp) { 1131 if ((nd->nd_flag & ND_LASTOP) == 0) { 1132 /* 1133 * Pre-parse the next op#. If it is 1134 * SaveFH, count it and skip to the 1135 * next op#, if not the last op#. 1136 * nextop is used to determine if 1137 * NFSERR_WRONGSEC can be returned, 1138 * per RFC5661 Sec. 2.6. 1139 */ 1140 do { 1141 NFSM_DISSECT(tl, uint32_t *, 1142 NFSX_UNSIGNED); 1143 nextop = fxdr_unsigned(int, 1144 *tl); 1145 if (nextop == NFSV4OP_SAVEFH && 1146 i < numops - 1) 1147 savefhcnt++; 1148 } while (nextop == NFSV4OP_SAVEFH && 1149 i < numops - 1); 1150 } 1151 nd->nd_repstat = 0; 1152 /* If vp == savevp, a no-op */ 1153 if (vp != savevp) { 1154 if (nfsrv_checkwrongsec(nd, nextop, 1155 savevp->v_type)) 1156 nd->nd_repstat = 1157 nfsvno_testexp(nd, 1158 &savevpnes); 1159 if (nd->nd_repstat == 0) { 1160 VREF(savevp); 1161 vrele(vp); 1162 vp = savevp; 1163 vpnes = savevpnes; 1164 cur_fsid = save_fsid; 1165 } 1166 } 1167 if (nd->nd_repstat == 0 && 1168 (nd->nd_flag & ND_SAVEDCURSTATEID) != 0) { 1169 nd->nd_curstateid = 1170 nd->nd_savedcurstateid; 1171 nd->nd_flag |= ND_CURSTATEID; 1172 } 1173 } else { 1174 nd->nd_repstat = NFSERR_RESTOREFH; 1175 } 1176 break; 1177 default: 1178 /* 1179 * Allow a Lookup, Getattr, GetFH, Secinfo on an 1180 * non-exported directory if 1181 * nfs_rootfhset. Do I need to allow any other Ops? 1182 * (You can only have a non-exported vpnes if 1183 * nfs_rootfhset is true. See nfsd_fhtovp()) 1184 * Allow AUTH_SYS to be used for file systems 1185 * exported GSS only for certain Ops, to allow 1186 * clients to do mounts more easily. 1187 */ 1188 if (nfsv4_opflag[op].needscfh && vp) { 1189 if (!NFSVNO_EXPORTED(&vpnes) && 1190 op != NFSV4OP_LOOKUP && 1191 op != NFSV4OP_GETATTR && 1192 op != NFSV4OP_GETFH && 1193 op != NFSV4OP_ACCESS && 1194 op != NFSV4OP_READLINK && 1195 op != NFSV4OP_SECINFO && 1196 op != NFSV4OP_SECINFONONAME) 1197 nd->nd_repstat = NFSERR_NOFILEHANDLE; 1198 if (nd->nd_repstat) { 1199 if (op == NFSV4OP_SETATTR) { 1200 /* 1201 * Setattr reply requires a bitmap 1202 * even for errors like these. 1203 */ 1204 NFSM_BUILD(tl, u_int32_t *, 1205 NFSX_UNSIGNED); 1206 *tl = 0; 1207 } 1208 break; 1209 } 1210 } 1211 1212 /* 1213 * Save the current positions in the mbuf lists so 1214 * that a rollback to this location can be done upon a 1215 * redo due to a ERELOOKUP return for a operation. 1216 */ 1217 mb = nd->nd_mb; 1218 bpos = nd->nd_bpos; 1219 bextpg = nd->nd_bextpg; 1220 bextpgsiz = nd->nd_bextpgsiz; 1221 md = nd->nd_md; 1222 dpos = nd->nd_dpos; 1223 tryagain: 1224 1225 if (nfsv4_opflag[op].retfh == 1) { 1226 if (!vp) { 1227 nd->nd_repstat = NFSERR_NOFILEHANDLE; 1228 break; 1229 } 1230 if (NFSVNO_EXPORTED(&vpnes) && (op == NFSV4OP_LOOKUP || 1231 op == NFSV4OP_LOOKUPP || (op == NFSV4OP_OPEN && 1232 vp->v_type == VDIR))) { 1233 /* Check for wrong security. */ 1234 rstat = nfsvno_testexp(nd, &vpnes); 1235 if (rstat != 0) { 1236 nd->nd_repstat = rstat; 1237 break; 1238 } 1239 } 1240 VREF(vp); 1241 if (nfsv4_opflag[op].modifyfs) 1242 vn_start_write(vp, &temp_mp, V_WAIT); 1243 error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp, 1244 &nvp, (fhandle_t *)fh.nfsrvfh_data, &vpnes); 1245 if (!error && !nd->nd_repstat) { 1246 if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) { 1247 new_mp = nvp->v_mount; 1248 if (fsidcmp(&cur_fsid, &new_mp->mnt_stat.f_fsid) != 0) { 1249 /* crossed a server mount point */ 1250 nd->nd_repstat = nfsvno_checkexp(new_mp, 1251 nd->nd_nam, &nes, &credanon); 1252 if (!nd->nd_repstat) 1253 nd->nd_repstat = nfsd_excred(nd, 1254 &nes, credanon, true); 1255 if (credanon != NULL) 1256 crfree(credanon); 1257 if (!nd->nd_repstat) { 1258 vpnes = nes; 1259 cur_fsid = new_mp->mnt_stat.f_fsid; 1260 } 1261 } 1262 /* Lookup ops return a locked vnode */ 1263 NFSVOPUNLOCK(nvp); 1264 } 1265 if (!nd->nd_repstat) { 1266 vrele(vp); 1267 vp = nvp; 1268 } else 1269 vrele(nvp); 1270 } 1271 if (nfsv4_opflag[op].modifyfs) 1272 vn_finished_write(temp_mp); 1273 } else if (nfsv4_opflag[op].retfh == 2) { 1274 if (vp == NULL || savevp == NULL) { 1275 nd->nd_repstat = NFSERR_NOFILEHANDLE; 1276 break; 1277 } else if (fsidcmp(&cur_fsid, &save_fsid) != 0) { 1278 nd->nd_repstat = NFSERR_XDEV; 1279 break; 1280 } 1281 if (nfsv4_opflag[op].modifyfs) 1282 vn_start_write(savevp, &temp_mp, V_WAIT); 1283 if (NFSVOPLOCK(savevp, LK_EXCLUSIVE) == 0) { 1284 VREF(vp); 1285 VREF(savevp); 1286 error = (*(nfsrv4_ops2[op]))(nd, isdgram, 1287 savevp, vp, &savevpnes, &vpnes); 1288 } else 1289 nd->nd_repstat = NFSERR_PERM; 1290 if (nfsv4_opflag[op].modifyfs) 1291 vn_finished_write(temp_mp); 1292 } else { 1293 if (nfsv4_opflag[op].retfh != 0) 1294 panic("nfsrvd_compound"); 1295 if (nfsv4_opflag[op].needscfh) { 1296 if (vp != NULL) { 1297 lktype = nfsv4_opflag[op].lktype; 1298 if (nfsv4_opflag[op].modifyfs) { 1299 vn_start_write(vp, &temp_mp, 1300 V_WAIT); 1301 if (op == NFSV4OP_WRITE && 1302 MNT_SHARED_WRITES(temp_mp)) 1303 lktype = LK_SHARED; 1304 } 1305 if (NFSVOPLOCK(vp, lktype) == 0) 1306 VREF(vp); 1307 else 1308 nd->nd_repstat = NFSERR_PERM; 1309 } else { 1310 nd->nd_repstat = NFSERR_NOFILEHANDLE; 1311 if (op == NFSV4OP_SETATTR) { 1312 /* 1313 * Setattr reply requires a 1314 * bitmap even for errors like 1315 * these. 1316 */ 1317 NFSM_BUILD(tl, u_int32_t *, 1318 NFSX_UNSIGNED); 1319 *tl = 0; 1320 } 1321 break; 1322 } 1323 if (nd->nd_repstat == 0) { 1324 error = (*(nfsrv4_ops0[op]))(nd, 1325 isdgram, vp, &vpnes); 1326 if ((op == NFSV4OP_SECINFO || 1327 op == NFSV4OP_SECINFONONAME) && 1328 error == 0 && nd->nd_repstat == 0) { 1329 /* 1330 * Secinfo and Secinfo_no_name 1331 * consume the current FH. 1332 */ 1333 vrele(vp); 1334 vp = NULL; 1335 } 1336 } 1337 if (nfsv4_opflag[op].modifyfs) 1338 vn_finished_write(temp_mp); 1339 } else { 1340 error = (*(nfsrv4_ops0[op]))(nd, isdgram, 1341 NULL, &vpnes); 1342 } 1343 } 1344 } 1345 if (error) { 1346 if (error == EBADRPC || error == NFSERR_BADXDR) { 1347 nd->nd_repstat = NFSERR_BADXDR; 1348 } else { 1349 nd->nd_repstat = error; 1350 printf("nfsv4 comperr0=%d\n", error); 1351 } 1352 error = 0; 1353 } 1354 1355 if (nd->nd_repstat == ERELOOKUP) { 1356 /* 1357 * Roll back to the beginning of the operation 1358 * arguments. 1359 */ 1360 nd->nd_md = md; 1361 nd->nd_dpos = dpos; 1362 1363 /* 1364 * Trim off the bogus reply for this operation 1365 * and redo the operation. 1366 */ 1367 nfsm_trimtrailing(nd, mb, bpos, bextpg, bextpgsiz); 1368 nd->nd_repstat = 0; 1369 nd->nd_flag |= ND_ERELOOKUP; 1370 goto tryagain; 1371 } 1372 nd->nd_flag &= ~ND_ERELOOKUP; 1373 1374 if (statsinprog != 0) { 1375 nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL, 1376 /*then*/ &start_time); 1377 statsinprog = 0; 1378 } 1379 1380 retops++; 1381 if (nd->nd_repstat) { 1382 *repp = nfsd_errmap(nd); 1383 break; 1384 } else { 1385 *repp = 0; /* NFS4_OK */ 1386 } 1387 } 1388 nfsmout: 1389 if (statsinprog != 0) { 1390 nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL, 1391 /*then*/ &start_time); 1392 statsinprog = 0; 1393 } 1394 if (error) { 1395 if (error == EBADRPC || error == NFSERR_BADXDR) 1396 nd->nd_repstat = NFSERR_BADXDR; 1397 else 1398 printf("nfsv4 comperr1=%d\n", error); 1399 } 1400 if (taglen == -1) { 1401 NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 1402 *tl++ = 0; 1403 *tl = 0; 1404 } else { 1405 *retopsp = txdr_unsigned(retops); 1406 } 1407 if (vp) 1408 vrele(vp); 1409 if (savevp) 1410 vrele(savevp); 1411 if (savecred != NULL) 1412 nd->nd_cred = savecred; 1413 if (rootcred != NULL) 1414 crfree(rootcred); 1415 NFSLOCKV4ROOTMUTEX(); 1416 nfsv4_relref(&nfsv4rootfs_lock); 1417 NFSUNLOCKV4ROOTMUTEX(); 1418 1419 NFSEXITCODE2(0, nd); 1420 } 1421 1422 /* Create a credential for "root". */ 1423 static struct ucred * 1424 nfsrv_createrootcred(void) 1425 { 1426 struct ucred *cr; 1427 gid_t grp; 1428 1429 cr = crget(); 1430 cr->cr_uid = cr->cr_ruid = cr->cr_svuid = UID_ROOT; 1431 grp = GID_WHEEL; 1432 crsetgroups(cr, 1, &grp); 1433 cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0]; 1434 cr->cr_prison = curthread->td_ucred->cr_prison; 1435 prison_hold(cr->cr_prison); 1436 #ifdef MAC 1437 mac_cred_associate_nfsd(cr); 1438 #endif 1439 return (cr); 1440 } 1441