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