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 /* 775 * For now, newnfsstats.srvrpccnt[] doesn't have entries 776 * for the NFSv4.1 operations. 777 */ 778 if (nd->nd_procnum < NFSV4OP_NOPS) 779 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]); 780 switch (op) { 781 case NFSV4OP_PUTFH: 782 error = nfsrv_mtofh(nd, &fh); 783 if (error) 784 goto nfsmout; 785 if (!nd->nd_repstat) 786 nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes, 787 NULL, 0, p); 788 /* For now, allow this for non-export FHs */ 789 if (!nd->nd_repstat) { 790 if (vp) 791 vrele(vp); 792 vp = nvp; 793 cur_fsid = vp->v_mount->mnt_stat.f_fsid; 794 NFSVOPUNLOCK(vp, 0); 795 vpnes = nes; 796 } 797 break; 798 case NFSV4OP_PUTPUBFH: 799 if (nfs_pubfhset) 800 nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp, 801 &nes, NULL, 0, p); 802 else 803 nd->nd_repstat = NFSERR_NOFILEHANDLE; 804 if (!nd->nd_repstat) { 805 if (vp) 806 vrele(vp); 807 vp = nvp; 808 cur_fsid = vp->v_mount->mnt_stat.f_fsid; 809 NFSVOPUNLOCK(vp, 0); 810 vpnes = nes; 811 } 812 break; 813 case NFSV4OP_PUTROOTFH: 814 if (nfs_rootfhset) { 815 nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp, 816 &nes, NULL, 0, p); 817 if (!nd->nd_repstat) { 818 if (vp) 819 vrele(vp); 820 vp = nvp; 821 cur_fsid = vp->v_mount->mnt_stat.f_fsid; 822 NFSVOPUNLOCK(vp, 0); 823 vpnes = nes; 824 } 825 } else 826 nd->nd_repstat = NFSERR_NOFILEHANDLE; 827 break; 828 case NFSV4OP_SAVEFH: 829 if (vp && NFSVNO_EXPORTED(&vpnes)) { 830 nd->nd_repstat = 0; 831 /* If vp == savevp, a no-op */ 832 if (vp != savevp) { 833 if (savevp) 834 vrele(savevp); 835 VREF(vp); 836 savevp = vp; 837 savevpnes = vpnes; 838 save_fsid = cur_fsid; 839 } 840 } else { 841 nd->nd_repstat = NFSERR_NOFILEHANDLE; 842 } 843 break; 844 case NFSV4OP_RESTOREFH: 845 if (savevp) { 846 nd->nd_repstat = 0; 847 /* If vp == savevp, a no-op */ 848 if (vp != savevp) { 849 VREF(savevp); 850 vrele(vp); 851 vp = savevp; 852 vpnes = savevpnes; 853 cur_fsid = save_fsid; 854 } 855 } else { 856 nd->nd_repstat = NFSERR_RESTOREFH; 857 } 858 break; 859 default: 860 /* 861 * Allow a Lookup, Getattr, GetFH, Secinfo on an 862 * non-exported directory if 863 * nfs_rootfhset. Do I need to allow any other Ops? 864 * (You can only have a non-exported vpnes if 865 * nfs_rootfhset is true. See nfsd_fhtovp()) 866 * Allow AUTH_SYS to be used for file systems 867 * exported GSS only for certain Ops, to allow 868 * clients to do mounts more easily. 869 */ 870 if (nfsv4_opflag[op].needscfh && vp) { 871 if (!NFSVNO_EXPORTED(&vpnes) && 872 op != NFSV4OP_LOOKUP && 873 op != NFSV4OP_GETATTR && 874 op != NFSV4OP_GETFH && 875 op != NFSV4OP_ACCESS && 876 op != NFSV4OP_READLINK && 877 op != NFSV4OP_SECINFO) 878 nd->nd_repstat = NFSERR_NOFILEHANDLE; 879 else if (nfsvno_testexp(nd, &vpnes) && 880 op != NFSV4OP_LOOKUP && 881 op != NFSV4OP_GETFH && 882 op != NFSV4OP_GETATTR && 883 op != NFSV4OP_SECINFO) 884 nd->nd_repstat = NFSERR_WRONGSEC; 885 if (nd->nd_repstat) { 886 if (op == NFSV4OP_SETATTR) { 887 /* 888 * Setattr reply requires a bitmap 889 * even for errors like these. 890 */ 891 NFSM_BUILD(tl, u_int32_t *, 892 NFSX_UNSIGNED); 893 *tl = 0; 894 } 895 break; 896 } 897 } 898 if (nfsv4_opflag[op].retfh == 1) { 899 if (!vp) { 900 nd->nd_repstat = NFSERR_NOFILEHANDLE; 901 break; 902 } 903 VREF(vp); 904 if (nfsv4_opflag[op].modifyfs) 905 vn_start_write(vp, &temp_mp, V_WAIT); 906 error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp, 907 &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes); 908 if (!error && !nd->nd_repstat) { 909 if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) { 910 new_mp = nvp->v_mount; 911 if (cur_fsid.val[0] != 912 new_mp->mnt_stat.f_fsid.val[0] || 913 cur_fsid.val[1] != 914 new_mp->mnt_stat.f_fsid.val[1]) { 915 /* crossed a server mount point */ 916 nd->nd_repstat = nfsvno_checkexp(new_mp, 917 nd->nd_nam, &nes, &credanon); 918 if (!nd->nd_repstat) 919 nd->nd_repstat = nfsd_excred(nd, 920 &nes, credanon); 921 if (credanon != NULL) 922 crfree(credanon); 923 if (!nd->nd_repstat) { 924 vpnes = nes; 925 cur_fsid = new_mp->mnt_stat.f_fsid; 926 } 927 } 928 /* Lookup ops return a locked vnode */ 929 NFSVOPUNLOCK(nvp, 0); 930 } 931 if (!nd->nd_repstat) { 932 vrele(vp); 933 vp = nvp; 934 } else 935 vrele(nvp); 936 } 937 if (nfsv4_opflag[op].modifyfs) 938 vn_finished_write(temp_mp); 939 } else if (nfsv4_opflag[op].retfh == 2) { 940 if (vp == NULL || savevp == NULL) { 941 nd->nd_repstat = NFSERR_NOFILEHANDLE; 942 break; 943 } else if (cur_fsid.val[0] != save_fsid.val[0] || 944 cur_fsid.val[1] != save_fsid.val[1]) { 945 nd->nd_repstat = NFSERR_XDEV; 946 break; 947 } 948 if (nfsv4_opflag[op].modifyfs) 949 vn_start_write(savevp, &temp_mp, V_WAIT); 950 if (NFSVOPLOCK(savevp, LK_EXCLUSIVE) == 0) { 951 VREF(vp); 952 VREF(savevp); 953 error = (*(nfsrv4_ops2[op]))(nd, isdgram, 954 savevp, vp, p, &savevpnes, &vpnes); 955 } else 956 nd->nd_repstat = NFSERR_PERM; 957 if (nfsv4_opflag[op].modifyfs) 958 vn_finished_write(temp_mp); 959 } else { 960 if (nfsv4_opflag[op].retfh != 0) 961 panic("nfsrvd_compound"); 962 if (nfsv4_opflag[op].needscfh) { 963 if (vp != NULL) { 964 lktype = nfsv4_opflag[op].lktype; 965 if (nfsv4_opflag[op].modifyfs) { 966 vn_start_write(vp, &temp_mp, 967 V_WAIT); 968 if (op == NFSV4OP_WRITE && 969 MNT_SHARED_WRITES(temp_mp)) 970 lktype = LK_SHARED; 971 } 972 if (NFSVOPLOCK(vp, lktype) == 0) 973 VREF(vp); 974 else 975 nd->nd_repstat = NFSERR_PERM; 976 } else { 977 nd->nd_repstat = NFSERR_NOFILEHANDLE; 978 if (op == NFSV4OP_SETATTR) { 979 /* 980 * Setattr reply requires a 981 * bitmap even for errors like 982 * these. 983 */ 984 NFSM_BUILD(tl, u_int32_t *, 985 NFSX_UNSIGNED); 986 *tl = 0; 987 } 988 break; 989 } 990 if (nd->nd_repstat == 0) 991 error = (*(nfsrv4_ops0[op]))(nd, 992 isdgram, vp, p, &vpnes); 993 if (nfsv4_opflag[op].modifyfs) 994 vn_finished_write(temp_mp); 995 } else { 996 error = (*(nfsrv4_ops0[op]))(nd, isdgram, 997 NULL, p, &vpnes); 998 } 999 } 1000 } 1001 if (error) { 1002 if (error == EBADRPC || error == NFSERR_BADXDR) { 1003 nd->nd_repstat = NFSERR_BADXDR; 1004 } else { 1005 nd->nd_repstat = error; 1006 printf("nfsv4 comperr0=%d\n", error); 1007 } 1008 error = 0; 1009 } 1010 retops++; 1011 if (nd->nd_repstat) { 1012 *repp = nfsd_errmap(nd); 1013 break; 1014 } else { 1015 *repp = 0; /* NFS4_OK */ 1016 } 1017 } 1018 nfsmout: 1019 if (error) { 1020 if (error == EBADRPC || error == NFSERR_BADXDR) 1021 nd->nd_repstat = NFSERR_BADXDR; 1022 else 1023 printf("nfsv4 comperr1=%d\n", error); 1024 } 1025 if (taglen == -1) { 1026 NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 1027 *tl++ = 0; 1028 *tl = 0; 1029 } else { 1030 *retopsp = txdr_unsigned(retops); 1031 } 1032 if (vp) 1033 vrele(vp); 1034 if (savevp) 1035 vrele(savevp); 1036 NFSLOCKV4ROOTMUTEX(); 1037 nfsv4_relref(&nfsv4rootfs_lock); 1038 NFSUNLOCKV4ROOTMUTEX(); 1039 1040 NFSEXITCODE2(0, nd); 1041 } 1042