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