nfs_nfsdsocket.c revision 216893
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 216893 2011-01-02 19:58:39Z rmacklem $"); 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, lktype; 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 if (nd->nd_procnum == NFSPROC_READ || 384 nd->nd_procnum == NFSPROC_READDIR || 385 nd->nd_procnum == NFSPROC_READLINK || 386 nd->nd_procnum == NFSPROC_GETATTR || 387 nd->nd_procnum == NFSPROC_ACCESS) 388 lktype = LK_SHARED; 389 else 390 lktype = LK_EXCLUSIVE; 391 nes.nes_vfslocked = 0; 392 if (nd->nd_flag & ND_PUBLOOKUP) 393 nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes, 394 &mp, nfs_writerpc[nd->nd_procnum], p); 395 else 396 nfsd_fhtovp(nd, &fh, lktype, &vp, &nes, 397 &mp, nfs_writerpc[nd->nd_procnum], p); 398 if (nd->nd_repstat == NFSERR_PROGNOTV4) 399 return; 400 } 401 } 402 403 /* 404 * For V2 and 3, set the ND_SAVEREPLY flag for the recent request 405 * cache, as required. 406 * For V4, nfsrvd_compound() does this. 407 */ 408 if (!(nd->nd_flag & ND_NFSV4) && nfsrv_nonidempotent[nd->nd_procnum]) 409 nd->nd_flag |= ND_SAVEREPLY; 410 411 nfsrvd_rephead(nd); 412 /* 413 * If nd_repstat is non-zero, just fill in the reply status 414 * to complete the RPC reply for V2. Otherwise, you must do 415 * the RPC. 416 */ 417 if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) { 418 *nd->nd_errp = nfsd_errmap(nd); 419 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]); 420 if (mp != NULL) { 421 if (nfs_writerpc[nd->nd_procnum]) 422 NFS_ENDWRITE(mp); 423 if (nes.nes_vfslocked) 424 nfsvno_unlockvfs(mp); 425 } 426 return; 427 } 428 429 /* 430 * Now the procedure can be performed. For V4, nfsrvd_compound() 431 * works through the sub-rpcs, otherwise just call the procedure. 432 * The procedures are in three groups with different arguments. 433 * The group is indicated by the value in nfs_retfh[]. 434 */ 435 if (nd->nd_flag & ND_NFSV4) { 436 nfsrvd_compound(nd, isdgram, p); 437 } else { 438 if (nfs_retfh[nd->nd_procnum] == 1) { 439 if (vp) 440 NFSVOPUNLOCK(vp, 0, p); 441 error = (*(nfsrv3_procs1[nd->nd_procnum]))(nd, isdgram, 442 vp, NULL, (fhandle_t *)fh.nfsrvfh_data, p, &nes); 443 } else if (nfs_retfh[nd->nd_procnum] == 2) { 444 error = (*(nfsrv3_procs2[nd->nd_procnum]))(nd, isdgram, 445 vp, NULL, p, &nes, NULL); 446 } else { 447 error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram, 448 vp, p, &nes); 449 } 450 if (mp) { 451 if (nfs_writerpc[nd->nd_procnum]) 452 NFS_ENDWRITE(mp); 453 if (nes.nes_vfslocked) 454 nfsvno_unlockvfs(mp); 455 } 456 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]); 457 } 458 if (error) { 459 if (error != EBADRPC) 460 printf("nfs dorpc err2=%d\n", error); 461 nd->nd_repstat = NFSERR_GARBAGE; 462 } 463 *nd->nd_errp = nfsd_errmap(nd); 464 465 /* 466 * Don't cache certain reply status values. 467 */ 468 if (nd->nd_repstat && (nd->nd_flag & ND_SAVEREPLY) && 469 (nd->nd_repstat == NFSERR_GARBAGE || 470 nd->nd_repstat == NFSERR_BADXDR || 471 nd->nd_repstat == NFSERR_MOVED || 472 nd->nd_repstat == NFSERR_DELAY || 473 nd->nd_repstat == NFSERR_BADSEQID || 474 nd->nd_repstat == NFSERR_RESOURCE || 475 nd->nd_repstat == NFSERR_SERVERFAULT || 476 nd->nd_repstat == NFSERR_STALECLIENTID || 477 nd->nd_repstat == NFSERR_STALESTATEID || 478 nd->nd_repstat == NFSERR_OLDSTATEID || 479 nd->nd_repstat == NFSERR_BADSTATEID || 480 nd->nd_repstat == NFSERR_GRACE || 481 nd->nd_repstat == NFSERR_NOGRACE)) 482 nd->nd_flag &= ~ND_SAVEREPLY; 483} 484 485/* 486 * Breaks down a compound RPC request and calls the server routines for 487 * the subprocedures. 488 * Some suboperations are performed directly here to simplify file handle<--> 489 * vnode pointer handling. 490 */ 491static void 492nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, 493 NFSPROC_T *p) 494{ 495 int i, op; 496 u_int32_t *tl; 497 struct nfsclient *clp, *nclp; 498 int numops, taglen = -1, error = 0, igotlock; 499 u_int32_t minorvers, retops = 0, *retopsp = NULL, *repp; 500 u_char tag[NFSV4_SMALLSTR + 1], *tagstr; 501 vnode_t vp, nvp, savevp; 502 struct nfsrvfh fh; 503 mount_t mp, savemp; 504 struct ucred *credanon; 505 struct nfsexstuff nes, vpnes, savevpnes; 506 static u_int64_t compref = 0; 507 508 NFSVNO_EXINIT(&vpnes); 509 NFSVNO_EXINIT(&savevpnes); 510 /* 511 * Put the seq# of the current compound RPC in nfsrv_descript. 512 * (This is used by nfsrv_checkgetattr(), to see if the write 513 * delegation was created by the same compound RPC as the one 514 * with that Getattr in it.) 515 * Don't worry about the 64bit number wrapping around. It ain't 516 * gonna happen before this server gets shut down/rebooted. 517 */ 518 nd->nd_compref = compref++; 519 520 /* 521 * Check for and optionally get a lock on the root. This lock means that 522 * no nfsd will be fiddling with the V4 file system and state stuff. It 523 * is required when the V4 root is being changed, the stable storage 524 * restart file is being updated, or callbacks are being done. 525 * When any of the nfsd are processing an NFSv4 compound RPC, they must 526 * either hold a reference count (nfs_usecnt) or the lock. When 527 * nfsrv_unlock() is called to release the lock, it can optionally 528 * also get a reference count, which saves the need for a call to 529 * nfsrv_getref() after nfsrv_unlock(). 530 */ 531 /* 532 * First, check to see if we need to wait for an update lock. 533 */ 534 igotlock = 0; 535 NFSLOCKV4ROOTMUTEX(); 536 if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK) 537 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL, 538 NFSV4ROOTLOCKMUTEXPTR); 539 else 540 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 0, NULL, 541 NFSV4ROOTLOCKMUTEXPTR); 542 NFSUNLOCKV4ROOTMUTEX(); 543 if (igotlock) { 544 /* 545 * If I got the lock, I can update the stable storage file. 546 * Done when the grace period is over or a client has long 547 * since expired. 548 */ 549 nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NEEDLOCK; 550 if ((nfsrv_stablefirst.nsf_flags & 551 (NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER) 552 nfsrv_updatestable(p); 553 554 /* 555 * If at least one client has long since expired, search 556 * the client list for them, write a REVOKE record on the 557 * stable storage file and then remove them from the client 558 * list. 559 */ 560 if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) { 561 nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT; 562 for (i = 0; i < NFSCLIENTHASHSIZE; i++) { 563 LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, 564 nclp) { 565 if (clp->lc_flags & LCL_EXPIREIT) { 566 if (!LIST_EMPTY(&clp->lc_open) || 567 !LIST_EMPTY(&clp->lc_deleg)) 568 nfsrv_writestable(clp->lc_id, 569 clp->lc_idlen, NFSNST_REVOKE, p); 570 nfsrv_cleanclient(clp, p); 571 nfsrv_freedeleglist(&clp->lc_deleg); 572 nfsrv_freedeleglist(&clp->lc_olddeleg); 573 LIST_REMOVE(clp, lc_hash); 574 nfsrv_zapclient(clp, p); 575 } 576 } 577 } 578 } 579 NFSLOCKV4ROOTMUTEX(); 580 nfsv4_unlock(&nfsv4rootfs_lock, 1); 581 NFSUNLOCKV4ROOTMUTEX(); 582 } else { 583 /* 584 * If we didn't get the lock, we need to get a refcnt, 585 * which also checks for and waits for the lock. 586 */ 587 NFSLOCKV4ROOTMUTEX(); 588 nfsv4_getref(&nfsv4rootfs_lock, NULL, 589 NFSV4ROOTLOCKMUTEXPTR); 590 NFSUNLOCKV4ROOTMUTEX(); 591 } 592 593 /* 594 * If flagged, search for open owners that haven't had any opens 595 * for a long time. 596 */ 597 if (nfsrv_stablefirst.nsf_flags & NFSNSF_NOOPENS) { 598 nfsrv_throwawayopens(p); 599 } 600 601 savevp = vp = NULL; 602 savevpnes.nes_vfslocked = vpnes.nes_vfslocked = 0; 603 savemp = mp = NULL; 604 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 605 taglen = fxdr_unsigned(int, *tl); 606 if (taglen < 0) { 607 error = EBADRPC; 608 goto nfsmout; 609 } 610 if (taglen <= NFSV4_SMALLSTR) 611 tagstr = tag; 612 else 613 tagstr = malloc(taglen + 1, M_TEMP, M_WAITOK); 614 error = nfsrv_mtostr(nd, tagstr, taglen); 615 if (error) { 616 if (taglen > NFSV4_SMALLSTR) 617 free(tagstr, M_TEMP); 618 taglen = -1; 619 goto nfsmout; 620 } 621 (void) nfsm_strtom(nd, tag, taglen); 622 if (taglen > NFSV4_SMALLSTR) { 623 free(tagstr, M_TEMP); 624 } 625 NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED); 626 NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 627 minorvers = fxdr_unsigned(u_int32_t, *tl++); 628 if (minorvers != NFSV4_MINORVERSION) 629 nd->nd_repstat = NFSERR_MINORVERMISMATCH; 630 if (nd->nd_repstat) 631 numops = 0; 632 else 633 numops = fxdr_unsigned(int, *tl); 634 /* 635 * Loop around doing the sub ops. 636 * vp - is an unlocked vnode pointer for the CFH 637 * savevp - is an unlocked vnode pointer for the SAVEDFH 638 * (at some future date, it might turn out to be more appropriate 639 * to keep the file handles instead of vnode pointers?) 640 * savevpnes and vpnes - are the export flags for the above. 641 */ 642 for (i = 0; i < numops; i++) { 643 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 644 NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED); 645 *repp = *tl; 646 op = fxdr_unsigned(int, *tl); 647 if (op < NFSV4OP_ACCESS || op >= NFSV4OP_NOPS) { 648 nd->nd_repstat = NFSERR_OPILLEGAL; 649 *repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL); 650 *repp = nfsd_errmap(nd); 651 retops++; 652 break; 653 } else { 654 repp++; 655 } 656 657 /* 658 * Check for a referral on the current FH and, if so, return 659 * NFSERR_MOVED for all ops that allow it, except Getattr. 660 */ 661 if (vp != NULL && op != NFSV4OP_GETATTR && 662 nfsv4root_getreferral(vp, NULL, 0) != NULL && 663 nfsrv_errmoved(op)) { 664 nd->nd_repstat = NFSERR_MOVED; 665 *repp = nfsd_errmap(nd); 666 retops++; 667 break; 668 } 669 670 nd->nd_procnum = op; 671 /* 672 * If over flood level, reply NFSERR_RESOURCE, if at the first 673 * Op. (Since a client recovery from NFSERR_RESOURCE can get 674 * really nasty for certain Op sequences, I'll play it safe 675 * and only return the error at the beginning.) The cache 676 * will still function over flood level, but uses lots of 677 * mbufs.) 678 * If nfsrv_mallocmget_limit() returns True, the system is near 679 * to its limit for memory that malloc()/mget() can allocate. 680 */ 681 if (i == 0 && nd->nd_rp->rc_refcnt == 0 && 682 (nfsrv_mallocmget_limit() || 683 nfsrc_tcpsavedreplies > nfsrc_floodlevel)) { 684 if (nfsrc_tcpsavedreplies > nfsrc_floodlevel) { 685 printf("nfsd server cache flooded, try to"); 686 printf(" increase nfsrc_floodlevel\n"); 687 } 688 nd->nd_repstat = NFSERR_RESOURCE; 689 *repp = nfsd_errmap(nd); 690 if (op == NFSV4OP_SETATTR) { 691 /* 692 * Setattr replies require a bitmap. 693 * even for errors like these. 694 */ 695 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); 696 *tl = 0; 697 } 698 retops++; 699 break; 700 } 701 if (nfsv4_opflag[op].savereply) 702 nd->nd_flag |= ND_SAVEREPLY; 703 NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]); 704 switch (op) { 705 case NFSV4OP_PUTFH: 706 error = nfsrv_mtofh(nd, &fh); 707 if (error) 708 goto nfsmout; 709 if (!nd->nd_repstat) { 710 nes.nes_vfslocked = vpnes.nes_vfslocked; 711 nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes, &mp, 712 0, p); 713 } 714 /* For now, allow this for non-export FHs */ 715 if (!nd->nd_repstat) { 716 if (vp) 717 vrele(vp); 718 vp = nvp; 719 NFSVOPUNLOCK(vp, 0, p); 720 vpnes = nes; 721 } 722 break; 723 case NFSV4OP_PUTPUBFH: 724 if (nfs_pubfhset) { 725 nes.nes_vfslocked = vpnes.nes_vfslocked; 726 nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp, 727 &nes, &mp, 0, p); 728 } else { 729 nd->nd_repstat = NFSERR_NOFILEHANDLE; 730 } 731 if (!nd->nd_repstat) { 732 if (vp) 733 vrele(vp); 734 vp = nvp; 735 NFSVOPUNLOCK(vp, 0, p); 736 vpnes = nes; 737 } 738 break; 739 case NFSV4OP_PUTROOTFH: 740 if (nfs_rootfhset) { 741 nes.nes_vfslocked = vpnes.nes_vfslocked; 742 nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp, 743 &nes, &mp, 0, p); 744 if (!nd->nd_repstat) { 745 if (vp) 746 vrele(vp); 747 vp = nvp; 748 NFSVOPUNLOCK(vp, 0, p); 749 vpnes = nes; 750 } 751 } else if (nfsv4root_vp && nfsv4root_set) { 752 if (vp) { 753 if (vpnes.nes_vfslocked) 754 nfsvno_unlockvfs(mp); 755 vrele(vp); 756 } 757 vp = nfsv4root_vp; 758 VREF(vp); 759 NFSVNO_SETEXRDONLY(&vpnes); 760 vpnes.nes_vfslocked = 0; 761 mp = vnode_mount(vp); 762 } else { 763 nd->nd_repstat = NFSERR_NOFILEHANDLE; 764 } 765 break; 766 case NFSV4OP_SAVEFH: 767 if (vp && NFSVNO_EXPORTED(&vpnes)) { 768 nd->nd_repstat = 0; 769 /* If vp == savevp, a no-op */ 770 if (vp != savevp) { 771 if (savevp) 772 vrele(savevp); 773 VREF(vp); 774 savevp = vp; 775 savevpnes = vpnes; 776 savemp = mp; 777 } 778 } else { 779 nd->nd_repstat = NFSERR_NOFILEHANDLE; 780 } 781 break; 782 case NFSV4OP_RESTOREFH: 783 if (savevp) { 784 nd->nd_repstat = 0; 785 /* If vp == savevp, a no-op */ 786 if (vp != savevp) { 787 VREF(savevp); 788 if (mp == NULL || savemp == NULL) 789 panic("nfscmpmp"); 790 if (!savevpnes.nes_vfslocked && 791 vpnes.nes_vfslocked) { 792 if (mp == savemp) 793 panic("nfscmp2"); 794 nfsvno_unlockvfs(mp); 795 } else if (savevpnes.nes_vfslocked && 796 !vpnes.nes_vfslocked) { 797 if (mp == savemp) 798 panic("nfscmp3"); 799 savevpnes.nes_vfslocked = nfsvno_lockvfs(savemp); 800 } 801 vrele(vp); 802 vp = savevp; 803 vpnes = savevpnes; 804 mp = savemp; 805 } 806 } else { 807 nd->nd_repstat = NFSERR_RESTOREFH; 808 } 809 break; 810 default: 811 /* 812 * Allow a Lookup, Getattr, GetFH, Secinfo on an 813 * non-exported directory if 814 * nfs_rootfhset. Do I need to allow any other Ops? 815 * (You can only have a non-exported vpnes if 816 * nfs_rootfhset is true. See nfsd_fhtovp()) 817 * Allow AUTH_SYS to be used for file systems 818 * exported GSS only for certain Ops, to allow 819 * clients to do mounts more easily. 820 */ 821 if (nfsv4_opflag[op].needscfh && vp) { 822 if (!NFSVNO_EXPORTED(&vpnes) && 823 op != NFSV4OP_LOOKUP && 824 op != NFSV4OP_GETATTR && 825 op != NFSV4OP_GETFH && 826 op != NFSV4OP_SECINFO) 827 nd->nd_repstat = NFSERR_NOFILEHANDLE; 828 else if (nfsvno_testexp(nd, &vpnes) && 829 op != NFSV4OP_LOOKUP && 830 op != NFSV4OP_GETFH && 831 op != NFSV4OP_GETATTR && 832 op != NFSV4OP_SECINFO) 833 nd->nd_repstat = NFSERR_WRONGSEC; 834 if (nd->nd_repstat) { 835 if (op == NFSV4OP_SETATTR) { 836 /* 837 * Setattr reply requires a bitmap 838 * even for errors like these. 839 */ 840 NFSM_BUILD(tl, u_int32_t *, 841 NFSX_UNSIGNED); 842 *tl = 0; 843 } 844 break; 845 } 846 } 847 if (nfsv4_opflag[op].retfh == 1) { 848 if (!vp) { 849 nd->nd_repstat = NFSERR_NOFILEHANDLE; 850 break; 851 } 852 VREF(vp); 853 if (nfsv4_opflag[op].modifyfs) 854 NFS_STARTWRITE(NULL, &mp); 855 error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp, 856 &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes); 857 if (!error && !nd->nd_repstat) { 858 if (vfs_statfs(mp)->f_fsid.val[0] != 859 vfs_statfs(vnode_mount(nvp))->f_fsid.val[0] || 860 vfs_statfs(mp)->f_fsid.val[1] != 861 vfs_statfs(vnode_mount(nvp))->f_fsid.val[1]) { 862 if (vfs_statfs(vnode_mount(nvp))->f_fsid.val[0] == 863 NFSV4ROOT_FSID0 && 864 vfs_statfs(vnode_mount(nvp))->f_fsid.val[1] == 865 NFSV4ROOT_FSID1) { 866 if (vpnes.nes_vfslocked) { 867 nfsvno_unlockvfs(mp); 868 vpnes.nes_vfslocked = 0; 869 } 870 NFSVNO_SETEXRDONLY(&vpnes); 871 mp = vnode_mount(nvp); 872 } else { 873 nd->nd_repstat = nfsvno_checkexp(vnode_mount(nvp), 874 nd->nd_nam, &nes, &credanon); 875 if (!nd->nd_repstat) 876 nd->nd_repstat = nfsd_excred(nd, 877 &nes, credanon); 878 if (credanon != NULL) 879 crfree(credanon); 880 if (!nd->nd_repstat) { 881 if (vpnes.nes_vfslocked) 882 nfsvno_unlockvfs(mp); 883 mp = vnode_mount(nvp); 884 vpnes = nes; 885 vpnes.nes_vfslocked = 886 nfsvno_lockvfs(mp); 887 } 888 } 889 } 890 if (!nd->nd_repstat) { 891 vrele(vp); 892 vp = nvp; 893 } 894 } 895 if (nfsv4_opflag[op].modifyfs) 896 NFS_ENDWRITE(mp); 897 } else if (nfsv4_opflag[op].retfh == 2) { 898 if (vp == NULL || savevp == NULL) { 899 nd->nd_repstat = NFSERR_NOFILEHANDLE; 900 break; 901 } else if (mp != savemp) { 902 nd->nd_repstat = NFSERR_XDEV; 903 break; 904 } 905 if (nfsv4_opflag[op].modifyfs) 906 NFS_STARTWRITE(NULL, &mp); 907 if (vn_lock(savevp, LK_EXCLUSIVE) == 0) { 908 VREF(vp); 909 VREF(savevp); 910 error = (*(nfsrv4_ops2[op]))(nd, isdgram, 911 savevp, vp, p, &savevpnes, &vpnes); 912 } else 913 nd->nd_repstat = NFSERR_PERM; 914 if (nfsv4_opflag[op].modifyfs) 915 NFS_ENDWRITE(mp); 916 } else { 917 if (nfsv4_opflag[op].retfh != 0) 918 panic("nfsrvd_compound"); 919 if (nfsv4_opflag[op].needscfh) { 920 if (vp != NULL) { 921 if (nfsv4_opflag[op].modifyfs) 922 NFS_STARTWRITE(NULL, &mp); 923 if (vn_lock(vp, nfsv4_opflag[op].lktype) 924 == 0) 925 VREF(vp); 926 else 927 nd->nd_repstat = NFSERR_PERM; 928 } else { 929 nd->nd_repstat = NFSERR_NOFILEHANDLE; 930 if (op == NFSV4OP_SETATTR) { 931 /* 932 * Setattr reply requires a 933 * bitmap even for errors like 934 * these. 935 */ 936 NFSM_BUILD(tl, u_int32_t *, 937 NFSX_UNSIGNED); 938 *tl = 0; 939 } 940 break; 941 } 942 if (nd->nd_repstat == 0) 943 error = (*(nfsrv4_ops0[op]))(nd, 944 isdgram, vp, p, &vpnes); 945 if (nfsv4_opflag[op].modifyfs) 946 NFS_ENDWRITE(mp); 947 } else { 948 error = (*(nfsrv4_ops0[op]))(nd, isdgram, 949 NULL, p, &vpnes); 950 } 951 } 952 }; 953 if (error) { 954 if (error == EBADRPC || error == NFSERR_BADXDR) { 955 nd->nd_repstat = NFSERR_BADXDR; 956 } else { 957 nd->nd_repstat = error; 958 printf("nfsv4 comperr0=%d\n", error); 959 } 960 error = 0; 961 } 962 retops++; 963 if (nd->nd_repstat) { 964 *repp = nfsd_errmap(nd); 965 break; 966 } else { 967 *repp = 0; /* NFS4_OK */ 968 } 969 } 970nfsmout: 971 if (error) { 972 if (error == EBADRPC || error == NFSERR_BADXDR) 973 nd->nd_repstat = NFSERR_BADXDR; 974 else 975 printf("nfsv4 comperr1=%d\n", error); 976 } 977 if (taglen == -1) { 978 NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 979 *tl++ = 0; 980 *tl = 0; 981 } else { 982 *retopsp = txdr_unsigned(retops); 983 } 984 if (mp && vpnes.nes_vfslocked) 985 nfsvno_unlockvfs(mp); 986 if (vp) 987 vrele(vp); 988 if (savevp) 989 vrele(savevp); 990 NFSLOCKV4ROOTMUTEX(); 991 nfsv4_relref(&nfsv4rootfs_lock); 992 NFSUNLOCKV4ROOTMUTEX(); 993} 994