nfs_nfsdsocket.c revision 209120
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: head/sys/fs/nfsserver/nfs_nfsdsocket.c 209120 2010-06-13 05:24:27Z kib $"); 36 37/* 38 * Socket operations for use by the nfs server. 39 */ 40 41#ifndef APPLEKEXT 42#include <fs/nfs/nfsport.h> 43 44extern struct nfsstats newnfsstats; 45extern struct nfsrvfh nfs_pubfh, nfs_rootfh; 46extern int nfs_pubfhset, nfs_rootfhset; 47extern struct nfsv4lock nfsv4rootfs_lock; 48extern struct nfsrv_stablefirst nfsrv_stablefirst; 49extern struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE]; 50extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies; 51NFSV4ROOTLOCKMUTEX; 52NFSSTATESPINLOCK; 53vnode_t nfsv4root_vp = NULL; 54int nfsv4root_set = 0; 55 56int (*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 82int (*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 109int (*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 136int (*nfsrv4_ops0[NFSV4OP_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}; 179 180int (*nfsrv4_ops1[NFSV4OP_NOPS])(struct nfsrv_descript *, 181 int, vnode_t , vnode_t *, fhandle_t *, 182 NFSPROC_T *, struct nfsexstuff *) = { 183 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 184 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 185 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 186 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 187 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 188 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 189 nfsrvd_mknod, 190 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 191 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 192 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 193 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 194 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 195 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 196 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 197 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 198 nfsrvd_lookup, 199 nfsrvd_lookup, 200 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 201 nfsrvd_open, 202 nfsrvd_openattr, 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 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 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 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 218 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 219 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 220 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 221 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 222 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0, 223}; 224 225int (*nfsrv4_ops2[NFSV4OP_NOPS])(struct nfsrv_descript *, 226 int, vnode_t , vnode_t , NFSPROC_T *, 227 struct nfsexstuff *, struct nfsexstuff *) = { 228 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 229 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 230 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 231 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 232 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 233 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 234 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 235 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 236 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 237 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 238 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 239 nfsrvd_link, 240 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 241 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 242 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 243 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 244 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 245 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 246 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 247 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 248 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 249 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 250 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 251 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 252 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 253 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 254 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 255 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 256 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 257 nfsrvd_rename, 258 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 259 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 260 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 261 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 262 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 263 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 264 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 265 (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0, 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}; 269#endif /* !APPLEKEXT */ 270 271/* 272 * Static array that defines which nfs rpc's are nonidempotent 273 */ 274static int nfsrv_nonidempotent[NFS_V3NPROCS] = { 275 FALSE, 276 FALSE, 277 TRUE, 278 FALSE, 279 FALSE, 280 FALSE, 281 FALSE, 282 TRUE, 283 TRUE, 284 TRUE, 285 TRUE, 286 TRUE, 287 TRUE, 288 TRUE, 289 TRUE, 290 TRUE, 291 FALSE, 292 FALSE, 293 FALSE, 294 FALSE, 295 FALSE, 296 FALSE, 297}; 298 299/* 300 * This static array indicates whether or not the RPC modifies the 301 * file system. 302 */ 303static int nfs_writerpc[NFS_NPROCS] = { 0, 0, 1, 0, 0, 0, 0, 304 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 305 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; 306 307/* local functions */ 308static void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, 309 NFSPROC_T *p); 310 311 312/* 313 * This static array indicates which server procedures require the extra 314 * arguments to return the current file handle for V2, 3. 315 */ 316static int nfs_retfh[NFS_V3NPROCS] = { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 317 1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 }; 318 319extern struct nfsv4_opflag nfsv4_opflag[NFSV4OP_NOPS]; 320 321static int nfsv3to4op[NFS_V3NPROCS] = { 322 NFSPROC_NULL, 323 NFSV4OP_GETATTR, 324 NFSV4OP_SETATTR, 325 NFSV4OP_LOOKUP, 326 NFSV4OP_ACCESS, 327 NFSV4OP_READLINK, 328 NFSV4OP_READ, 329 NFSV4OP_WRITE, 330 NFSV4OP_V3CREATE, 331 NFSV4OP_MKDIR, 332 NFSV4OP_SYMLINK, 333 NFSV4OP_MKNOD, 334 NFSV4OP_REMOVE, 335 NFSV4OP_RMDIR, 336 NFSV4OP_RENAME, 337 NFSV4OP_LINK, 338 NFSV4OP_READDIR, 339 NFSV4OP_READDIRPLUS, 340 NFSV4OP_FSSTAT, 341 NFSV4OP_FSINFO, 342 NFSV4OP_PATHCONF, 343 NFSV4OP_COMMIT, 344}; 345 346/* 347 * Do an RPC. Basically, get the file handles translated to vnode pointers 348 * and then call the appropriate server routine. The server routines are 349 * split into groups, based on whether they use a file handle or file 350 * handle plus name or ... 351 * The NFS V4 Compound RPC is performed separately by nfsrvd_compound(). 352 */ 353APPLESTATIC void 354nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, 355 NFSPROC_T *p) 356{ 357 int error = 0; 358 vnode_t vp; 359 mount_t mp = NULL; 360 struct nfsrvfh fh; 361 struct nfsexstuff nes; 362 363 /* 364 * Get a locked vnode for the first file handle 365 */ 366 if (!(nd->nd_flag & ND_NFSV4)) { 367 KASSERT(nd->nd_repstat == 0, ("nfsrvd_dorpc")); 368 /* 369 * For NFSv3, if the malloc/mget allocation is near limits, 370 * return NFSERR_DELAY. 371 */ 372 if ((nd->nd_flag & ND_NFSV3) && nfsrv_mallocmget_limit()) { 373 nd->nd_repstat = NFSERR_DELAY; 374 vp = NULL; 375 } else { 376 error = nfsrv_mtofh(nd, &fh); 377 if (error) { 378 if (error != EBADRPC) 379 printf("nfs dorpc err1=%d\n", error); 380 nd->nd_repstat = NFSERR_GARBAGE; 381 return; 382 } 383 nes.nes_vfslocked = 0; 384 if (nd->nd_flag & ND_PUBLOOKUP) 385 nfsd_fhtovp(nd, &nfs_pubfh, &vp, &nes, 386 &mp, nfs_writerpc[nd->nd_procnum], p); 387 else 388 nfsd_fhtovp(nd, &fh, &vp, &nes, 389 &mp, nfs_writerpc[nd->nd_procnum], p); 390 if (nd->nd_repstat == NFSERR_PROGNOTV4) 391 return; 392 } 393 } 394 395 /* 396 * For V2 and 3, set the ND_SAVEREPLY flag for the recent request 397 * cache, as required. 398 * For V4, nfsrvd_compound() does this. 399 */ 400 if (!(nd->nd_flag & ND_NFSV4) && nfsrv_nonidempotent[nd->nd_procnum]) 401 nd->nd_flag |= ND_SAVEREPLY; 402 403 nfsrvd_rephead(nd); 404 /* 405 * If nd_repstat is non-zero, just fill in the reply status 406 * to complete the RPC reply for V2. Otherwise, you must do 407 * the RPC. 408 */ 409 if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) { 410 *nd->nd_errp = nfsd_errmap(nd); 411 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]); 412 if (mp != NULL) { 413 if (nfs_writerpc[nd->nd_procnum]) 414 NFS_ENDWRITE(mp); 415 if (nes.nes_vfslocked) 416 nfsvno_unlockvfs(mp); 417 } 418 return; 419 } 420 421 /* 422 * Now the procedure can be performed. For V4, nfsrvd_compound() 423 * works through the sub-rpcs, otherwise just call the procedure. 424 * The procedures are in three groups with different arguments. 425 * The group is indicated by the value in nfs_retfh[]. 426 */ 427 if (nd->nd_flag & ND_NFSV4) { 428 nfsrvd_compound(nd, isdgram, p); 429 } else { 430 if (nfs_retfh[nd->nd_procnum] == 1) { 431 if (vp) 432 NFSVOPUNLOCK(vp, 0, p); 433 error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram, 434 vp, NULL, (fhandle_t *)fh.nfsrvfh_data, p, &nes); 435 } else if (nfs_retfh[nd->nd_procnum] == 2) { 436 error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram, 437 vp, NULL, p, &nes, NULL); 438 } else { 439 error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram, 440 vp, p, &nes); 441 } 442 if (mp) { 443 if (nfs_writerpc[nd->nd_procnum]) 444 NFS_ENDWRITE(mp); 445 if (nes.nes_vfslocked) 446 nfsvno_unlockvfs(mp); 447 } 448 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]); 449 } 450 if (error) { 451 if (error != EBADRPC) 452 printf("nfs dorpc err2=%d\n", error); 453 nd->nd_repstat = NFSERR_GARBAGE; 454 } 455 *nd->nd_errp = nfsd_errmap(nd); 456 457 /* 458 * Don't cache certain reply status values. 459 */ 460 if (nd->nd_repstat && (nd->nd_flag & ND_SAVEREPLY) && 461 (nd->nd_repstat == NFSERR_GARBAGE || 462 nd->nd_repstat == NFSERR_BADXDR || 463 nd->nd_repstat == NFSERR_MOVED || 464 nd->nd_repstat == NFSERR_DELAY || 465 nd->nd_repstat == NFSERR_BADSEQID || 466 nd->nd_repstat == NFSERR_RESOURCE || 467 nd->nd_repstat == NFSERR_SERVERFAULT || 468 nd->nd_repstat == NFSERR_STALECLIENTID || 469 nd->nd_repstat == NFSERR_STALESTATEID || 470 nd->nd_repstat == NFSERR_OLDSTATEID || 471 nd->nd_repstat == NFSERR_BADSTATEID || 472 nd->nd_repstat == NFSERR_GRACE || 473 nd->nd_repstat == NFSERR_NOGRACE)) 474 nd->nd_flag &= ~ND_SAVEREPLY; 475} 476 477/* 478 * Breaks down a compound RPC request and calls the server routines for 479 * the subprocedures. 480 * Some suboperations are performed directly here to simplify file handle<--> 481 * vnode pointer handling. 482 */ 483static void 484nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, 485 NFSPROC_T *p) 486{ 487 int i, op; 488 u_int32_t *tl; 489 struct nfsclient *clp, *nclp; 490 int numops, taglen = -1, error = 0, igotlock; 491 u_int32_t minorvers, retops = 0, *retopsp = NULL, *repp; 492 u_char tag[NFSV4_SMALLSTR + 1], *tagstr; 493 vnode_t vp, nvp, savevp; 494 struct nfsrvfh fh; 495 mount_t mp, savemp; 496 struct ucred *credanon; 497 struct nfsexstuff nes, vpnes, savevpnes; 498 static u_int64_t compref = 0; 499 500 NFSVNO_EXINIT(&vpnes); 501 NFSVNO_EXINIT(&savevpnes); 502 /* 503 * Put the seq# of the current compound RPC in nfsrv_descript. 504 * (This is used by nfsrv_checkgetattr(), to see if the write 505 * delegation was created by the same compound RPC as the one 506 * with that Getattr in it.) 507 * Don't worry about the 64bit number wrapping around. It ain't 508 * gonna happen before this server gets shut down/rebooted. 509 */ 510 nd->nd_compref = compref++; 511 512 /* 513 * Check for and optionally get a lock on the root. This lock means that 514 * no nfsd will be fiddling with the V4 file system and state stuff. It 515 * is required when the V4 root is being changed, the stable storage 516 * restart file is being updated, or callbacks are being done. 517 * When any of the nfsd are processing an NFSv4 compound RPC, they must 518 * either hold a reference count (nfs_usecnt) or the lock. When 519 * nfsrv_unlock() is called to release the lock, it can optionally 520 * also get a reference count, which saves the need for a call to 521 * nfsrv_getref() after nfsrv_unlock(). 522 */ 523 /* 524 * First, check to see if we need to wait for an update lock. 525 */ 526 igotlock = 0; 527 NFSLOCKV4ROOTMUTEX(); 528 if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK) 529 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL, 530 NFSV4ROOTLOCKMUTEXPTR); 531 else 532 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL, 533 NFSV4ROOTLOCKMUTEXPTR); 534 NFSUNLOCKV4ROOTMUTEX(); 535 if (igotlock) { 536 NFSLOCKSTATE(); /* to avoid a race with */ 537 NFSUNLOCKSTATE(); /* nfsrv_servertimer() */ 538 /* 539 * If I got the lock, I can update the stable storage file. 540 * Done when the grace period is over or a client has long 541 * since expired. 542 */ 543 nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NEEDLOCK; 544 if ((nfsrv_stablefirst.nsf_flags & 545 (NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER) 546 nfsrv_updatestable(p); 547 548 /* 549 * If at least one client has long since expired, search 550 * the client list for them, write a REVOKE record on the 551 * stable storage file and then remove them from the client 552 * list. 553 */ 554 if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) { 555 nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT; 556 for (i = 0; i < NFSCLIENTHASHSIZE; i++) { 557 LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, 558 nclp) { 559 if (clp->lc_flags & LCL_EXPIREIT) { 560 if (!LIST_EMPTY(&clp->lc_open) || 561 !LIST_EMPTY(&clp->lc_deleg)) 562 nfsrv_writestable(clp->lc_id, 563 clp->lc_idlen, NFSNST_REVOKE, p); 564 nfsrv_cleanclient(clp, p); 565 nfsrv_freedeleglist(&clp->lc_deleg); 566 nfsrv_freedeleglist(&clp->lc_olddeleg); 567 LIST_REMOVE(clp, lc_hash); 568 nfsrv_zapclient(clp, p); 569 } 570 } 571 } 572 } 573 NFSLOCKV4ROOTMUTEX(); 574 nfsv4_unlock(&nfsv4rootfs_lock, 1); 575 NFSUNLOCKV4ROOTMUTEX(); 576 } else { 577 /* 578 * If we didn't get the lock, we need to get a refcnt, 579 * which also checks for and waits for the lock. 580 */ 581 NFSLOCKV4ROOTMUTEX(); 582 nfsv4_getref(&nfsv4rootfs_lock, NULL, 583 NFSV4ROOTLOCKMUTEXPTR); 584 NFSUNLOCKV4ROOTMUTEX(); 585 } 586 587 /* 588 * If flagged, search for open owners that haven't had any opens 589 * for a long time. 590 */ 591 if (nfsrv_stablefirst.nsf_flags & NFSNSF_NOOPENS) { 592 nfsrv_throwawayopens(p); 593 } 594 595 savevp = vp = NULL; 596 savevpnes.nes_vfslocked = vpnes.nes_vfslocked = 0; 597 savemp = mp = NULL; 598 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 599 taglen = fxdr_unsigned(int, *tl); 600 if (taglen < 0) { 601 error = EBADRPC; 602 goto nfsmout; 603 } 604 if (taglen <= NFSV4_SMALLSTR) 605 tagstr = tag; 606 else 607 tagstr = malloc(taglen + 1, M_TEMP, M_WAITOK); 608 error = nfsrv_mtostr(nd, tagstr, taglen); 609 if (error) { 610 if (taglen > NFSV4_SMALLSTR) 611 free(tagstr, M_TEMP); 612 taglen = -1; 613 goto nfsmout; 614 } 615 (void) nfsm_strtom(nd, tag, taglen); 616 if (taglen > NFSV4_SMALLSTR) { 617 free(tagstr, M_TEMP); 618 } 619 NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED); 620 NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 621 minorvers = fxdr_unsigned(u_int32_t, *tl++); 622 if (minorvers != NFSV4_MINORVERSION) 623 nd->nd_repstat = NFSERR_MINORVERMISMATCH; 624 if (nd->nd_repstat) 625 numops = 0; 626 else 627 numops = fxdr_unsigned(int, *tl); 628 /* 629 * Loop around doing the sub ops. 630 * vp - is an unlocked vnode pointer for the CFH 631 * savevp - is an unlocked vnode pointer for the SAVEDFH 632 * (at some future date, it might turn out to be more appropriate 633 * to keep the file handles instead of vnode pointers?) 634 * savevpnes and vpnes - are the export flags for the above. 635 */ 636 for (i = 0; i < numops; i++) { 637 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 638 NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED); 639 *repp = *tl; 640 op = fxdr_unsigned(int, *tl); 641 if (op < NFSV4OP_ACCESS || op >= NFSV4OP_NOPS) { 642 nd->nd_repstat = NFSERR_OPILLEGAL; 643 *repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL); 644 *repp = nfsd_errmap(nd); 645 retops++; 646 break; 647 } else { 648 repp++; 649 } 650 651 /* 652 * Check for a referral on the current FH and, if so, return 653 * NFSERR_MOVED for all ops that allow it, except Getattr. 654 */ 655 if (vp != NULL && op != NFSV4OP_GETATTR && 656 nfsv4root_getreferral(vp, NULL, 0) != NULL && 657 nfsrv_errmoved(op)) { 658 nd->nd_repstat = NFSERR_MOVED; 659 *repp = nfsd_errmap(nd); 660 retops++; 661 break; 662 } 663 664 nd->nd_procnum = op; 665 /* 666 * If over flood level, reply NFSERR_RESOURCE, if at the first 667 * Op. (Since a client recovery from NFSERR_RESOURCE can get 668 * really nasty for certain Op sequences, I'll play it safe 669 * and only return the error at the beginning.) The cache 670 * will still function over flood level, but uses lots of 671 * mbufs.) 672 * If nfsrv_mallocmget_limit() returns True, the system is near 673 * to its limit for memory that malloc()/mget() can allocate. 674 */ 675 if (i == 0 && nd->nd_rp->rc_refcnt == 0 && 676 (nfsrv_mallocmget_limit() || 677 nfsrc_tcpsavedreplies > nfsrc_floodlevel)) { 678 if (nfsrc_tcpsavedreplies > nfsrc_floodlevel) { 679 printf("nfsd server cache flooded, try to"); 680 printf(" increase nfsrc_floodlevel\n"); 681 } 682 nd->nd_repstat = NFSERR_RESOURCE; 683 *repp = nfsd_errmap(nd); 684 if (op == NFSV4OP_SETATTR) { 685 /* 686 * Setattr replies require a bitmap. 687 * even for errors like these. 688 */ 689 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); 690 *tl = 0; 691 } 692 retops++; 693 break; 694 } 695 if (nfsv4_opflag[op].savereply) 696 nd->nd_flag |= ND_SAVEREPLY; 697 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]); 698 switch (op) { 699 case NFSV4OP_PUTFH: 700 error = nfsrv_mtofh(nd, &fh); 701 if (error) 702 goto nfsmout; 703 if (!nd->nd_repstat) { 704 nes.nes_vfslocked = vpnes.nes_vfslocked; 705 nfsd_fhtovp(nd, &fh, &nvp, &nes, &mp, 706 0, p); 707 } 708 /* For now, allow this for non-export FHs */ 709 if (!nd->nd_repstat) { 710 if (vp) 711 vrele(vp); 712 vp = nvp; 713 NFSVOPUNLOCK(vp, 0, p); 714 vpnes = nes; 715 } 716 break; 717 case NFSV4OP_PUTPUBFH: 718 if (nfs_pubfhset) { 719 nes.nes_vfslocked = vpnes.nes_vfslocked; 720 nfsd_fhtovp(nd, &nfs_pubfh, &nvp, 721 &nes, &mp, 0, p); 722 } else { 723 nd->nd_repstat = NFSERR_NOFILEHANDLE; 724 } 725 if (!nd->nd_repstat) { 726 if (vp) 727 vrele(vp); 728 vp = nvp; 729 NFSVOPUNLOCK(vp, 0, p); 730 vpnes = nes; 731 } 732 break; 733 case NFSV4OP_PUTROOTFH: 734 if (nfs_rootfhset) { 735 nes.nes_vfslocked = vpnes.nes_vfslocked; 736 nfsd_fhtovp(nd, &nfs_rootfh, &nvp, 737 &nes, &mp, 0, p); 738 if (!nd->nd_repstat) { 739 if (vp) 740 vrele(vp); 741 vp = nvp; 742 NFSVOPUNLOCK(vp, 0, p); 743 vpnes = nes; 744 } 745 } else if (nfsv4root_vp && nfsv4root_set) { 746 if (vp) { 747 if (vpnes.nes_vfslocked) 748 nfsvno_unlockvfs(mp); 749 vrele(vp); 750 } 751 vp = nfsv4root_vp; 752 VREF(vp); 753 NFSVNO_SETEXRDONLY(&vpnes); 754 vpnes.nes_vfslocked = 0; 755 mp = vnode_mount(vp); 756 } else { 757 nd->nd_repstat = NFSERR_NOFILEHANDLE; 758 } 759 break; 760 case NFSV4OP_SAVEFH: 761 if (vp && NFSVNO_EXPORTED(&vpnes)) { 762 nd->nd_repstat = 0; 763 /* If vp == savevp, a no-op */ 764 if (vp != savevp) { 765 if (savevp) 766 vrele(savevp); 767 VREF(vp); 768 savevp = vp; 769 savevpnes = vpnes; 770 savemp = mp; 771 } 772 } else { 773 nd->nd_repstat = NFSERR_NOFILEHANDLE; 774 } 775 break; 776 case NFSV4OP_RESTOREFH: 777 if (savevp) { 778 nd->nd_repstat = 0; 779 /* If vp == savevp, a no-op */ 780 if (vp != savevp) { 781 VREF(savevp); 782 if (mp == NULL || savemp == NULL) 783 panic("nfscmpmp"); 784 if (!savevpnes.nes_vfslocked && 785 vpnes.nes_vfslocked) { 786 if (mp == savemp) 787 panic("nfscmp2"); 788 nfsvno_unlockvfs(mp); 789 } else if (savevpnes.nes_vfslocked && 790 !vpnes.nes_vfslocked) { 791 if (mp == savemp) 792 panic("nfscmp3"); 793 savevpnes.nes_vfslocked = nfsvno_lockvfs(savemp); 794 } 795 vrele(vp); 796 vp = savevp; 797 vpnes = savevpnes; 798 mp = savemp; 799 } 800 } else { 801 nd->nd_repstat = NFSERR_RESTOREFH; 802 } 803 break; 804 default: 805 /* 806 * Allow a Lookup, Getattr, GetFH, Secinfo on an 807 * non-exported directory if 808 * nfs_rootfhset. Do I need to allow any other Ops? 809 * (You can only have a non-exported vpnes if 810 * nfs_rootfhset is true. See nfsd_fhtovp()) 811 * Allow AUTH_SYS to be used for file systems 812 * exported GSS only for certain Ops, to allow 813 * clients to do mounts more easily. 814 */ 815 if (nfsv4_opflag[op].needscfh && vp) { 816 if (!NFSVNO_EXPORTED(&vpnes) && 817 op != NFSV4OP_LOOKUP && 818 op != NFSV4OP_GETATTR && 819 op != NFSV4OP_GETFH && 820 op != NFSV4OP_SECINFO) 821 nd->nd_repstat = NFSERR_NOFILEHANDLE; 822 else if (nfsvno_testexp(nd, &vpnes) && 823 op != NFSV4OP_LOOKUP && 824 op != NFSV4OP_GETFH && 825 op != NFSV4OP_GETATTR && 826 op != NFSV4OP_SECINFO) 827 nd->nd_repstat = NFSERR_WRONGSEC; 828 if (nd->nd_repstat) { 829 if (op == NFSV4OP_SETATTR) { 830 /* 831 * Setattr reply requires a bitmap 832 * even for errors like these. 833 */ 834 NFSM_BUILD(tl, u_int32_t *, 835 NFSX_UNSIGNED); 836 *tl = 0; 837 } 838 break; 839 } 840 } 841 if (nfsv4_opflag[op].retfh == 1) { 842 if (!vp) { 843 nd->nd_repstat = NFSERR_NOFILEHANDLE; 844 break; 845 } 846 VREF(vp); 847 if (nfsv4_opflag[op].modifyfs) 848 NFS_STARTWRITE(NULL, &mp); 849 error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp, 850 &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes); 851 if (!error && !nd->nd_repstat) { 852 if (vfs_statfs(mp)->f_fsid.val[0] != 853 vfs_statfs(vnode_mount(nvp))->f_fsid.val[0] || 854 vfs_statfs(mp)->f_fsid.val[1] != 855 vfs_statfs(vnode_mount(nvp))->f_fsid.val[1]) { 856 if (vfs_statfs(vnode_mount(nvp))->f_fsid.val[0] == 857 NFSV4ROOT_FSID0 && 858 vfs_statfs(vnode_mount(nvp))->f_fsid.val[1] == 859 NFSV4ROOT_FSID1) { 860 if (vpnes.nes_vfslocked) { 861 nfsvno_unlockvfs(mp); 862 vpnes.nes_vfslocked = 0; 863 } 864 NFSVNO_SETEXRDONLY(&vpnes); 865 mp = vnode_mount(nvp); 866 } else { 867 nd->nd_repstat = nfsvno_checkexp(vnode_mount(nvp), 868 nd->nd_nam, &nes, &credanon); 869 if (!nd->nd_repstat) 870 nd->nd_repstat = nfsd_excred(nd, 871 &nes, credanon); 872 if (credanon != NULL) 873 crfree(credanon); 874 if (!nd->nd_repstat) { 875 if (vpnes.nes_vfslocked) 876 nfsvno_unlockvfs(mp); 877 mp = vnode_mount(nvp); 878 vpnes = nes; 879 vpnes.nes_vfslocked = 880 nfsvno_lockvfs(mp); 881 } 882 } 883 } 884 if (!nd->nd_repstat) { 885 vrele(vp); 886 vp = nvp; 887 } 888 } 889 if (nfsv4_opflag[op].modifyfs) 890 NFS_ENDWRITE(mp); 891 } else if (nfsv4_opflag[op].retfh == 2) { 892 if (vp == NULL || savevp == NULL) { 893 nd->nd_repstat = NFSERR_NOFILEHANDLE; 894 break; 895 } else if (mp != savemp) { 896 nd->nd_repstat = NFSERR_XDEV; 897 break; 898 } 899 VREF(vp); 900 VREF(savevp); 901 if (nfsv4_opflag[op].modifyfs) 902 NFS_STARTWRITE(NULL, &mp); 903 NFSVOPLOCK(savevp, LK_EXCLUSIVE | LK_RETRY, p); 904 error = (*(nfsrv4_ops2[op]))(nd, isdgram, savevp, 905 vp, p, &savevpnes, &vpnes); 906 if (nfsv4_opflag[op].modifyfs) 907 NFS_ENDWRITE(mp); 908 } else { 909 if (nfsv4_opflag[op].retfh != 0) 910 panic("nfsrvd_compound"); 911 if (nfsv4_opflag[op].needscfh) { 912 if (vp) { 913 VREF(vp); 914 if (nfsv4_opflag[op].modifyfs) 915 NFS_STARTWRITE(NULL, &mp); 916 NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, p); 917 } else { 918 nd->nd_repstat = NFSERR_NOFILEHANDLE; 919 if (op == NFSV4OP_SETATTR) { 920 /* 921 * Setattr reply requires a bitmap 922 * even for errors like these. 923 */ 924 NFSM_BUILD(tl, u_int32_t *, 925 NFSX_UNSIGNED); 926 *tl = 0; 927 } 928 break; 929 } 930 error = (*(nfsrv4_ops0[op]))(nd, isdgram, vp, 931 p, &vpnes); 932 if (nfsv4_opflag[op].modifyfs) 933 NFS_ENDWRITE(mp); 934 } else { 935 error = (*(nfsrv4_ops0[op]))(nd, isdgram, 936 NULL, p, &vpnes); 937 } 938 } 939 }; 940 if (error) { 941 if (error == EBADRPC || error == NFSERR_BADXDR) { 942 nd->nd_repstat = NFSERR_BADXDR; 943 } else { 944 nd->nd_repstat = error; 945 printf("nfsv4 comperr0=%d\n", error); 946 } 947 error = 0; 948 } 949 retops++; 950 if (nd->nd_repstat) { 951 *repp = nfsd_errmap(nd); 952 break; 953 } else { 954 *repp = 0; /* NFS4_OK */ 955 } 956 } 957nfsmout: 958 if (error) { 959 if (error == EBADRPC || error == NFSERR_BADXDR) 960 nd->nd_repstat = NFSERR_BADXDR; 961 else 962 printf("nfsv4 comperr1=%d\n", error); 963 } 964 if (taglen == -1) { 965 NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 966 *tl++ = 0; 967 *tl = 0; 968 } else { 969 *retopsp = txdr_unsigned(retops); 970 } 971 if (mp && vpnes.nes_vfslocked) 972 nfsvno_unlockvfs(mp); 973 if (vp) 974 vrele(vp); 975 if (savevp) 976 vrele(savevp); 977 NFSLOCKV4ROOTMUTEX(); 978 nfsv4_relref(&nfsv4rootfs_lock); 979 NFSUNLOCKV4ROOTMUTEX(); 980} 981