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