1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2009 Rick Macklem, University of Guelph 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include "opt_inet.h" 34 #include "opt_inet6.h" 35 #include <sys/extattr.h> 36 #include <fs/nfs/nfsport.h> 37 38 struct nfsrv_stablefirst nfsrv_stablefirst; 39 int nfsrv_issuedelegs = 0; 40 int nfsrv_dolocallocks = 0; 41 struct nfsv4lock nfsv4rootfs_lock; 42 time_t nfsdev_time = 0; 43 int nfsrv_layouthashsize; 44 volatile int nfsrv_layoutcnt = 0; 45 extern uint32_t nfs_srvmaxio; 46 47 extern int newnfs_numnfsd; 48 extern struct nfsstatsv1 nfsstatsv1; 49 extern int nfsrv_lease; 50 extern struct timeval nfsboottime; 51 extern u_int32_t newnfs_true, newnfs_false; 52 extern struct mtx nfsrv_dslock_mtx; 53 extern struct mtx nfsrv_recalllock_mtx; 54 extern struct mtx nfsrv_dontlistlock_mtx; 55 extern int nfsd_debuglevel; 56 extern u_int nfsrv_dsdirsize; 57 extern struct nfsdevicehead nfsrv_devidhead; 58 extern int nfsrv_doflexfile; 59 extern int nfsrv_maxpnfsmirror; 60 NFSV4ROOTLOCKMUTEX; 61 NFSSTATESPINLOCK; 62 extern struct nfsdontlisthead nfsrv_dontlisthead; 63 extern volatile int nfsrv_devidcnt; 64 extern struct nfslayouthead nfsrv_recalllisthead; 65 extern char *nfsrv_zeropnfsdat; 66 67 SYSCTL_DECL(_vfs_nfsd); 68 int nfsrv_statehashsize = NFSSTATEHASHSIZE; 69 SYSCTL_INT(_vfs_nfsd, OID_AUTO, statehashsize, CTLFLAG_RDTUN, 70 &nfsrv_statehashsize, 0, 71 "Size of state hash table set via loader.conf"); 72 73 int nfsrv_clienthashsize = NFSCLIENTHASHSIZE; 74 SYSCTL_INT(_vfs_nfsd, OID_AUTO, clienthashsize, CTLFLAG_RDTUN, 75 &nfsrv_clienthashsize, 0, 76 "Size of client hash table set via loader.conf"); 77 78 int nfsrv_lockhashsize = NFSLOCKHASHSIZE; 79 SYSCTL_INT(_vfs_nfsd, OID_AUTO, fhhashsize, CTLFLAG_RDTUN, 80 &nfsrv_lockhashsize, 0, 81 "Size of file handle hash table set via loader.conf"); 82 83 int nfsrv_sessionhashsize = NFSSESSIONHASHSIZE; 84 SYSCTL_INT(_vfs_nfsd, OID_AUTO, sessionhashsize, CTLFLAG_RDTUN, 85 &nfsrv_sessionhashsize, 0, 86 "Size of session hash table set via loader.conf"); 87 88 int nfsrv_layouthighwater = NFSLAYOUTHIGHWATER; 89 SYSCTL_INT(_vfs_nfsd, OID_AUTO, layouthighwater, CTLFLAG_RDTUN, 90 &nfsrv_layouthighwater, 0, 91 "High water mark for number of layouts set via loader.conf"); 92 93 static int nfsrv_v4statelimit = NFSRV_V4STATELIMIT; 94 SYSCTL_INT(_vfs_nfsd, OID_AUTO, v4statelimit, CTLFLAG_RWTUN, 95 &nfsrv_v4statelimit, 0, 96 "High water limit for NFSv4 opens+locks+delegations"); 97 98 static int nfsrv_writedelegifpos = 0; 99 SYSCTL_INT(_vfs_nfsd, OID_AUTO, writedelegifpos, CTLFLAG_RW, 100 &nfsrv_writedelegifpos, 0, 101 "Issue a write delegation for read opens if possible"); 102 103 static int nfsrv_allowreadforwriteopen = 1; 104 SYSCTL_INT(_vfs_nfsd, OID_AUTO, allowreadforwriteopen, CTLFLAG_RW, 105 &nfsrv_allowreadforwriteopen, 0, 106 "Allow Reads to be done with Write Access StateIDs"); 107 108 int nfsrv_pnfsatime = 0; 109 SYSCTL_INT(_vfs_nfsd, OID_AUTO, pnfsstrictatime, CTLFLAG_RW, 110 &nfsrv_pnfsatime, 0, 111 "For pNFS service, do Getattr ops to keep atime up-to-date"); 112 113 int nfsrv_flexlinuxhack = 0; 114 SYSCTL_INT(_vfs_nfsd, OID_AUTO, flexlinuxhack, CTLFLAG_RW, 115 &nfsrv_flexlinuxhack, 0, 116 "For Linux clients, hack around Flex File Layout bug"); 117 118 /* 119 * Hash lists for nfs V4. 120 */ 121 struct nfsclienthashhead *nfsclienthash; 122 struct nfslockhashhead *nfslockhash; 123 struct nfssessionhash *nfssessionhash; 124 struct nfslayouthash *nfslayouthash; 125 volatile int nfsrv_dontlistlen = 0; 126 127 static u_int32_t nfsrv_openpluslock = 0, nfsrv_delegatecnt = 0; 128 static time_t nfsrvboottime; 129 static int nfsrv_returnoldstateid = 0, nfsrv_clients = 0; 130 static int nfsrv_clienthighwater = NFSRV_CLIENTHIGHWATER; 131 static int nfsrv_nogsscallback = 0; 132 static volatile int nfsrv_writedelegcnt = 0; 133 static int nfsrv_faildscnt; 134 135 /* local functions */ 136 static void nfsrv_dumpaclient(struct nfsclient *clp, 137 struct nfsd_dumpclients *dumpp); 138 static void nfsrv_freeopenowner(struct nfsstate *stp, int cansleep, 139 NFSPROC_T *p); 140 static int nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep, 141 NFSPROC_T *p); 142 static void nfsrv_freelockowner(struct nfsstate *stp, vnode_t vp, int cansleep, 143 NFSPROC_T *p); 144 static void nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, 145 int cansleep, NFSPROC_T *p); 146 static void nfsrv_freenfslock(struct nfslock *lop); 147 static void nfsrv_freenfslockfile(struct nfslockfile *lfp); 148 static void nfsrv_freedeleg(struct nfsstate *); 149 static int nfsrv_getstate(struct nfsclient *clp, nfsv4stateid_t *stateidp, 150 u_int32_t flags, struct nfsstate **stpp); 151 static void nfsrv_getowner(struct nfsstatehead *hp, struct nfsstate *new_stp, 152 struct nfsstate **stpp); 153 static int nfsrv_getlockfh(vnode_t vp, u_short flags, 154 struct nfslockfile *new_lfp, fhandle_t *nfhp, NFSPROC_T *p); 155 static int nfsrv_getlockfile(u_short flags, struct nfslockfile **new_lfpp, 156 struct nfslockfile **lfpp, fhandle_t *nfhp, int lockit); 157 static void nfsrv_insertlock(struct nfslock *new_lop, 158 struct nfslock *insert_lop, struct nfsstate *stp, struct nfslockfile *lfp); 159 static void nfsrv_updatelock(struct nfsstate *stp, struct nfslock **new_lopp, 160 struct nfslock **other_lopp, struct nfslockfile *lfp); 161 static int nfsrv_getipnumber(u_char *cp); 162 static int nfsrv_checkrestart(nfsquad_t clientid, u_int32_t flags, 163 nfsv4stateid_t *stateidp, int specialid); 164 static int nfsrv_checkgrace(struct nfsrv_descript *nd, struct nfsclient *clp, 165 u_int32_t flags); 166 static int nfsrv_docallback(struct nfsclient *clp, int procnum, 167 nfsv4stateid_t *stateidp, int trunc, fhandle_t *fhp, 168 struct nfsvattr *nap, nfsattrbit_t *attrbitp, int laytype, NFSPROC_T *p); 169 static int nfsrv_cbcallargs(struct nfsrv_descript *nd, struct nfsclient *clp, 170 uint32_t callback, int op, const char *optag, struct nfsdsession **sepp, 171 int *slotposp); 172 static u_int32_t nfsrv_nextclientindex(void); 173 static u_int32_t nfsrv_nextstateindex(struct nfsclient *clp); 174 static void nfsrv_markstable(struct nfsclient *clp); 175 static void nfsrv_markreclaim(struct nfsclient *clp); 176 static int nfsrv_checkstable(struct nfsclient *clp); 177 static int nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, struct 178 vnode *vp, NFSPROC_T *p); 179 static int nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, 180 NFSPROC_T *p, vnode_t vp); 181 static int nfsrv_cleandeleg(vnode_t vp, struct nfslockfile *lfp, 182 struct nfsclient *clp, int *haslockp, NFSPROC_T *p); 183 static int nfsrv_notsamecredname(struct nfsrv_descript *nd, 184 struct nfsclient *clp); 185 static time_t nfsrv_leaseexpiry(void); 186 static void nfsrv_delaydelegtimeout(struct nfsstate *stp); 187 static int nfsrv_checkseqid(struct nfsrv_descript *nd, u_int32_t seqid, 188 struct nfsstate *stp, struct nfsrvcache *op); 189 static int nfsrv_nootherstate(struct nfsstate *stp); 190 static int nfsrv_locallock(vnode_t vp, struct nfslockfile *lfp, int flags, 191 uint64_t first, uint64_t end, struct nfslockconflict *cfp, NFSPROC_T *p); 192 static void nfsrv_localunlock(vnode_t vp, struct nfslockfile *lfp, 193 uint64_t init_first, uint64_t init_end, NFSPROC_T *p); 194 static int nfsrv_dolocal(vnode_t vp, struct nfslockfile *lfp, int flags, 195 int oldflags, uint64_t first, uint64_t end, struct nfslockconflict *cfp, 196 NFSPROC_T *p); 197 static void nfsrv_locallock_rollback(vnode_t vp, struct nfslockfile *lfp, 198 NFSPROC_T *p); 199 static void nfsrv_locallock_commit(struct nfslockfile *lfp, int flags, 200 uint64_t first, uint64_t end); 201 static void nfsrv_locklf(struct nfslockfile *lfp); 202 static void nfsrv_unlocklf(struct nfslockfile *lfp); 203 static struct nfsdsession *nfsrv_findsession(uint8_t *sessionid); 204 static int nfsrv_freesession(struct nfsdsession *sep, uint8_t *sessionid); 205 static int nfsv4_setcbsequence(struct nfsrv_descript *nd, struct nfsclient *clp, 206 int dont_replycache, struct nfsdsession **sepp, int *slotposp); 207 static int nfsv4_getcbsession(struct nfsclient *clp, struct nfsdsession **sepp); 208 static int nfsrv_addlayout(struct nfsrv_descript *nd, struct nfslayout **lypp, 209 nfsv4stateid_t *stateidp, char *layp, int *layoutlenp, NFSPROC_T *p); 210 static void nfsrv_freelayout(struct nfslayouthead *lhp, struct nfslayout *lyp); 211 static void nfsrv_freelayoutlist(nfsquad_t clientid); 212 static void nfsrv_freelayouts(nfsquad_t *clid, fsid_t *fs, int laytype, 213 int iomode); 214 static void nfsrv_freealllayouts(void); 215 static void nfsrv_freedevid(struct nfsdevice *ds); 216 static int nfsrv_setdsserver(char *dspathp, char *mdspathp, NFSPROC_T *p, 217 struct nfsdevice **dsp); 218 static void nfsrv_deleteds(struct nfsdevice *fndds); 219 static void nfsrv_allocdevid(struct nfsdevice *ds, char *addr, char *dnshost); 220 static void nfsrv_freealldevids(void); 221 static void nfsrv_flexlayouterr(struct nfsrv_descript *nd, uint32_t *layp, 222 int maxcnt, NFSPROC_T *p); 223 static int nfsrv_recalllayout(nfsquad_t clid, nfsv4stateid_t *stateidp, 224 fhandle_t *fhp, struct nfslayout *lyp, int changed, int laytype, 225 NFSPROC_T *p); 226 static int nfsrv_findlayout(nfsquad_t *clientidp, fhandle_t *fhp, int laytype, 227 NFSPROC_T *, struct nfslayout **lypp); 228 static int nfsrv_fndclid(nfsquad_t *clidvec, nfsquad_t clid, int clidcnt); 229 static struct nfslayout *nfsrv_filelayout(struct nfsrv_descript *nd, int iomode, 230 fhandle_t *fhp, fhandle_t *dsfhp, char *devid, fsid_t fs); 231 static struct nfslayout *nfsrv_flexlayout(struct nfsrv_descript *nd, int iomode, 232 int mirrorcnt, fhandle_t *fhp, fhandle_t *dsfhp, char *devid, fsid_t fs); 233 static int nfsrv_dontlayout(fhandle_t *fhp); 234 static int nfsrv_createdsfile(vnode_t vp, fhandle_t *fhp, struct pnfsdsfile *pf, 235 vnode_t dvp, struct nfsdevice *ds, struct ucred *cred, NFSPROC_T *p, 236 vnode_t *tvpp); 237 static struct nfsdevice *nfsrv_findmirroredds(struct nfsmount *nmp); 238 239 /* 240 * Scan the client list for a match and either return the current one, 241 * create a new entry or return an error. 242 * If returning a non-error, the clp structure must either be linked into 243 * the client list or free'd. 244 */ 245 int 246 nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp, 247 nfsquad_t *clientidp, nfsquad_t *confirmp, NFSPROC_T *p) 248 { 249 struct nfsclient *clp = NULL, *new_clp = *new_clpp; 250 int i, error = 0, ret; 251 struct nfsstate *stp, *tstp; 252 #ifdef INET 253 struct sockaddr_in *sin, *rin; 254 #endif 255 #ifdef INET6 256 struct sockaddr_in6 *sin6, *rin6; 257 #endif 258 struct nfsdsession *sep, *nsep; 259 int zapit = 0, gotit, hasstate = 0, igotlock; 260 static u_int64_t confirm_index = 0; 261 262 /* 263 * Check for state resource limit exceeded. 264 */ 265 if (nfsrv_openpluslock > nfsrv_v4statelimit) { 266 error = NFSERR_RESOURCE; 267 goto out; 268 } 269 270 if (nfsrv_issuedelegs == 0 || 271 ((nd->nd_flag & ND_GSS) != 0 && nfsrv_nogsscallback != 0)) 272 /* 273 * Don't do callbacks when delegations are disabled or 274 * for AUTH_GSS unless enabled via nfsrv_nogsscallback. 275 * If establishing a callback connection is attempted 276 * when a firewall is blocking the callback path, the 277 * server may wait too long for the connect attempt to 278 * succeed during the Open. Some clients, such as Linux, 279 * may timeout and give up on the Open before the server 280 * replies. Also, since AUTH_GSS callbacks are not 281 * yet interoperability tested, they might cause the 282 * server to crap out, if they get past the Init call to 283 * the client. 284 */ 285 new_clp->lc_program = 0; 286 287 /* Lock out other nfsd threads */ 288 NFSLOCKV4ROOTMUTEX(); 289 nfsv4_relref(&nfsv4rootfs_lock); 290 do { 291 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL, 292 NFSV4ROOTLOCKMUTEXPTR, NULL); 293 } while (!igotlock); 294 NFSUNLOCKV4ROOTMUTEX(); 295 296 /* 297 * Search for a match in the client list. 298 */ 299 gotit = i = 0; 300 while (i < nfsrv_clienthashsize && !gotit) { 301 LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) { 302 if (new_clp->lc_idlen == clp->lc_idlen && 303 !NFSBCMP(new_clp->lc_id, clp->lc_id, clp->lc_idlen)) { 304 gotit = 1; 305 break; 306 } 307 } 308 if (gotit == 0) 309 i++; 310 } 311 if (!gotit || 312 (clp->lc_flags & (LCL_NEEDSCONFIRM | LCL_ADMINREVOKED))) { 313 if ((nd->nd_flag & ND_NFSV41) != 0 && confirmp->lval[1] != 0) { 314 /* 315 * For NFSv4.1, if confirmp->lval[1] is non-zero, the 316 * client is trying to update a confirmed clientid. 317 */ 318 NFSLOCKV4ROOTMUTEX(); 319 nfsv4_unlock(&nfsv4rootfs_lock, 1); 320 NFSUNLOCKV4ROOTMUTEX(); 321 confirmp->lval[1] = 0; 322 error = NFSERR_NOENT; 323 goto out; 324 } 325 /* 326 * Get rid of the old one. 327 */ 328 if (i != nfsrv_clienthashsize) { 329 LIST_REMOVE(clp, lc_hash); 330 nfsrv_cleanclient(clp, p); 331 nfsrv_freedeleglist(&clp->lc_deleg); 332 nfsrv_freedeleglist(&clp->lc_olddeleg); 333 zapit = 1; 334 } 335 /* 336 * Add it after assigning a client id to it. 337 */ 338 new_clp->lc_flags |= LCL_NEEDSCONFIRM; 339 if ((nd->nd_flag & ND_NFSV41) != 0) { 340 confirmp->lval[0] = ++confirm_index; 341 new_clp->lc_confirm.lval[0] = confirmp->lval[0] - 1; 342 } else 343 confirmp->qval = new_clp->lc_confirm.qval = 344 ++confirm_index; 345 clientidp->lval[0] = new_clp->lc_clientid.lval[0] = 346 (u_int32_t)nfsrvboottime; 347 clientidp->lval[1] = new_clp->lc_clientid.lval[1] = 348 nfsrv_nextclientindex(); 349 new_clp->lc_stateindex = 0; 350 new_clp->lc_statemaxindex = 0; 351 new_clp->lc_prevsess = 0; 352 new_clp->lc_cbref = 0; 353 new_clp->lc_expiry = nfsrv_leaseexpiry(); 354 LIST_INIT(&new_clp->lc_open); 355 LIST_INIT(&new_clp->lc_deleg); 356 LIST_INIT(&new_clp->lc_olddeleg); 357 LIST_INIT(&new_clp->lc_session); 358 for (i = 0; i < nfsrv_statehashsize; i++) 359 LIST_INIT(&new_clp->lc_stateid[i]); 360 LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp, 361 lc_hash); 362 nfsstatsv1.srvclients++; 363 nfsrv_openpluslock++; 364 nfsrv_clients++; 365 NFSLOCKV4ROOTMUTEX(); 366 nfsv4_unlock(&nfsv4rootfs_lock, 1); 367 NFSUNLOCKV4ROOTMUTEX(); 368 if (zapit) 369 nfsrv_zapclient(clp, p); 370 *new_clpp = NULL; 371 goto out; 372 } 373 374 /* 375 * Now, handle the cases where the id is already issued. 376 */ 377 if (nfsrv_notsamecredname(nd, clp)) { 378 /* 379 * Check to see if there is expired state that should go away. 380 */ 381 if (clp->lc_expiry < NFSD_MONOSEC && 382 (!LIST_EMPTY(&clp->lc_open) || !LIST_EMPTY(&clp->lc_deleg))) { 383 nfsrv_cleanclient(clp, p); 384 nfsrv_freedeleglist(&clp->lc_deleg); 385 } 386 387 /* 388 * If there is outstanding state, then reply NFSERR_CLIDINUSE per 389 * RFC3530 Sec. 8.1.2 last para. 390 */ 391 if (!LIST_EMPTY(&clp->lc_deleg)) { 392 hasstate = 1; 393 } else if (LIST_EMPTY(&clp->lc_open)) { 394 hasstate = 0; 395 } else { 396 hasstate = 0; 397 /* Look for an Open on the OpenOwner */ 398 LIST_FOREACH(stp, &clp->lc_open, ls_list) { 399 if (!LIST_EMPTY(&stp->ls_open)) { 400 hasstate = 1; 401 break; 402 } 403 } 404 } 405 if (hasstate) { 406 /* 407 * If the uid doesn't match, return NFSERR_CLIDINUSE after 408 * filling out the correct ipaddr and portnum. 409 */ 410 switch (clp->lc_req.nr_nam->sa_family) { 411 #ifdef INET 412 case AF_INET: 413 sin = (struct sockaddr_in *)new_clp->lc_req.nr_nam; 414 rin = (struct sockaddr_in *)clp->lc_req.nr_nam; 415 sin->sin_addr.s_addr = rin->sin_addr.s_addr; 416 sin->sin_port = rin->sin_port; 417 break; 418 #endif 419 #ifdef INET6 420 case AF_INET6: 421 sin6 = (struct sockaddr_in6 *)new_clp->lc_req.nr_nam; 422 rin6 = (struct sockaddr_in6 *)clp->lc_req.nr_nam; 423 sin6->sin6_addr = rin6->sin6_addr; 424 sin6->sin6_port = rin6->sin6_port; 425 break; 426 #endif 427 } 428 NFSLOCKV4ROOTMUTEX(); 429 nfsv4_unlock(&nfsv4rootfs_lock, 1); 430 NFSUNLOCKV4ROOTMUTEX(); 431 error = NFSERR_CLIDINUSE; 432 goto out; 433 } 434 } 435 436 if (NFSBCMP(new_clp->lc_verf, clp->lc_verf, NFSX_VERF)) { 437 /* 438 * If the verifier has changed, the client has rebooted 439 * and a new client id is issued. The old state info 440 * can be thrown away once the SETCLIENTID_CONFIRM occurs. 441 */ 442 LIST_REMOVE(clp, lc_hash); 443 444 /* Get rid of all sessions on this clientid. */ 445 LIST_FOREACH_SAFE(sep, &clp->lc_session, sess_list, nsep) { 446 ret = nfsrv_freesession(sep, NULL); 447 if (ret != 0) 448 printf("nfsrv_setclient: verifier changed free" 449 " session failed=%d\n", ret); 450 } 451 452 new_clp->lc_flags |= LCL_NEEDSCONFIRM; 453 if ((nd->nd_flag & ND_NFSV41) != 0) { 454 confirmp->lval[0] = ++confirm_index; 455 new_clp->lc_confirm.lval[0] = confirmp->lval[0] - 1; 456 } else 457 confirmp->qval = new_clp->lc_confirm.qval = 458 ++confirm_index; 459 clientidp->lval[0] = new_clp->lc_clientid.lval[0] = 460 nfsrvboottime; 461 clientidp->lval[1] = new_clp->lc_clientid.lval[1] = 462 nfsrv_nextclientindex(); 463 new_clp->lc_stateindex = 0; 464 new_clp->lc_statemaxindex = 0; 465 new_clp->lc_prevsess = 0; 466 new_clp->lc_cbref = 0; 467 new_clp->lc_expiry = nfsrv_leaseexpiry(); 468 469 /* 470 * Save the state until confirmed. 471 */ 472 LIST_NEWHEAD(&new_clp->lc_open, &clp->lc_open, ls_list); 473 LIST_FOREACH(tstp, &new_clp->lc_open, ls_list) 474 tstp->ls_clp = new_clp; 475 LIST_NEWHEAD(&new_clp->lc_deleg, &clp->lc_deleg, ls_list); 476 LIST_FOREACH(tstp, &new_clp->lc_deleg, ls_list) 477 tstp->ls_clp = new_clp; 478 LIST_NEWHEAD(&new_clp->lc_olddeleg, &clp->lc_olddeleg, 479 ls_list); 480 LIST_FOREACH(tstp, &new_clp->lc_olddeleg, ls_list) 481 tstp->ls_clp = new_clp; 482 for (i = 0; i < nfsrv_statehashsize; i++) { 483 LIST_NEWHEAD(&new_clp->lc_stateid[i], 484 &clp->lc_stateid[i], ls_hash); 485 LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_hash) 486 tstp->ls_clp = new_clp; 487 } 488 LIST_INIT(&new_clp->lc_session); 489 LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp, 490 lc_hash); 491 nfsstatsv1.srvclients++; 492 nfsrv_openpluslock++; 493 nfsrv_clients++; 494 NFSLOCKV4ROOTMUTEX(); 495 nfsv4_unlock(&nfsv4rootfs_lock, 1); 496 NFSUNLOCKV4ROOTMUTEX(); 497 498 /* 499 * Must wait until any outstanding callback on the old clp 500 * completes. 501 */ 502 NFSLOCKSTATE(); 503 while (clp->lc_cbref) { 504 clp->lc_flags |= LCL_WAKEUPWANTED; 505 (void)mtx_sleep(clp, NFSSTATEMUTEXPTR, PZERO - 1, 506 "nfsd clp", 10 * hz); 507 } 508 NFSUNLOCKSTATE(); 509 nfsrv_zapclient(clp, p); 510 *new_clpp = NULL; 511 goto out; 512 } 513 514 /* For NFSv4.1, mark that we found a confirmed clientid. */ 515 if ((nd->nd_flag & ND_NFSV41) != 0) { 516 clientidp->lval[0] = clp->lc_clientid.lval[0]; 517 clientidp->lval[1] = clp->lc_clientid.lval[1]; 518 confirmp->lval[0] = 0; /* Ignored by client */ 519 confirmp->lval[1] = 1; 520 } else { 521 /* 522 * id and verifier match, so update the net address info 523 * and get rid of any existing callback authentication 524 * handle, so a new one will be acquired. 525 */ 526 LIST_REMOVE(clp, lc_hash); 527 new_clp->lc_flags |= (LCL_NEEDSCONFIRM | LCL_DONTCLEAN); 528 new_clp->lc_expiry = nfsrv_leaseexpiry(); 529 confirmp->qval = new_clp->lc_confirm.qval = ++confirm_index; 530 clientidp->lval[0] = new_clp->lc_clientid.lval[0] = 531 clp->lc_clientid.lval[0]; 532 clientidp->lval[1] = new_clp->lc_clientid.lval[1] = 533 clp->lc_clientid.lval[1]; 534 new_clp->lc_delegtime = clp->lc_delegtime; 535 new_clp->lc_stateindex = clp->lc_stateindex; 536 new_clp->lc_statemaxindex = clp->lc_statemaxindex; 537 new_clp->lc_cbref = 0; 538 LIST_NEWHEAD(&new_clp->lc_open, &clp->lc_open, ls_list); 539 LIST_FOREACH(tstp, &new_clp->lc_open, ls_list) 540 tstp->ls_clp = new_clp; 541 LIST_NEWHEAD(&new_clp->lc_deleg, &clp->lc_deleg, ls_list); 542 LIST_FOREACH(tstp, &new_clp->lc_deleg, ls_list) 543 tstp->ls_clp = new_clp; 544 LIST_NEWHEAD(&new_clp->lc_olddeleg, &clp->lc_olddeleg, ls_list); 545 LIST_FOREACH(tstp, &new_clp->lc_olddeleg, ls_list) 546 tstp->ls_clp = new_clp; 547 for (i = 0; i < nfsrv_statehashsize; i++) { 548 LIST_NEWHEAD(&new_clp->lc_stateid[i], 549 &clp->lc_stateid[i], ls_hash); 550 LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_hash) 551 tstp->ls_clp = new_clp; 552 } 553 LIST_INIT(&new_clp->lc_session); 554 LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp, 555 lc_hash); 556 nfsstatsv1.srvclients++; 557 nfsrv_openpluslock++; 558 nfsrv_clients++; 559 } 560 NFSLOCKV4ROOTMUTEX(); 561 nfsv4_unlock(&nfsv4rootfs_lock, 1); 562 NFSUNLOCKV4ROOTMUTEX(); 563 564 if ((nd->nd_flag & ND_NFSV41) == 0) { 565 /* 566 * Must wait until any outstanding callback on the old clp 567 * completes. 568 */ 569 NFSLOCKSTATE(); 570 while (clp->lc_cbref) { 571 clp->lc_flags |= LCL_WAKEUPWANTED; 572 (void)mtx_sleep(clp, NFSSTATEMUTEXPTR, PZERO - 1, 573 "nfsdclp", 10 * hz); 574 } 575 NFSUNLOCKSTATE(); 576 nfsrv_zapclient(clp, p); 577 *new_clpp = NULL; 578 } 579 580 out: 581 NFSEXITCODE2(error, nd); 582 return (error); 583 } 584 585 /* 586 * Check to see if the client id exists and optionally confirm it. 587 */ 588 int 589 nfsrv_getclient(nfsquad_t clientid, int opflags, struct nfsclient **clpp, 590 struct nfsdsession *nsep, nfsquad_t confirm, uint32_t cbprogram, 591 struct nfsrv_descript *nd, NFSPROC_T *p) 592 { 593 struct nfsclient *clp; 594 struct nfsstate *stp; 595 int i; 596 struct nfsclienthashhead *hp; 597 int error = 0, igotlock, doneok; 598 struct nfssessionhash *shp; 599 struct nfsdsession *sep; 600 uint64_t sessid[2]; 601 bool sess_replay; 602 static uint64_t next_sess = 0; 603 604 if (clpp) 605 *clpp = NULL; 606 if ((nd == NULL || (nd->nd_flag & ND_NFSV41) == 0 || 607 opflags != CLOPS_RENEW) && nfsrvboottime != clientid.lval[0]) { 608 error = NFSERR_STALECLIENTID; 609 goto out; 610 } 611 612 /* 613 * If called with opflags == CLOPS_RENEW, the State Lock is 614 * already held. Otherwise, we need to get either that or, 615 * for the case of Confirm, lock out the nfsd threads. 616 */ 617 if (opflags & CLOPS_CONFIRM) { 618 NFSLOCKV4ROOTMUTEX(); 619 nfsv4_relref(&nfsv4rootfs_lock); 620 do { 621 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL, 622 NFSV4ROOTLOCKMUTEXPTR, NULL); 623 } while (!igotlock); 624 /* 625 * Create a new sessionid here, since we need to do it where 626 * there is a mutex held to serialize update of next_sess. 627 */ 628 if ((nd->nd_flag & ND_NFSV41) != 0) { 629 sessid[0] = ++next_sess; 630 sessid[1] = clientid.qval; 631 } 632 NFSUNLOCKV4ROOTMUTEX(); 633 } else if (opflags != CLOPS_RENEW) { 634 NFSLOCKSTATE(); 635 } 636 637 /* For NFSv4.1, the clp is acquired from the associated session. */ 638 if (nd != NULL && (nd->nd_flag & ND_NFSV41) != 0 && 639 opflags == CLOPS_RENEW) { 640 clp = NULL; 641 if ((nd->nd_flag & ND_HASSEQUENCE) != 0) { 642 shp = NFSSESSIONHASH(nd->nd_sessionid); 643 NFSLOCKSESSION(shp); 644 sep = nfsrv_findsession(nd->nd_sessionid); 645 if (sep != NULL) 646 clp = sep->sess_clp; 647 NFSUNLOCKSESSION(shp); 648 } 649 } else { 650 hp = NFSCLIENTHASH(clientid); 651 LIST_FOREACH(clp, hp, lc_hash) { 652 if (clp->lc_clientid.lval[1] == clientid.lval[1]) 653 break; 654 } 655 } 656 if (clp == NULL) { 657 if (opflags & CLOPS_CONFIRM) 658 error = NFSERR_STALECLIENTID; 659 else 660 error = NFSERR_EXPIRED; 661 } else if (clp->lc_flags & LCL_ADMINREVOKED) { 662 /* 663 * If marked admin revoked, just return the error. 664 */ 665 error = NFSERR_ADMINREVOKED; 666 } 667 if (error) { 668 if (opflags & CLOPS_CONFIRM) { 669 NFSLOCKV4ROOTMUTEX(); 670 nfsv4_unlock(&nfsv4rootfs_lock, 1); 671 NFSUNLOCKV4ROOTMUTEX(); 672 } else if (opflags != CLOPS_RENEW) { 673 NFSUNLOCKSTATE(); 674 } 675 goto out; 676 } 677 678 /* 679 * Perform any operations specified by the opflags. 680 */ 681 if (opflags & CLOPS_CONFIRM) { 682 sess_replay = false; 683 if ((nd->nd_flag & ND_NFSV41) != 0) { 684 /* 685 * For the case where lc_confirm.lval[0] == confirm.lval[0], 686 * use the new session, but with the previous sessionid. 687 * This is not exactly what the RFC describes, but should 688 * result in the same reply as the previous CreateSession. 689 */ 690 if (clp->lc_confirm.lval[0] + 1 == confirm.lval[0]) { 691 clp->lc_confirm.lval[0] = confirm.lval[0]; 692 clp->lc_prevsess = sessid[0]; 693 } else if (clp->lc_confirm.lval[0] == confirm.lval[0]) { 694 if (clp->lc_prevsess == 0) 695 error = NFSERR_SEQMISORDERED; 696 else 697 sessid[0] = clp->lc_prevsess; 698 sess_replay = true; 699 } else 700 error = NFSERR_SEQMISORDERED; 701 } else if ((nd->nd_flag & ND_NFSV41) == 0 && 702 clp->lc_confirm.qval != confirm.qval) 703 error = NFSERR_STALECLIENTID; 704 if (error == 0 && nfsrv_notsamecredname(nd, clp)) 705 error = NFSERR_CLIDINUSE; 706 707 if (!error) { 708 if ((clp->lc_flags & (LCL_NEEDSCONFIRM | LCL_DONTCLEAN)) == 709 LCL_NEEDSCONFIRM) { 710 /* 711 * Hang onto the delegations (as old delegations) 712 * for an Open with CLAIM_DELEGATE_PREV unless in 713 * grace, but get rid of the rest of the state. 714 */ 715 nfsrv_cleanclient(clp, p); 716 nfsrv_freedeleglist(&clp->lc_olddeleg); 717 if (nfsrv_checkgrace(nd, clp, 0)) { 718 /* In grace, so just delete delegations */ 719 nfsrv_freedeleglist(&clp->lc_deleg); 720 } else { 721 LIST_FOREACH(stp, &clp->lc_deleg, ls_list) 722 stp->ls_flags |= NFSLCK_OLDDELEG; 723 clp->lc_delegtime = NFSD_MONOSEC + 724 nfsrv_lease + NFSRV_LEASEDELTA; 725 LIST_NEWHEAD(&clp->lc_olddeleg, &clp->lc_deleg, 726 ls_list); 727 } 728 if ((nd->nd_flag & ND_NFSV41) != 0) 729 clp->lc_program = cbprogram; 730 } 731 clp->lc_flags &= ~(LCL_NEEDSCONFIRM | LCL_DONTCLEAN); 732 if (clp->lc_program) 733 clp->lc_flags |= LCL_NEEDSCBNULL; 734 /* For NFSv4.1, link the session onto the client. */ 735 if (nsep != NULL) { 736 /* Hold a reference on the xprt for a backchannel. */ 737 if ((nsep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN) 738 != 0 && !sess_replay) { 739 if (clp->lc_req.nr_client == NULL) 740 clp->lc_req.nr_client = (struct __rpc_client *) 741 clnt_bck_create(nd->nd_xprt->xp_socket, 742 cbprogram, NFSV4_CBVERS); 743 if (clp->lc_req.nr_client != NULL) { 744 SVC_ACQUIRE(nd->nd_xprt); 745 CLNT_ACQUIRE(clp->lc_req.nr_client); 746 nd->nd_xprt->xp_p2 = clp->lc_req.nr_client; 747 /* Disable idle timeout. */ 748 nd->nd_xprt->xp_idletimeout = 0; 749 nsep->sess_cbsess.nfsess_xprt = nd->nd_xprt; 750 } else 751 nsep->sess_crflags &= ~NFSV4CRSESS_CONNBACKCHAN; 752 } 753 NFSBCOPY(sessid, nsep->sess_sessionid, 754 NFSX_V4SESSIONID); 755 NFSBCOPY(sessid, nsep->sess_cbsess.nfsess_sessionid, 756 NFSX_V4SESSIONID); 757 if (!sess_replay) { 758 shp = NFSSESSIONHASH(nsep->sess_sessionid); 759 NFSLOCKSTATE(); 760 NFSLOCKSESSION(shp); 761 LIST_INSERT_HEAD(&shp->list, nsep, sess_hash); 762 LIST_INSERT_HEAD(&clp->lc_session, nsep, sess_list); 763 nsep->sess_clp = clp; 764 NFSUNLOCKSESSION(shp); 765 NFSUNLOCKSTATE(); 766 } 767 } 768 } 769 } else if (clp->lc_flags & LCL_NEEDSCONFIRM) { 770 error = NFSERR_EXPIRED; 771 } 772 773 /* 774 * If called by the Renew Op, we must check the principal. 775 */ 776 if (!error && (opflags & CLOPS_RENEWOP)) { 777 if (nfsrv_notsamecredname(nd, clp)) { 778 doneok = 0; 779 for (i = 0; i < nfsrv_statehashsize && doneok == 0; i++) { 780 LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) { 781 if ((stp->ls_flags & NFSLCK_OPEN) && 782 stp->ls_uid == nd->nd_cred->cr_uid) { 783 doneok = 1; 784 break; 785 } 786 } 787 } 788 if (!doneok) 789 error = NFSERR_ACCES; 790 } 791 if (!error && (clp->lc_flags & LCL_CBDOWN)) 792 error = NFSERR_CBPATHDOWN; 793 } 794 if ((!error || error == NFSERR_CBPATHDOWN) && 795 (opflags & CLOPS_RENEW)) { 796 clp->lc_expiry = nfsrv_leaseexpiry(); 797 } 798 if (opflags & CLOPS_CONFIRM) { 799 NFSLOCKV4ROOTMUTEX(); 800 nfsv4_unlock(&nfsv4rootfs_lock, 1); 801 NFSUNLOCKV4ROOTMUTEX(); 802 } else if (opflags != CLOPS_RENEW) { 803 NFSUNLOCKSTATE(); 804 } 805 if (clpp) 806 *clpp = clp; 807 808 out: 809 NFSEXITCODE2(error, nd); 810 return (error); 811 } 812 813 /* 814 * Perform the NFSv4.1 destroy clientid. 815 */ 816 int 817 nfsrv_destroyclient(nfsquad_t clientid, NFSPROC_T *p) 818 { 819 struct nfsclient *clp; 820 struct nfsclienthashhead *hp; 821 int error = 0, i, igotlock; 822 823 if (nfsrvboottime != clientid.lval[0]) { 824 error = NFSERR_STALECLIENTID; 825 goto out; 826 } 827 828 /* Lock out other nfsd threads */ 829 NFSLOCKV4ROOTMUTEX(); 830 nfsv4_relref(&nfsv4rootfs_lock); 831 do { 832 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL, 833 NFSV4ROOTLOCKMUTEXPTR, NULL); 834 } while (igotlock == 0); 835 NFSUNLOCKV4ROOTMUTEX(); 836 837 hp = NFSCLIENTHASH(clientid); 838 LIST_FOREACH(clp, hp, lc_hash) { 839 if (clp->lc_clientid.lval[1] == clientid.lval[1]) 840 break; 841 } 842 if (clp == NULL) { 843 NFSLOCKV4ROOTMUTEX(); 844 nfsv4_unlock(&nfsv4rootfs_lock, 1); 845 NFSUNLOCKV4ROOTMUTEX(); 846 /* Just return ok, since it is gone. */ 847 goto out; 848 } 849 850 /* 851 * Free up all layouts on the clientid. Should the client return the 852 * layouts? 853 */ 854 nfsrv_freelayoutlist(clientid); 855 856 /* Scan for state on the clientid. */ 857 for (i = 0; i < nfsrv_statehashsize; i++) 858 if (!LIST_EMPTY(&clp->lc_stateid[i])) { 859 NFSLOCKV4ROOTMUTEX(); 860 nfsv4_unlock(&nfsv4rootfs_lock, 1); 861 NFSUNLOCKV4ROOTMUTEX(); 862 error = NFSERR_CLIENTIDBUSY; 863 goto out; 864 } 865 if (!LIST_EMPTY(&clp->lc_session) || !LIST_EMPTY(&clp->lc_deleg)) { 866 NFSLOCKV4ROOTMUTEX(); 867 nfsv4_unlock(&nfsv4rootfs_lock, 1); 868 NFSUNLOCKV4ROOTMUTEX(); 869 error = NFSERR_CLIENTIDBUSY; 870 goto out; 871 } 872 873 /* Destroy the clientid and return ok. */ 874 nfsrv_cleanclient(clp, p); 875 nfsrv_freedeleglist(&clp->lc_deleg); 876 nfsrv_freedeleglist(&clp->lc_olddeleg); 877 LIST_REMOVE(clp, lc_hash); 878 NFSLOCKV4ROOTMUTEX(); 879 nfsv4_unlock(&nfsv4rootfs_lock, 1); 880 NFSUNLOCKV4ROOTMUTEX(); 881 nfsrv_zapclient(clp, p); 882 out: 883 NFSEXITCODE2(error, nd); 884 return (error); 885 } 886 887 /* 888 * Called from the new nfssvc syscall to admin revoke a clientid. 889 * Returns 0 for success, error otherwise. 890 */ 891 int 892 nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p) 893 { 894 struct nfsclient *clp = NULL; 895 int i, error = 0; 896 int gotit, igotlock; 897 898 /* 899 * First, lock out the nfsd so that state won't change while the 900 * revocation record is being written to the stable storage restart 901 * file. 902 */ 903 NFSLOCKV4ROOTMUTEX(); 904 do { 905 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL, 906 NFSV4ROOTLOCKMUTEXPTR, NULL); 907 } while (!igotlock); 908 NFSUNLOCKV4ROOTMUTEX(); 909 910 /* 911 * Search for a match in the client list. 912 */ 913 gotit = i = 0; 914 while (i < nfsrv_clienthashsize && !gotit) { 915 LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) { 916 if (revokep->nclid_idlen == clp->lc_idlen && 917 !NFSBCMP(revokep->nclid_id, clp->lc_id, clp->lc_idlen)) { 918 gotit = 1; 919 break; 920 } 921 } 922 i++; 923 } 924 if (!gotit) { 925 NFSLOCKV4ROOTMUTEX(); 926 nfsv4_unlock(&nfsv4rootfs_lock, 0); 927 NFSUNLOCKV4ROOTMUTEX(); 928 error = EPERM; 929 goto out; 930 } 931 932 /* 933 * Now, write out the revocation record 934 */ 935 nfsrv_writestable(clp->lc_id, clp->lc_idlen, NFSNST_REVOKE, p); 936 nfsrv_backupstable(); 937 938 /* 939 * and clear out the state, marking the clientid revoked. 940 */ 941 clp->lc_flags &= ~LCL_CALLBACKSON; 942 clp->lc_flags |= LCL_ADMINREVOKED; 943 nfsrv_cleanclient(clp, p); 944 nfsrv_freedeleglist(&clp->lc_deleg); 945 nfsrv_freedeleglist(&clp->lc_olddeleg); 946 NFSLOCKV4ROOTMUTEX(); 947 nfsv4_unlock(&nfsv4rootfs_lock, 0); 948 NFSUNLOCKV4ROOTMUTEX(); 949 950 out: 951 NFSEXITCODE(error); 952 return (error); 953 } 954 955 /* 956 * Dump out stats for all clients. Called from nfssvc(2), that is used 957 * nfsstatsv1. 958 */ 959 void 960 nfsrv_dumpclients(struct nfsd_dumpclients *dumpp, int maxcnt) 961 { 962 struct nfsclient *clp; 963 int i = 0, cnt = 0; 964 965 /* 966 * First, get a reference on the nfsv4rootfs_lock so that an 967 * exclusive lock cannot be acquired while dumping the clients. 968 */ 969 NFSLOCKV4ROOTMUTEX(); 970 nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, NULL); 971 NFSUNLOCKV4ROOTMUTEX(); 972 NFSLOCKSTATE(); 973 /* 974 * Rattle through the client lists until done. 975 */ 976 while (i < nfsrv_clienthashsize && cnt < maxcnt) { 977 clp = LIST_FIRST(&nfsclienthash[i]); 978 while (clp != LIST_END(&nfsclienthash[i]) && cnt < maxcnt) { 979 nfsrv_dumpaclient(clp, &dumpp[cnt]); 980 cnt++; 981 clp = LIST_NEXT(clp, lc_hash); 982 } 983 i++; 984 } 985 if (cnt < maxcnt) 986 dumpp[cnt].ndcl_clid.nclid_idlen = 0; 987 NFSUNLOCKSTATE(); 988 NFSLOCKV4ROOTMUTEX(); 989 nfsv4_relref(&nfsv4rootfs_lock); 990 NFSUNLOCKV4ROOTMUTEX(); 991 } 992 993 /* 994 * Dump stats for a client. Must be called with the NFSSTATELOCK and spl'd. 995 */ 996 static void 997 nfsrv_dumpaclient(struct nfsclient *clp, struct nfsd_dumpclients *dumpp) 998 { 999 struct nfsstate *stp, *openstp, *lckownstp; 1000 struct nfslock *lop; 1001 sa_family_t af; 1002 #ifdef INET 1003 struct sockaddr_in *rin; 1004 #endif 1005 #ifdef INET6 1006 struct sockaddr_in6 *rin6; 1007 #endif 1008 1009 dumpp->ndcl_nopenowners = dumpp->ndcl_nlockowners = 0; 1010 dumpp->ndcl_nopens = dumpp->ndcl_nlocks = 0; 1011 dumpp->ndcl_ndelegs = dumpp->ndcl_nolddelegs = 0; 1012 dumpp->ndcl_flags = clp->lc_flags; 1013 dumpp->ndcl_clid.nclid_idlen = clp->lc_idlen; 1014 NFSBCOPY(clp->lc_id, dumpp->ndcl_clid.nclid_id, clp->lc_idlen); 1015 af = clp->lc_req.nr_nam->sa_family; 1016 dumpp->ndcl_addrfam = af; 1017 switch (af) { 1018 #ifdef INET 1019 case AF_INET: 1020 rin = (struct sockaddr_in *)clp->lc_req.nr_nam; 1021 dumpp->ndcl_cbaddr.sin_addr = rin->sin_addr; 1022 break; 1023 #endif 1024 #ifdef INET6 1025 case AF_INET6: 1026 rin6 = (struct sockaddr_in6 *)clp->lc_req.nr_nam; 1027 dumpp->ndcl_cbaddr.sin6_addr = rin6->sin6_addr; 1028 break; 1029 #endif 1030 } 1031 1032 /* 1033 * Now, scan the state lists and total up the opens and locks. 1034 */ 1035 LIST_FOREACH(stp, &clp->lc_open, ls_list) { 1036 dumpp->ndcl_nopenowners++; 1037 LIST_FOREACH(openstp, &stp->ls_open, ls_list) { 1038 dumpp->ndcl_nopens++; 1039 LIST_FOREACH(lckownstp, &openstp->ls_open, ls_list) { 1040 dumpp->ndcl_nlockowners++; 1041 LIST_FOREACH(lop, &lckownstp->ls_lock, lo_lckowner) { 1042 dumpp->ndcl_nlocks++; 1043 } 1044 } 1045 } 1046 } 1047 1048 /* 1049 * and the delegation lists. 1050 */ 1051 LIST_FOREACH(stp, &clp->lc_deleg, ls_list) { 1052 dumpp->ndcl_ndelegs++; 1053 } 1054 LIST_FOREACH(stp, &clp->lc_olddeleg, ls_list) { 1055 dumpp->ndcl_nolddelegs++; 1056 } 1057 } 1058 1059 /* 1060 * Dump out lock stats for a file. 1061 */ 1062 void 1063 nfsrv_dumplocks(vnode_t vp, struct nfsd_dumplocks *ldumpp, int maxcnt, 1064 NFSPROC_T *p) 1065 { 1066 struct nfsstate *stp; 1067 struct nfslock *lop; 1068 int cnt = 0; 1069 struct nfslockfile *lfp; 1070 sa_family_t af; 1071 #ifdef INET 1072 struct sockaddr_in *rin; 1073 #endif 1074 #ifdef INET6 1075 struct sockaddr_in6 *rin6; 1076 #endif 1077 int ret; 1078 fhandle_t nfh; 1079 1080 ret = nfsrv_getlockfh(vp, 0, NULL, &nfh, p); 1081 /* 1082 * First, get a reference on the nfsv4rootfs_lock so that an 1083 * exclusive lock on it cannot be acquired while dumping the locks. 1084 */ 1085 NFSLOCKV4ROOTMUTEX(); 1086 nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, NULL); 1087 NFSUNLOCKV4ROOTMUTEX(); 1088 NFSLOCKSTATE(); 1089 if (!ret) 1090 ret = nfsrv_getlockfile(0, NULL, &lfp, &nfh, 0); 1091 if (ret) { 1092 ldumpp[0].ndlck_clid.nclid_idlen = 0; 1093 NFSUNLOCKSTATE(); 1094 NFSLOCKV4ROOTMUTEX(); 1095 nfsv4_relref(&nfsv4rootfs_lock); 1096 NFSUNLOCKV4ROOTMUTEX(); 1097 return; 1098 } 1099 1100 /* 1101 * For each open share on file, dump it out. 1102 */ 1103 stp = LIST_FIRST(&lfp->lf_open); 1104 while (stp != LIST_END(&lfp->lf_open) && cnt < maxcnt) { 1105 ldumpp[cnt].ndlck_flags = stp->ls_flags; 1106 ldumpp[cnt].ndlck_stateid.seqid = stp->ls_stateid.seqid; 1107 ldumpp[cnt].ndlck_stateid.other[0] = stp->ls_stateid.other[0]; 1108 ldumpp[cnt].ndlck_stateid.other[1] = stp->ls_stateid.other[1]; 1109 ldumpp[cnt].ndlck_stateid.other[2] = stp->ls_stateid.other[2]; 1110 ldumpp[cnt].ndlck_owner.nclid_idlen = 1111 stp->ls_openowner->ls_ownerlen; 1112 NFSBCOPY(stp->ls_openowner->ls_owner, 1113 ldumpp[cnt].ndlck_owner.nclid_id, 1114 stp->ls_openowner->ls_ownerlen); 1115 ldumpp[cnt].ndlck_clid.nclid_idlen = stp->ls_clp->lc_idlen; 1116 NFSBCOPY(stp->ls_clp->lc_id, ldumpp[cnt].ndlck_clid.nclid_id, 1117 stp->ls_clp->lc_idlen); 1118 af = stp->ls_clp->lc_req.nr_nam->sa_family; 1119 ldumpp[cnt].ndlck_addrfam = af; 1120 switch (af) { 1121 #ifdef INET 1122 case AF_INET: 1123 rin = (struct sockaddr_in *)stp->ls_clp->lc_req.nr_nam; 1124 ldumpp[cnt].ndlck_cbaddr.sin_addr = rin->sin_addr; 1125 break; 1126 #endif 1127 #ifdef INET6 1128 case AF_INET6: 1129 rin6 = (struct sockaddr_in6 *) 1130 stp->ls_clp->lc_req.nr_nam; 1131 ldumpp[cnt].ndlck_cbaddr.sin6_addr = rin6->sin6_addr; 1132 break; 1133 #endif 1134 } 1135 stp = LIST_NEXT(stp, ls_file); 1136 cnt++; 1137 } 1138 1139 /* 1140 * and all locks. 1141 */ 1142 lop = LIST_FIRST(&lfp->lf_lock); 1143 while (lop != LIST_END(&lfp->lf_lock) && cnt < maxcnt) { 1144 stp = lop->lo_stp; 1145 ldumpp[cnt].ndlck_flags = lop->lo_flags; 1146 ldumpp[cnt].ndlck_first = lop->lo_first; 1147 ldumpp[cnt].ndlck_end = lop->lo_end; 1148 ldumpp[cnt].ndlck_stateid.seqid = stp->ls_stateid.seqid; 1149 ldumpp[cnt].ndlck_stateid.other[0] = stp->ls_stateid.other[0]; 1150 ldumpp[cnt].ndlck_stateid.other[1] = stp->ls_stateid.other[1]; 1151 ldumpp[cnt].ndlck_stateid.other[2] = stp->ls_stateid.other[2]; 1152 ldumpp[cnt].ndlck_owner.nclid_idlen = stp->ls_ownerlen; 1153 NFSBCOPY(stp->ls_owner, ldumpp[cnt].ndlck_owner.nclid_id, 1154 stp->ls_ownerlen); 1155 ldumpp[cnt].ndlck_clid.nclid_idlen = stp->ls_clp->lc_idlen; 1156 NFSBCOPY(stp->ls_clp->lc_id, ldumpp[cnt].ndlck_clid.nclid_id, 1157 stp->ls_clp->lc_idlen); 1158 af = stp->ls_clp->lc_req.nr_nam->sa_family; 1159 ldumpp[cnt].ndlck_addrfam = af; 1160 switch (af) { 1161 #ifdef INET 1162 case AF_INET: 1163 rin = (struct sockaddr_in *)stp->ls_clp->lc_req.nr_nam; 1164 ldumpp[cnt].ndlck_cbaddr.sin_addr = rin->sin_addr; 1165 break; 1166 #endif 1167 #ifdef INET6 1168 case AF_INET6: 1169 rin6 = (struct sockaddr_in6 *) 1170 stp->ls_clp->lc_req.nr_nam; 1171 ldumpp[cnt].ndlck_cbaddr.sin6_addr = rin6->sin6_addr; 1172 break; 1173 #endif 1174 } 1175 lop = LIST_NEXT(lop, lo_lckfile); 1176 cnt++; 1177 } 1178 1179 /* 1180 * and the delegations. 1181 */ 1182 stp = LIST_FIRST(&lfp->lf_deleg); 1183 while (stp != LIST_END(&lfp->lf_deleg) && cnt < maxcnt) { 1184 ldumpp[cnt].ndlck_flags = stp->ls_flags; 1185 ldumpp[cnt].ndlck_stateid.seqid = stp->ls_stateid.seqid; 1186 ldumpp[cnt].ndlck_stateid.other[0] = stp->ls_stateid.other[0]; 1187 ldumpp[cnt].ndlck_stateid.other[1] = stp->ls_stateid.other[1]; 1188 ldumpp[cnt].ndlck_stateid.other[2] = stp->ls_stateid.other[2]; 1189 ldumpp[cnt].ndlck_owner.nclid_idlen = 0; 1190 ldumpp[cnt].ndlck_clid.nclid_idlen = stp->ls_clp->lc_idlen; 1191 NFSBCOPY(stp->ls_clp->lc_id, ldumpp[cnt].ndlck_clid.nclid_id, 1192 stp->ls_clp->lc_idlen); 1193 af = stp->ls_clp->lc_req.nr_nam->sa_family; 1194 ldumpp[cnt].ndlck_addrfam = af; 1195 switch (af) { 1196 #ifdef INET 1197 case AF_INET: 1198 rin = (struct sockaddr_in *)stp->ls_clp->lc_req.nr_nam; 1199 ldumpp[cnt].ndlck_cbaddr.sin_addr = rin->sin_addr; 1200 break; 1201 #endif 1202 #ifdef INET6 1203 case AF_INET6: 1204 rin6 = (struct sockaddr_in6 *) 1205 stp->ls_clp->lc_req.nr_nam; 1206 ldumpp[cnt].ndlck_cbaddr.sin6_addr = rin6->sin6_addr; 1207 break; 1208 #endif 1209 } 1210 stp = LIST_NEXT(stp, ls_file); 1211 cnt++; 1212 } 1213 1214 /* 1215 * If list isn't full, mark end of list by setting the client name 1216 * to zero length. 1217 */ 1218 if (cnt < maxcnt) 1219 ldumpp[cnt].ndlck_clid.nclid_idlen = 0; 1220 NFSUNLOCKSTATE(); 1221 NFSLOCKV4ROOTMUTEX(); 1222 nfsv4_relref(&nfsv4rootfs_lock); 1223 NFSUNLOCKV4ROOTMUTEX(); 1224 } 1225 1226 /* 1227 * Server timer routine. It can scan any linked list, so long 1228 * as it holds the spin/mutex lock and there is no exclusive lock on 1229 * nfsv4rootfs_lock. 1230 * (For OpenBSD, a kthread is ok. For FreeBSD, I think it is ok 1231 * to do this from a callout, since the spin locks work. For 1232 * Darwin, I'm not sure what will work correctly yet.) 1233 * Should be called once per second. 1234 */ 1235 void 1236 nfsrv_servertimer(void) 1237 { 1238 struct nfsclient *clp, *nclp; 1239 struct nfsstate *stp, *nstp; 1240 int got_ref, i; 1241 1242 /* 1243 * Make sure nfsboottime is set. This is used by V3 as well 1244 * as V4. Note that nfsboottime is not nfsrvboottime, which is 1245 * only used by the V4 server for leases. 1246 */ 1247 if (nfsboottime.tv_sec == 0) 1248 NFSSETBOOTTIME(nfsboottime); 1249 1250 /* 1251 * If server hasn't started yet, just return. 1252 */ 1253 NFSLOCKSTATE(); 1254 if (nfsrv_stablefirst.nsf_eograce == 0) { 1255 NFSUNLOCKSTATE(); 1256 return; 1257 } 1258 if (!(nfsrv_stablefirst.nsf_flags & NFSNSF_UPDATEDONE)) { 1259 if (!(nfsrv_stablefirst.nsf_flags & NFSNSF_GRACEOVER) && 1260 NFSD_MONOSEC > nfsrv_stablefirst.nsf_eograce) 1261 nfsrv_stablefirst.nsf_flags |= 1262 (NFSNSF_GRACEOVER | NFSNSF_NEEDLOCK); 1263 NFSUNLOCKSTATE(); 1264 return; 1265 } 1266 1267 /* 1268 * Try and get a reference count on the nfsv4rootfs_lock so that 1269 * no nfsd thread can acquire an exclusive lock on it before this 1270 * call is done. If it is already exclusively locked, just return. 1271 */ 1272 NFSLOCKV4ROOTMUTEX(); 1273 got_ref = nfsv4_getref_nonblock(&nfsv4rootfs_lock); 1274 NFSUNLOCKV4ROOTMUTEX(); 1275 if (got_ref == 0) { 1276 NFSUNLOCKSTATE(); 1277 return; 1278 } 1279 1280 /* 1281 * For each client... 1282 */ 1283 for (i = 0; i < nfsrv_clienthashsize; i++) { 1284 clp = LIST_FIRST(&nfsclienthash[i]); 1285 while (clp != LIST_END(&nfsclienthash[i])) { 1286 nclp = LIST_NEXT(clp, lc_hash); 1287 if (!(clp->lc_flags & LCL_EXPIREIT)) { 1288 if (((clp->lc_expiry + NFSRV_STALELEASE) < NFSD_MONOSEC 1289 && ((LIST_EMPTY(&clp->lc_deleg) 1290 && LIST_EMPTY(&clp->lc_open)) || 1291 nfsrv_clients > nfsrv_clienthighwater)) || 1292 (clp->lc_expiry + NFSRV_MOULDYLEASE) < NFSD_MONOSEC || 1293 (clp->lc_expiry < NFSD_MONOSEC && 1294 (nfsrv_openpluslock * 10 / 9) > nfsrv_v4statelimit)) { 1295 /* 1296 * Lease has expired several nfsrv_lease times ago: 1297 * PLUS 1298 * - no state is associated with it 1299 * OR 1300 * - above high water mark for number of clients 1301 * (nfsrv_clienthighwater should be large enough 1302 * that this only occurs when clients fail to 1303 * use the same nfs_client_id4.id. Maybe somewhat 1304 * higher that the maximum number of clients that 1305 * will mount this server?) 1306 * OR 1307 * Lease has expired a very long time ago 1308 * OR 1309 * Lease has expired PLUS the number of opens + locks 1310 * has exceeded 90% of capacity 1311 * 1312 * --> Mark for expiry. The actual expiry will be done 1313 * by an nfsd sometime soon. 1314 */ 1315 clp->lc_flags |= LCL_EXPIREIT; 1316 nfsrv_stablefirst.nsf_flags |= 1317 (NFSNSF_NEEDLOCK | NFSNSF_EXPIREDCLIENT); 1318 } else { 1319 /* 1320 * If there are no opens, increment no open tick cnt 1321 * If time exceeds NFSNOOPEN, mark it to be thrown away 1322 * otherwise, if there is an open, reset no open time 1323 * Hopefully, this will avoid excessive re-creation 1324 * of open owners and subsequent open confirms. 1325 */ 1326 stp = LIST_FIRST(&clp->lc_open); 1327 while (stp != LIST_END(&clp->lc_open)) { 1328 nstp = LIST_NEXT(stp, ls_list); 1329 if (LIST_EMPTY(&stp->ls_open)) { 1330 stp->ls_noopens++; 1331 if (stp->ls_noopens > NFSNOOPEN || 1332 (nfsrv_openpluslock * 2) > 1333 nfsrv_v4statelimit) 1334 nfsrv_stablefirst.nsf_flags |= 1335 NFSNSF_NOOPENS; 1336 } else { 1337 stp->ls_noopens = 0; 1338 } 1339 stp = nstp; 1340 } 1341 } 1342 } 1343 clp = nclp; 1344 } 1345 } 1346 NFSUNLOCKSTATE(); 1347 NFSLOCKV4ROOTMUTEX(); 1348 nfsv4_relref(&nfsv4rootfs_lock); 1349 NFSUNLOCKV4ROOTMUTEX(); 1350 } 1351 1352 /* 1353 * The following set of functions free up the various data structures. 1354 */ 1355 /* 1356 * Clear out all open/lock state related to this nfsclient. 1357 * Caller must hold an exclusive lock on nfsv4rootfs_lock, so that 1358 * there are no other active nfsd threads. 1359 */ 1360 void 1361 nfsrv_cleanclient(struct nfsclient *clp, NFSPROC_T *p) 1362 { 1363 struct nfsstate *stp, *nstp; 1364 struct nfsdsession *sep, *nsep; 1365 1366 LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) 1367 nfsrv_freeopenowner(stp, 1, p); 1368 if ((clp->lc_flags & LCL_ADMINREVOKED) == 0) 1369 LIST_FOREACH_SAFE(sep, &clp->lc_session, sess_list, nsep) 1370 (void)nfsrv_freesession(sep, NULL); 1371 } 1372 1373 /* 1374 * Free a client that has been cleaned. It should also already have been 1375 * removed from the lists. 1376 * (Just to be safe w.r.t. newnfs_disconnect(), call this function when 1377 * softclock interrupts are enabled.) 1378 */ 1379 void 1380 nfsrv_zapclient(struct nfsclient *clp, NFSPROC_T *p) 1381 { 1382 1383 #ifdef notyet 1384 if ((clp->lc_flags & (LCL_GSS | LCL_CALLBACKSON)) == 1385 (LCL_GSS | LCL_CALLBACKSON) && 1386 (clp->lc_hand.nfsh_flag & NFSG_COMPLETE) && 1387 clp->lc_handlelen > 0) { 1388 clp->lc_hand.nfsh_flag &= ~NFSG_COMPLETE; 1389 clp->lc_hand.nfsh_flag |= NFSG_DESTROYED; 1390 (void) nfsrv_docallback(clp, NFSV4PROC_CBNULL, 1391 NULL, 0, NULL, NULL, NULL, 0, p); 1392 } 1393 #endif 1394 newnfs_disconnect(NULL, &clp->lc_req); 1395 free(clp->lc_req.nr_nam, M_SONAME); 1396 NFSFREEMUTEX(&clp->lc_req.nr_mtx); 1397 free(clp->lc_stateid, M_NFSDCLIENT); 1398 free(clp, M_NFSDCLIENT); 1399 NFSLOCKSTATE(); 1400 nfsstatsv1.srvclients--; 1401 nfsrv_openpluslock--; 1402 nfsrv_clients--; 1403 NFSUNLOCKSTATE(); 1404 } 1405 1406 /* 1407 * Free a list of delegation state structures. 1408 * (This function will also free all nfslockfile structures that no 1409 * longer have associated state.) 1410 */ 1411 void 1412 nfsrv_freedeleglist(struct nfsstatehead *sthp) 1413 { 1414 struct nfsstate *stp, *nstp; 1415 1416 LIST_FOREACH_SAFE(stp, sthp, ls_list, nstp) { 1417 nfsrv_freedeleg(stp); 1418 } 1419 LIST_INIT(sthp); 1420 } 1421 1422 /* 1423 * Free up a delegation. 1424 */ 1425 static void 1426 nfsrv_freedeleg(struct nfsstate *stp) 1427 { 1428 struct nfslockfile *lfp; 1429 1430 LIST_REMOVE(stp, ls_hash); 1431 LIST_REMOVE(stp, ls_list); 1432 LIST_REMOVE(stp, ls_file); 1433 if ((stp->ls_flags & NFSLCK_DELEGWRITE) != 0) 1434 nfsrv_writedelegcnt--; 1435 lfp = stp->ls_lfp; 1436 if (LIST_EMPTY(&lfp->lf_open) && 1437 LIST_EMPTY(&lfp->lf_lock) && LIST_EMPTY(&lfp->lf_deleg) && 1438 LIST_EMPTY(&lfp->lf_locallock) && LIST_EMPTY(&lfp->lf_rollback) && 1439 lfp->lf_usecount == 0 && 1440 nfsv4_testlock(&lfp->lf_locallock_lck) == 0) 1441 nfsrv_freenfslockfile(lfp); 1442 free(stp, M_NFSDSTATE); 1443 nfsstatsv1.srvdelegates--; 1444 nfsrv_openpluslock--; 1445 nfsrv_delegatecnt--; 1446 } 1447 1448 /* 1449 * This function frees an open owner and all associated opens. 1450 */ 1451 static void 1452 nfsrv_freeopenowner(struct nfsstate *stp, int cansleep, NFSPROC_T *p) 1453 { 1454 struct nfsstate *nstp, *tstp; 1455 1456 LIST_REMOVE(stp, ls_list); 1457 /* 1458 * Now, free all associated opens. 1459 */ 1460 nstp = LIST_FIRST(&stp->ls_open); 1461 while (nstp != LIST_END(&stp->ls_open)) { 1462 tstp = nstp; 1463 nstp = LIST_NEXT(nstp, ls_list); 1464 (void) nfsrv_freeopen(tstp, NULL, cansleep, p); 1465 } 1466 if (stp->ls_op) 1467 nfsrvd_derefcache(stp->ls_op); 1468 free(stp, M_NFSDSTATE); 1469 nfsstatsv1.srvopenowners--; 1470 nfsrv_openpluslock--; 1471 } 1472 1473 /* 1474 * This function frees an open (nfsstate open structure) with all associated 1475 * lock_owners and locks. It also frees the nfslockfile structure iff there 1476 * are no other opens on the file. 1477 * Returns 1 if it free'd the nfslockfile, 0 otherwise. 1478 */ 1479 static int 1480 nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep, NFSPROC_T *p) 1481 { 1482 struct nfsstate *nstp, *tstp; 1483 struct nfslockfile *lfp; 1484 int ret; 1485 1486 LIST_REMOVE(stp, ls_hash); 1487 LIST_REMOVE(stp, ls_list); 1488 LIST_REMOVE(stp, ls_file); 1489 1490 lfp = stp->ls_lfp; 1491 /* 1492 * Now, free all lockowners associated with this open. 1493 */ 1494 LIST_FOREACH_SAFE(tstp, &stp->ls_open, ls_list, nstp) 1495 nfsrv_freelockowner(tstp, vp, cansleep, p); 1496 1497 /* 1498 * The nfslockfile is freed here if there are no locks 1499 * associated with the open. 1500 * If there are locks associated with the open, the 1501 * nfslockfile structure can be freed via nfsrv_freelockowner(). 1502 * Acquire the state mutex to avoid races with calls to 1503 * nfsrv_getlockfile(). 1504 */ 1505 if (cansleep != 0) 1506 NFSLOCKSTATE(); 1507 if (lfp != NULL && LIST_EMPTY(&lfp->lf_open) && 1508 LIST_EMPTY(&lfp->lf_deleg) && LIST_EMPTY(&lfp->lf_lock) && 1509 LIST_EMPTY(&lfp->lf_locallock) && LIST_EMPTY(&lfp->lf_rollback) && 1510 lfp->lf_usecount == 0 && 1511 (cansleep != 0 || nfsv4_testlock(&lfp->lf_locallock_lck) == 0)) { 1512 nfsrv_freenfslockfile(lfp); 1513 ret = 1; 1514 } else 1515 ret = 0; 1516 if (cansleep != 0) 1517 NFSUNLOCKSTATE(); 1518 free(stp, M_NFSDSTATE); 1519 nfsstatsv1.srvopens--; 1520 nfsrv_openpluslock--; 1521 return (ret); 1522 } 1523 1524 /* 1525 * Frees a lockowner and all associated locks. 1526 */ 1527 static void 1528 nfsrv_freelockowner(struct nfsstate *stp, vnode_t vp, int cansleep, 1529 NFSPROC_T *p) 1530 { 1531 1532 LIST_REMOVE(stp, ls_hash); 1533 LIST_REMOVE(stp, ls_list); 1534 nfsrv_freeallnfslocks(stp, vp, cansleep, p); 1535 if (stp->ls_op) 1536 nfsrvd_derefcache(stp->ls_op); 1537 free(stp, M_NFSDSTATE); 1538 nfsstatsv1.srvlockowners--; 1539 nfsrv_openpluslock--; 1540 } 1541 1542 /* 1543 * Free all the nfs locks on a lockowner. 1544 */ 1545 static void 1546 nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep, 1547 NFSPROC_T *p) 1548 { 1549 struct nfslock *lop, *nlop; 1550 struct nfsrollback *rlp, *nrlp; 1551 struct nfslockfile *lfp = NULL; 1552 int gottvp = 0; 1553 vnode_t tvp = NULL; 1554 uint64_t first, end; 1555 1556 if (vp != NULL) 1557 ASSERT_VOP_UNLOCKED(vp, "nfsrv_freeallnfslocks: vnode locked"); 1558 lop = LIST_FIRST(&stp->ls_lock); 1559 while (lop != LIST_END(&stp->ls_lock)) { 1560 nlop = LIST_NEXT(lop, lo_lckowner); 1561 /* 1562 * Since all locks should be for the same file, lfp should 1563 * not change. 1564 */ 1565 if (lfp == NULL) 1566 lfp = lop->lo_lfp; 1567 else if (lfp != lop->lo_lfp) 1568 panic("allnfslocks"); 1569 /* 1570 * If vp is NULL and cansleep != 0, a vnode must be acquired 1571 * from the file handle. This only occurs when called from 1572 * nfsrv_cleanclient(). 1573 */ 1574 if (gottvp == 0) { 1575 if (nfsrv_dolocallocks == 0) 1576 tvp = NULL; 1577 else if (vp == NULL && cansleep != 0) { 1578 tvp = nfsvno_getvp(&lfp->lf_fh); 1579 if (tvp != NULL) 1580 NFSVOPUNLOCK(tvp); 1581 } else 1582 tvp = vp; 1583 gottvp = 1; 1584 } 1585 1586 if (tvp != NULL) { 1587 if (cansleep == 0) 1588 panic("allnfs2"); 1589 first = lop->lo_first; 1590 end = lop->lo_end; 1591 nfsrv_freenfslock(lop); 1592 nfsrv_localunlock(tvp, lfp, first, end, p); 1593 LIST_FOREACH_SAFE(rlp, &lfp->lf_rollback, rlck_list, 1594 nrlp) 1595 free(rlp, M_NFSDROLLBACK); 1596 LIST_INIT(&lfp->lf_rollback); 1597 } else 1598 nfsrv_freenfslock(lop); 1599 lop = nlop; 1600 } 1601 if (vp == NULL && tvp != NULL) 1602 vrele(tvp); 1603 } 1604 1605 /* 1606 * Free an nfslock structure. 1607 */ 1608 static void 1609 nfsrv_freenfslock(struct nfslock *lop) 1610 { 1611 1612 if (lop->lo_lckfile.le_prev != NULL) { 1613 LIST_REMOVE(lop, lo_lckfile); 1614 nfsstatsv1.srvlocks--; 1615 nfsrv_openpluslock--; 1616 } 1617 LIST_REMOVE(lop, lo_lckowner); 1618 free(lop, M_NFSDLOCK); 1619 } 1620 1621 /* 1622 * This function frees an nfslockfile structure. 1623 */ 1624 static void 1625 nfsrv_freenfslockfile(struct nfslockfile *lfp) 1626 { 1627 1628 LIST_REMOVE(lfp, lf_hash); 1629 free(lfp, M_NFSDLOCKFILE); 1630 } 1631 1632 /* 1633 * This function looks up an nfsstate structure via stateid. 1634 */ 1635 static int 1636 nfsrv_getstate(struct nfsclient *clp, nfsv4stateid_t *stateidp, __unused u_int32_t flags, 1637 struct nfsstate **stpp) 1638 { 1639 struct nfsstate *stp; 1640 struct nfsstatehead *hp; 1641 int error = 0; 1642 1643 *stpp = NULL; 1644 hp = NFSSTATEHASH(clp, *stateidp); 1645 LIST_FOREACH(stp, hp, ls_hash) { 1646 if (!NFSBCMP(stp->ls_stateid.other, stateidp->other, 1647 NFSX_STATEIDOTHER)) 1648 break; 1649 } 1650 1651 /* 1652 * If no state id in list, return NFSERR_BADSTATEID. 1653 */ 1654 if (stp == LIST_END(hp)) { 1655 error = NFSERR_BADSTATEID; 1656 goto out; 1657 } 1658 *stpp = stp; 1659 1660 out: 1661 NFSEXITCODE(error); 1662 return (error); 1663 } 1664 1665 /* 1666 * This function gets an nfsstate structure via owner string. 1667 */ 1668 static void 1669 nfsrv_getowner(struct nfsstatehead *hp, struct nfsstate *new_stp, 1670 struct nfsstate **stpp) 1671 { 1672 struct nfsstate *stp; 1673 1674 *stpp = NULL; 1675 LIST_FOREACH(stp, hp, ls_list) { 1676 if (new_stp->ls_ownerlen == stp->ls_ownerlen && 1677 !NFSBCMP(new_stp->ls_owner,stp->ls_owner,stp->ls_ownerlen)) { 1678 *stpp = stp; 1679 return; 1680 } 1681 } 1682 } 1683 1684 /* 1685 * Lock control function called to update lock status. 1686 * Returns 0 upon success, -1 if there is no lock and the flags indicate 1687 * that one isn't to be created and an NFSERR_xxx for other errors. 1688 * The structures new_stp and new_lop are passed in as pointers that should 1689 * be set to NULL if the structure is used and shouldn't be free'd. 1690 * For the NFSLCK_TEST and NFSLCK_CHECK cases, the structures are 1691 * never used and can safely be allocated on the stack. For all other 1692 * cases, *new_stpp and *new_lopp should be malloc'd before the call, 1693 * in case they are used. 1694 */ 1695 int 1696 nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp, 1697 struct nfslock **new_lopp, struct nfslockconflict *cfp, 1698 nfsquad_t clientid, nfsv4stateid_t *stateidp, 1699 __unused struct nfsexstuff *exp, 1700 struct nfsrv_descript *nd, NFSPROC_T *p) 1701 { 1702 struct nfslock *lop; 1703 struct nfsstate *new_stp = *new_stpp; 1704 struct nfslock *new_lop = *new_lopp; 1705 struct nfsstate *tstp, *mystp, *nstp; 1706 int specialid = 0; 1707 struct nfslockfile *lfp; 1708 struct nfslock *other_lop = NULL; 1709 struct nfsstate *stp, *lckstp = NULL; 1710 struct nfsclient *clp = NULL; 1711 u_int32_t bits; 1712 int error = 0, haslock = 0, ret, reterr; 1713 int getlckret, delegation = 0, filestruct_locked, vnode_unlocked = 0; 1714 fhandle_t nfh; 1715 uint64_t first, end; 1716 uint32_t lock_flags; 1717 1718 if (new_stp->ls_flags & (NFSLCK_CHECK | NFSLCK_SETATTR)) { 1719 /* 1720 * Note the special cases of "all 1s" or "all 0s" stateids and 1721 * let reads with all 1s go ahead. 1722 */ 1723 if (new_stp->ls_stateid.seqid == 0x0 && 1724 new_stp->ls_stateid.other[0] == 0x0 && 1725 new_stp->ls_stateid.other[1] == 0x0 && 1726 new_stp->ls_stateid.other[2] == 0x0) 1727 specialid = 1; 1728 else if (new_stp->ls_stateid.seqid == 0xffffffff && 1729 new_stp->ls_stateid.other[0] == 0xffffffff && 1730 new_stp->ls_stateid.other[1] == 0xffffffff && 1731 new_stp->ls_stateid.other[2] == 0xffffffff) 1732 specialid = 2; 1733 } 1734 1735 /* 1736 * Check for restart conditions (client and server). 1737 */ 1738 error = nfsrv_checkrestart(clientid, new_stp->ls_flags, 1739 &new_stp->ls_stateid, specialid); 1740 if (error) 1741 goto out; 1742 1743 /* 1744 * Check for state resource limit exceeded. 1745 */ 1746 if ((new_stp->ls_flags & NFSLCK_LOCK) && 1747 nfsrv_openpluslock > nfsrv_v4statelimit) { 1748 error = NFSERR_RESOURCE; 1749 goto out; 1750 } 1751 1752 /* 1753 * For the lock case, get another nfslock structure, 1754 * just in case we need it. 1755 * Malloc now, before we start sifting through the linked lists, 1756 * in case we have to wait for memory. 1757 */ 1758 tryagain: 1759 if (new_stp->ls_flags & NFSLCK_LOCK) 1760 other_lop = malloc(sizeof (struct nfslock), 1761 M_NFSDLOCK, M_WAITOK); 1762 filestruct_locked = 0; 1763 reterr = 0; 1764 lfp = NULL; 1765 1766 /* 1767 * Get the lockfile structure for CFH now, so we can do a sanity 1768 * check against the stateid, before incrementing the seqid#, since 1769 * we want to return NFSERR_BADSTATEID on failure and the seqid# 1770 * shouldn't be incremented for this case. 1771 * If nfsrv_getlockfile() returns -1, it means "not found", which 1772 * will be handled later. 1773 * If we are doing Lock/LockU and local locking is enabled, sleep 1774 * lock the nfslockfile structure. 1775 */ 1776 getlckret = nfsrv_getlockfh(vp, new_stp->ls_flags, NULL, &nfh, p); 1777 NFSLOCKSTATE(); 1778 if (getlckret == 0) { 1779 if ((new_stp->ls_flags & (NFSLCK_LOCK | NFSLCK_UNLOCK)) != 0 && 1780 nfsrv_dolocallocks != 0 && nd->nd_repstat == 0) { 1781 getlckret = nfsrv_getlockfile(new_stp->ls_flags, NULL, 1782 &lfp, &nfh, 1); 1783 if (getlckret == 0) 1784 filestruct_locked = 1; 1785 } else 1786 getlckret = nfsrv_getlockfile(new_stp->ls_flags, NULL, 1787 &lfp, &nfh, 0); 1788 } 1789 if (getlckret != 0 && getlckret != -1) 1790 reterr = getlckret; 1791 1792 if (filestruct_locked != 0) { 1793 LIST_INIT(&lfp->lf_rollback); 1794 if ((new_stp->ls_flags & NFSLCK_LOCK)) { 1795 /* 1796 * For local locking, do the advisory locking now, so 1797 * that any conflict can be detected. A failure later 1798 * can be rolled back locally. If an error is returned, 1799 * struct nfslockfile has been unlocked and any local 1800 * locking rolled back. 1801 */ 1802 NFSUNLOCKSTATE(); 1803 if (vnode_unlocked == 0) { 1804 ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl1"); 1805 vnode_unlocked = 1; 1806 NFSVOPUNLOCK(vp); 1807 } 1808 reterr = nfsrv_locallock(vp, lfp, 1809 (new_lop->lo_flags & (NFSLCK_READ | NFSLCK_WRITE)), 1810 new_lop->lo_first, new_lop->lo_end, cfp, p); 1811 NFSLOCKSTATE(); 1812 } 1813 } 1814 1815 if (specialid == 0) { 1816 if (new_stp->ls_flags & NFSLCK_TEST) { 1817 /* 1818 * RFC 3530 does not list LockT as an op that renews a 1819 * lease, but the consensus seems to be that it is ok 1820 * for a server to do so. 1821 */ 1822 error = nfsrv_getclient(clientid, CLOPS_RENEW, &clp, NULL, 1823 (nfsquad_t)((u_quad_t)0), 0, nd, p); 1824 1825 /* 1826 * Since NFSERR_EXPIRED, NFSERR_ADMINREVOKED are not valid 1827 * error returns for LockT, just go ahead and test for a lock, 1828 * since there are no locks for this client, but other locks 1829 * can conflict. (ie. same client will always be false) 1830 */ 1831 if (error == NFSERR_EXPIRED || error == NFSERR_ADMINREVOKED) 1832 error = 0; 1833 lckstp = new_stp; 1834 } else { 1835 error = nfsrv_getclient(clientid, CLOPS_RENEW, &clp, NULL, 1836 (nfsquad_t)((u_quad_t)0), 0, nd, p); 1837 if (error == 0) 1838 /* 1839 * Look up the stateid 1840 */ 1841 error = nfsrv_getstate(clp, &new_stp->ls_stateid, 1842 new_stp->ls_flags, &stp); 1843 /* 1844 * do some sanity checks for an unconfirmed open or a 1845 * stateid that refers to the wrong file, for an open stateid 1846 */ 1847 if (error == 0 && (stp->ls_flags & NFSLCK_OPEN) && 1848 ((stp->ls_openowner->ls_flags & NFSLCK_NEEDSCONFIRM) || 1849 (getlckret == 0 && stp->ls_lfp != lfp))){ 1850 /* 1851 * NFSLCK_SETATTR should return OK rather than NFSERR_BADSTATEID 1852 * The only exception is using SETATTR with SIZE. 1853 * */ 1854 if ((new_stp->ls_flags & 1855 (NFSLCK_SETATTR | NFSLCK_CHECK)) != NFSLCK_SETATTR) 1856 error = NFSERR_BADSTATEID; 1857 } 1858 1859 if (error == 0 && 1860 (stp->ls_flags & (NFSLCK_DELEGREAD | NFSLCK_DELEGWRITE)) && 1861 getlckret == 0 && stp->ls_lfp != lfp) 1862 error = NFSERR_BADSTATEID; 1863 1864 /* 1865 * If the lockowner stateid doesn't refer to the same file, 1866 * I believe that is considered ok, since some clients will 1867 * only create a single lockowner and use that for all locks 1868 * on all files. 1869 * For now, log it as a diagnostic, instead of considering it 1870 * a BadStateid. 1871 */ 1872 if (error == 0 && (stp->ls_flags & 1873 (NFSLCK_OPEN | NFSLCK_DELEGREAD | NFSLCK_DELEGWRITE)) == 0 && 1874 getlckret == 0 && stp->ls_lfp != lfp) { 1875 #ifdef DIAGNOSTIC 1876 printf("Got a lock statid for different file open\n"); 1877 #endif 1878 /* 1879 error = NFSERR_BADSTATEID; 1880 */ 1881 } 1882 1883 if (error == 0) { 1884 if (new_stp->ls_flags & NFSLCK_OPENTOLOCK) { 1885 /* 1886 * If haslock set, we've already checked the seqid. 1887 */ 1888 if (!haslock) { 1889 if (stp->ls_flags & NFSLCK_OPEN) 1890 error = nfsrv_checkseqid(nd, new_stp->ls_seq, 1891 stp->ls_openowner, new_stp->ls_op); 1892 else 1893 error = NFSERR_BADSTATEID; 1894 } 1895 if (!error) 1896 nfsrv_getowner(&stp->ls_open, new_stp, &lckstp); 1897 if (lckstp) { 1898 /* 1899 * For NFSv4.1 and NFSv4.2 allow an 1900 * open_to_lock_owner when the lock_owner already 1901 * exists. Just clear NFSLCK_OPENTOLOCK so that 1902 * a new lock_owner will not be created. 1903 * RFC7530 states that the error for NFSv4.0 1904 * is NFS4ERR_BAD_SEQID. 1905 */ 1906 if ((nd->nd_flag & ND_NFSV41) != 0) 1907 new_stp->ls_flags &= ~NFSLCK_OPENTOLOCK; 1908 else 1909 error = NFSERR_BADSEQID; 1910 } else 1911 lckstp = new_stp; 1912 } else if (new_stp->ls_flags&(NFSLCK_LOCK|NFSLCK_UNLOCK)) { 1913 /* 1914 * If haslock set, ditto above. 1915 */ 1916 if (!haslock) { 1917 if (stp->ls_flags & NFSLCK_OPEN) 1918 error = NFSERR_BADSTATEID; 1919 else 1920 error = nfsrv_checkseqid(nd, new_stp->ls_seq, 1921 stp, new_stp->ls_op); 1922 } 1923 lckstp = stp; 1924 } else { 1925 lckstp = stp; 1926 } 1927 } 1928 /* 1929 * If the seqid part of the stateid isn't the same, return 1930 * NFSERR_OLDSTATEID for cases other than I/O Ops. 1931 * For I/O Ops, only return NFSERR_OLDSTATEID if 1932 * nfsrv_returnoldstateid is set. (The consensus on the email 1933 * list was that most clients would prefer to not receive 1934 * NFSERR_OLDSTATEID for I/O Ops, but the RFC suggests that that 1935 * is what will happen, so I use the nfsrv_returnoldstateid to 1936 * allow for either server configuration.) 1937 */ 1938 if (!error && stp->ls_stateid.seqid!=new_stp->ls_stateid.seqid && 1939 (((nd->nd_flag & ND_NFSV41) == 0 && 1940 (!(new_stp->ls_flags & NFSLCK_CHECK) || 1941 nfsrv_returnoldstateid)) || 1942 ((nd->nd_flag & ND_NFSV41) != 0 && 1943 new_stp->ls_stateid.seqid != 0))) 1944 error = NFSERR_OLDSTATEID; 1945 } 1946 } 1947 1948 /* 1949 * Now we can check for grace. 1950 */ 1951 if (!error) 1952 error = nfsrv_checkgrace(nd, clp, new_stp->ls_flags); 1953 if ((new_stp->ls_flags & NFSLCK_RECLAIM) && !error && 1954 nfsrv_checkstable(clp)) 1955 error = NFSERR_NOGRACE; 1956 /* 1957 * If we successfully Reclaimed state, note that. 1958 */ 1959 if ((new_stp->ls_flags & NFSLCK_RECLAIM) && !error) 1960 nfsrv_markstable(clp); 1961 1962 /* 1963 * At this point, either error == NFSERR_BADSTATEID or the 1964 * seqid# has been updated, so we can return any error. 1965 * If error == 0, there may be an error in: 1966 * nd_repstat - Set by the calling function. 1967 * reterr - Set above, if getting the nfslockfile structure 1968 * or acquiring the local lock failed. 1969 * (If both of these are set, nd_repstat should probably be 1970 * returned, since that error was detected before this 1971 * function call.) 1972 */ 1973 if (error != 0 || nd->nd_repstat != 0 || reterr != 0) { 1974 if (error == 0) { 1975 if (nd->nd_repstat != 0) 1976 error = nd->nd_repstat; 1977 else 1978 error = reterr; 1979 } 1980 if (filestruct_locked != 0) { 1981 /* Roll back local locks. */ 1982 NFSUNLOCKSTATE(); 1983 if (vnode_unlocked == 0) { 1984 ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl2"); 1985 vnode_unlocked = 1; 1986 NFSVOPUNLOCK(vp); 1987 } 1988 nfsrv_locallock_rollback(vp, lfp, p); 1989 NFSLOCKSTATE(); 1990 nfsrv_unlocklf(lfp); 1991 } 1992 NFSUNLOCKSTATE(); 1993 goto out; 1994 } 1995 1996 /* 1997 * Check the nfsrv_getlockfile return. 1998 * Returned -1 if no structure found. 1999 */ 2000 if (getlckret == -1) { 2001 error = NFSERR_EXPIRED; 2002 /* 2003 * Called from lockt, so no lock is OK. 2004 */ 2005 if (new_stp->ls_flags & NFSLCK_TEST) { 2006 error = 0; 2007 } else if (new_stp->ls_flags & 2008 (NFSLCK_CHECK | NFSLCK_SETATTR)) { 2009 /* 2010 * Called to check for a lock, OK if the stateid is all 2011 * 1s or all 0s, but there should be an nfsstate 2012 * otherwise. 2013 * (ie. If there is no open, I'll assume no share 2014 * deny bits.) 2015 */ 2016 if (specialid) 2017 error = 0; 2018 else 2019 error = NFSERR_BADSTATEID; 2020 } 2021 NFSUNLOCKSTATE(); 2022 goto out; 2023 } 2024 2025 /* 2026 * For NFSLCK_CHECK and NFSLCK_LOCK, test for a share conflict. 2027 * For NFSLCK_CHECK, allow a read if write access is granted, 2028 * but check for a deny. For NFSLCK_LOCK, require correct access, 2029 * which implies a conflicting deny can't exist. 2030 */ 2031 if (new_stp->ls_flags & (NFSLCK_CHECK | NFSLCK_LOCK)) { 2032 /* 2033 * Four kinds of state id: 2034 * - specialid (all 0s or all 1s), only for NFSLCK_CHECK 2035 * - stateid for an open 2036 * - stateid for a delegation 2037 * - stateid for a lock owner 2038 */ 2039 if (!specialid) { 2040 if (stp->ls_flags & (NFSLCK_DELEGREAD | NFSLCK_DELEGWRITE)) { 2041 delegation = 1; 2042 mystp = stp; 2043 nfsrv_delaydelegtimeout(stp); 2044 } else if (stp->ls_flags & NFSLCK_OPEN) { 2045 mystp = stp; 2046 } else { 2047 mystp = stp->ls_openstp; 2048 } 2049 /* 2050 * If locking or checking, require correct access 2051 * bit set. 2052 */ 2053 if (((new_stp->ls_flags & NFSLCK_LOCK) && 2054 !((new_lop->lo_flags >> NFSLCK_LOCKSHIFT) & 2055 mystp->ls_flags & NFSLCK_ACCESSBITS)) || 2056 ((new_stp->ls_flags & (NFSLCK_CHECK|NFSLCK_READACCESS)) == 2057 (NFSLCK_CHECK | NFSLCK_READACCESS) && 2058 !(mystp->ls_flags & NFSLCK_READACCESS) && 2059 nfsrv_allowreadforwriteopen == 0) || 2060 ((new_stp->ls_flags & (NFSLCK_CHECK|NFSLCK_WRITEACCESS)) == 2061 (NFSLCK_CHECK | NFSLCK_WRITEACCESS) && 2062 !(mystp->ls_flags & NFSLCK_WRITEACCESS))) { 2063 if (filestruct_locked != 0) { 2064 /* Roll back local locks. */ 2065 NFSUNLOCKSTATE(); 2066 if (vnode_unlocked == 0) { 2067 ASSERT_VOP_ELOCKED(vp, 2068 "nfsrv_lockctrl3"); 2069 vnode_unlocked = 1; 2070 NFSVOPUNLOCK(vp); 2071 } 2072 nfsrv_locallock_rollback(vp, lfp, p); 2073 NFSLOCKSTATE(); 2074 nfsrv_unlocklf(lfp); 2075 } 2076 NFSUNLOCKSTATE(); 2077 error = NFSERR_OPENMODE; 2078 goto out; 2079 } 2080 } else 2081 mystp = NULL; 2082 if ((new_stp->ls_flags & NFSLCK_CHECK) && !delegation) { 2083 /* 2084 * Check for a conflicting deny bit. 2085 */ 2086 LIST_FOREACH(tstp, &lfp->lf_open, ls_file) { 2087 if (tstp != mystp) { 2088 bits = tstp->ls_flags; 2089 bits >>= NFSLCK_SHIFT; 2090 if (new_stp->ls_flags & bits & NFSLCK_ACCESSBITS) { 2091 KASSERT(vnode_unlocked == 0, 2092 ("nfsrv_lockctrl: vnode unlocked1")); 2093 ret = nfsrv_clientconflict(tstp->ls_clp, &haslock, 2094 vp, p); 2095 if (ret == 1) { 2096 /* 2097 * nfsrv_clientconflict unlocks state 2098 * when it returns non-zero. 2099 */ 2100 lckstp = NULL; 2101 goto tryagain; 2102 } 2103 if (ret == 0) 2104 NFSUNLOCKSTATE(); 2105 if (ret == 2) 2106 error = NFSERR_PERM; 2107 else 2108 error = NFSERR_OPENMODE; 2109 goto out; 2110 } 2111 } 2112 } 2113 2114 /* We're outta here */ 2115 NFSUNLOCKSTATE(); 2116 goto out; 2117 } 2118 } 2119 2120 /* 2121 * For setattr, just get rid of all the Delegations for other clients. 2122 */ 2123 if (new_stp->ls_flags & NFSLCK_SETATTR) { 2124 KASSERT(vnode_unlocked == 0, 2125 ("nfsrv_lockctrl: vnode unlocked2")); 2126 ret = nfsrv_cleandeleg(vp, lfp, clp, &haslock, p); 2127 if (ret) { 2128 /* 2129 * nfsrv_cleandeleg() unlocks state when it 2130 * returns non-zero. 2131 */ 2132 if (ret == -1) { 2133 lckstp = NULL; 2134 goto tryagain; 2135 } 2136 error = ret; 2137 goto out; 2138 } 2139 if (!(new_stp->ls_flags & NFSLCK_CHECK) || 2140 (LIST_EMPTY(&lfp->lf_open) && LIST_EMPTY(&lfp->lf_lock) && 2141 LIST_EMPTY(&lfp->lf_deleg))) { 2142 NFSUNLOCKSTATE(); 2143 goto out; 2144 } 2145 } 2146 2147 /* 2148 * Check for a conflicting delegation. If one is found, call 2149 * nfsrv_delegconflict() to handle it. If the v4root lock hasn't 2150 * been set yet, it will get the lock. Otherwise, it will recall 2151 * the delegation. Then, we try try again... 2152 * I currently believe the conflict algorithm to be: 2153 * For Lock Ops (Lock/LockT/LockU) 2154 * - there is a conflict iff a different client has a write delegation 2155 * For Reading (Read Op) 2156 * - there is a conflict iff a different client has a write delegation 2157 * (the specialids are always a different client) 2158 * For Writing (Write/Setattr of size) 2159 * - there is a conflict if a different client has any delegation 2160 * - there is a conflict if the same client has a read delegation 2161 * (I don't understand why this isn't allowed, but that seems to be 2162 * the current consensus?) 2163 */ 2164 tstp = LIST_FIRST(&lfp->lf_deleg); 2165 while (tstp != LIST_END(&lfp->lf_deleg)) { 2166 nstp = LIST_NEXT(tstp, ls_file); 2167 if ((((new_stp->ls_flags&(NFSLCK_LOCK|NFSLCK_UNLOCK|NFSLCK_TEST))|| 2168 ((new_stp->ls_flags & NFSLCK_CHECK) && 2169 (new_lop->lo_flags & NFSLCK_READ))) && 2170 clp != tstp->ls_clp && 2171 (tstp->ls_flags & NFSLCK_DELEGWRITE)) || 2172 ((new_stp->ls_flags & NFSLCK_CHECK) && 2173 (new_lop->lo_flags & NFSLCK_WRITE) && 2174 (clp != tstp->ls_clp || 2175 (tstp->ls_flags & NFSLCK_DELEGREAD)))) { 2176 ret = 0; 2177 if (filestruct_locked != 0) { 2178 /* Roll back local locks. */ 2179 NFSUNLOCKSTATE(); 2180 if (vnode_unlocked == 0) { 2181 ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl4"); 2182 NFSVOPUNLOCK(vp); 2183 } 2184 nfsrv_locallock_rollback(vp, lfp, p); 2185 NFSLOCKSTATE(); 2186 nfsrv_unlocklf(lfp); 2187 NFSUNLOCKSTATE(); 2188 NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); 2189 vnode_unlocked = 0; 2190 if (VN_IS_DOOMED(vp)) 2191 ret = NFSERR_SERVERFAULT; 2192 NFSLOCKSTATE(); 2193 } 2194 if (ret == 0) 2195 ret = nfsrv_delegconflict(tstp, &haslock, p, vp); 2196 if (ret) { 2197 /* 2198 * nfsrv_delegconflict unlocks state when it 2199 * returns non-zero, which it always does. 2200 */ 2201 if (other_lop) { 2202 free(other_lop, M_NFSDLOCK); 2203 other_lop = NULL; 2204 } 2205 if (ret == -1) { 2206 lckstp = NULL; 2207 goto tryagain; 2208 } 2209 error = ret; 2210 goto out; 2211 } 2212 /* Never gets here. */ 2213 } 2214 tstp = nstp; 2215 } 2216 2217 /* 2218 * Handle the unlock case by calling nfsrv_updatelock(). 2219 * (Should I have done some access checking above for unlock? For now, 2220 * just let it happen.) 2221 */ 2222 if (new_stp->ls_flags & NFSLCK_UNLOCK) { 2223 first = new_lop->lo_first; 2224 end = new_lop->lo_end; 2225 nfsrv_updatelock(stp, new_lopp, &other_lop, lfp); 2226 stateidp->seqid = ++(stp->ls_stateid.seqid); 2227 if ((nd->nd_flag & ND_NFSV41) != 0 && stateidp->seqid == 0) 2228 stateidp->seqid = stp->ls_stateid.seqid = 1; 2229 stateidp->other[0] = stp->ls_stateid.other[0]; 2230 stateidp->other[1] = stp->ls_stateid.other[1]; 2231 stateidp->other[2] = stp->ls_stateid.other[2]; 2232 if (filestruct_locked != 0) { 2233 NFSUNLOCKSTATE(); 2234 if (vnode_unlocked == 0) { 2235 ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl5"); 2236 vnode_unlocked = 1; 2237 NFSVOPUNLOCK(vp); 2238 } 2239 /* Update the local locks. */ 2240 nfsrv_localunlock(vp, lfp, first, end, p); 2241 NFSLOCKSTATE(); 2242 nfsrv_unlocklf(lfp); 2243 } 2244 NFSUNLOCKSTATE(); 2245 goto out; 2246 } 2247 2248 /* 2249 * Search for a conflicting lock. A lock conflicts if: 2250 * - the lock range overlaps and 2251 * - at least one lock is a write lock and 2252 * - it is not owned by the same lock owner 2253 */ 2254 if (!delegation) { 2255 LIST_FOREACH(lop, &lfp->lf_lock, lo_lckfile) { 2256 if (new_lop->lo_end > lop->lo_first && 2257 new_lop->lo_first < lop->lo_end && 2258 (new_lop->lo_flags == NFSLCK_WRITE || 2259 lop->lo_flags == NFSLCK_WRITE) && 2260 lckstp != lop->lo_stp && 2261 (clp != lop->lo_stp->ls_clp || 2262 lckstp->ls_ownerlen != lop->lo_stp->ls_ownerlen || 2263 NFSBCMP(lckstp->ls_owner, lop->lo_stp->ls_owner, 2264 lckstp->ls_ownerlen))) { 2265 if (other_lop) { 2266 free(other_lop, M_NFSDLOCK); 2267 other_lop = NULL; 2268 } 2269 if (vnode_unlocked != 0) 2270 ret = nfsrv_clientconflict(lop->lo_stp->ls_clp, &haslock, 2271 NULL, p); 2272 else 2273 ret = nfsrv_clientconflict(lop->lo_stp->ls_clp, &haslock, 2274 vp, p); 2275 if (ret == 1) { 2276 if (filestruct_locked != 0) { 2277 if (vnode_unlocked == 0) { 2278 ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl6"); 2279 NFSVOPUNLOCK(vp); 2280 } 2281 /* Roll back local locks. */ 2282 nfsrv_locallock_rollback(vp, lfp, p); 2283 NFSLOCKSTATE(); 2284 nfsrv_unlocklf(lfp); 2285 NFSUNLOCKSTATE(); 2286 NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); 2287 vnode_unlocked = 0; 2288 if (VN_IS_DOOMED(vp)) { 2289 error = NFSERR_SERVERFAULT; 2290 goto out; 2291 } 2292 } 2293 /* 2294 * nfsrv_clientconflict() unlocks state when it 2295 * returns non-zero. 2296 */ 2297 lckstp = NULL; 2298 goto tryagain; 2299 } 2300 /* 2301 * Found a conflicting lock, so record the conflict and 2302 * return the error. 2303 */ 2304 if (cfp != NULL && ret == 0) { 2305 cfp->cl_clientid.lval[0]=lop->lo_stp->ls_stateid.other[0]; 2306 cfp->cl_clientid.lval[1]=lop->lo_stp->ls_stateid.other[1]; 2307 cfp->cl_first = lop->lo_first; 2308 cfp->cl_end = lop->lo_end; 2309 cfp->cl_flags = lop->lo_flags; 2310 cfp->cl_ownerlen = lop->lo_stp->ls_ownerlen; 2311 NFSBCOPY(lop->lo_stp->ls_owner, cfp->cl_owner, 2312 cfp->cl_ownerlen); 2313 } 2314 if (ret == 2) 2315 error = NFSERR_PERM; 2316 else if (new_stp->ls_flags & NFSLCK_RECLAIM) 2317 error = NFSERR_RECLAIMCONFLICT; 2318 else if (new_stp->ls_flags & NFSLCK_CHECK) 2319 error = NFSERR_LOCKED; 2320 else 2321 error = NFSERR_DENIED; 2322 if (filestruct_locked != 0 && ret == 0) { 2323 /* Roll back local locks. */ 2324 NFSUNLOCKSTATE(); 2325 if (vnode_unlocked == 0) { 2326 ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl7"); 2327 vnode_unlocked = 1; 2328 NFSVOPUNLOCK(vp); 2329 } 2330 nfsrv_locallock_rollback(vp, lfp, p); 2331 NFSLOCKSTATE(); 2332 nfsrv_unlocklf(lfp); 2333 } 2334 if (ret == 0) 2335 NFSUNLOCKSTATE(); 2336 goto out; 2337 } 2338 } 2339 } 2340 2341 /* 2342 * We only get here if there was no lock that conflicted. 2343 */ 2344 if (new_stp->ls_flags & (NFSLCK_TEST | NFSLCK_CHECK)) { 2345 NFSUNLOCKSTATE(); 2346 goto out; 2347 } 2348 2349 /* 2350 * We only get here when we are creating or modifying a lock. 2351 * There are two variants: 2352 * - exist_lock_owner where lock_owner exists 2353 * - open_to_lock_owner with new lock_owner 2354 */ 2355 first = new_lop->lo_first; 2356 end = new_lop->lo_end; 2357 lock_flags = new_lop->lo_flags; 2358 if (!(new_stp->ls_flags & NFSLCK_OPENTOLOCK)) { 2359 nfsrv_updatelock(lckstp, new_lopp, &other_lop, lfp); 2360 stateidp->seqid = ++(lckstp->ls_stateid.seqid); 2361 if ((nd->nd_flag & ND_NFSV41) != 0 && stateidp->seqid == 0) 2362 stateidp->seqid = lckstp->ls_stateid.seqid = 1; 2363 stateidp->other[0] = lckstp->ls_stateid.other[0]; 2364 stateidp->other[1] = lckstp->ls_stateid.other[1]; 2365 stateidp->other[2] = lckstp->ls_stateid.other[2]; 2366 } else { 2367 /* 2368 * The new open_to_lock_owner case. 2369 * Link the new nfsstate into the lists. 2370 */ 2371 new_stp->ls_seq = new_stp->ls_opentolockseq; 2372 nfsrvd_refcache(new_stp->ls_op); 2373 stateidp->seqid = new_stp->ls_stateid.seqid = 1; 2374 stateidp->other[0] = new_stp->ls_stateid.other[0] = 2375 clp->lc_clientid.lval[0]; 2376 stateidp->other[1] = new_stp->ls_stateid.other[1] = 2377 clp->lc_clientid.lval[1]; 2378 stateidp->other[2] = new_stp->ls_stateid.other[2] = 2379 nfsrv_nextstateindex(clp); 2380 new_stp->ls_clp = clp; 2381 LIST_INIT(&new_stp->ls_lock); 2382 new_stp->ls_openstp = stp; 2383 new_stp->ls_lfp = lfp; 2384 nfsrv_insertlock(new_lop, (struct nfslock *)new_stp, new_stp, 2385 lfp); 2386 LIST_INSERT_HEAD(NFSSTATEHASH(clp, new_stp->ls_stateid), 2387 new_stp, ls_hash); 2388 LIST_INSERT_HEAD(&stp->ls_open, new_stp, ls_list); 2389 *new_lopp = NULL; 2390 *new_stpp = NULL; 2391 nfsstatsv1.srvlockowners++; 2392 nfsrv_openpluslock++; 2393 } 2394 if (filestruct_locked != 0) { 2395 NFSUNLOCKSTATE(); 2396 nfsrv_locallock_commit(lfp, lock_flags, first, end); 2397 NFSLOCKSTATE(); 2398 nfsrv_unlocklf(lfp); 2399 } 2400 NFSUNLOCKSTATE(); 2401 2402 out: 2403 if (haslock) { 2404 NFSLOCKV4ROOTMUTEX(); 2405 nfsv4_unlock(&nfsv4rootfs_lock, 1); 2406 NFSUNLOCKV4ROOTMUTEX(); 2407 } 2408 if (vnode_unlocked != 0) { 2409 NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); 2410 if (error == 0 && VN_IS_DOOMED(vp)) 2411 error = NFSERR_SERVERFAULT; 2412 } 2413 if (other_lop) 2414 free(other_lop, M_NFSDLOCK); 2415 NFSEXITCODE2(error, nd); 2416 return (error); 2417 } 2418 2419 /* 2420 * Check for state errors for Open. 2421 * repstat is passed back out as an error if more critical errors 2422 * are not detected. 2423 */ 2424 int 2425 nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp, 2426 struct nfsstate *new_stp, vnode_t vp, struct nfsrv_descript *nd, 2427 NFSPROC_T *p, int repstat) 2428 { 2429 struct nfsstate *stp, *nstp; 2430 struct nfsclient *clp; 2431 struct nfsstate *ownerstp; 2432 struct nfslockfile *lfp, *new_lfp; 2433 int error = 0, haslock = 0, ret, readonly = 0, getfhret = 0; 2434 2435 if ((new_stp->ls_flags & NFSLCK_SHAREBITS) == NFSLCK_READACCESS) 2436 readonly = 1; 2437 /* 2438 * Check for restart conditions (client and server). 2439 */ 2440 error = nfsrv_checkrestart(clientid, new_stp->ls_flags, 2441 &new_stp->ls_stateid, 0); 2442 if (error) 2443 goto out; 2444 2445 /* 2446 * Check for state resource limit exceeded. 2447 * Technically this should be SMP protected, but the worst 2448 * case error is "out by one or two" on the count when it 2449 * returns NFSERR_RESOURCE and the limit is just a rather 2450 * arbitrary high water mark, so no harm is done. 2451 */ 2452 if (nfsrv_openpluslock > nfsrv_v4statelimit) { 2453 error = NFSERR_RESOURCE; 2454 goto out; 2455 } 2456 2457 tryagain: 2458 new_lfp = malloc(sizeof (struct nfslockfile), 2459 M_NFSDLOCKFILE, M_WAITOK); 2460 if (vp) 2461 getfhret = nfsrv_getlockfh(vp, new_stp->ls_flags, new_lfp, 2462 NULL, p); 2463 NFSLOCKSTATE(); 2464 /* 2465 * Get the nfsclient structure. 2466 */ 2467 error = nfsrv_getclient(clientid, CLOPS_RENEW, &clp, NULL, 2468 (nfsquad_t)((u_quad_t)0), 0, nd, p); 2469 2470 /* 2471 * Look up the open owner. See if it needs confirmation and 2472 * check the seq#, as required. 2473 */ 2474 if (!error) 2475 nfsrv_getowner(&clp->lc_open, new_stp, &ownerstp); 2476 2477 if (!error && ownerstp) { 2478 error = nfsrv_checkseqid(nd, new_stp->ls_seq, ownerstp, 2479 new_stp->ls_op); 2480 /* 2481 * If the OpenOwner hasn't been confirmed, assume the 2482 * old one was a replay and this one is ok. 2483 * See: RFC3530 Sec. 14.2.18. 2484 */ 2485 if (error == NFSERR_BADSEQID && 2486 (ownerstp->ls_flags & NFSLCK_NEEDSCONFIRM)) 2487 error = 0; 2488 } 2489 2490 /* 2491 * Check for grace. 2492 */ 2493 if (!error) 2494 error = nfsrv_checkgrace(nd, clp, new_stp->ls_flags); 2495 if ((new_stp->ls_flags & NFSLCK_RECLAIM) && !error && 2496 nfsrv_checkstable(clp)) 2497 error = NFSERR_NOGRACE; 2498 2499 /* 2500 * If none of the above errors occurred, let repstat be 2501 * returned. 2502 */ 2503 if (repstat && !error) 2504 error = repstat; 2505 if (error) { 2506 NFSUNLOCKSTATE(); 2507 if (haslock) { 2508 NFSLOCKV4ROOTMUTEX(); 2509 nfsv4_unlock(&nfsv4rootfs_lock, 1); 2510 NFSUNLOCKV4ROOTMUTEX(); 2511 } 2512 free(new_lfp, M_NFSDLOCKFILE); 2513 goto out; 2514 } 2515 2516 /* 2517 * If vp == NULL, the file doesn't exist yet, so return ok. 2518 * (This always happens on the first pass, so haslock must be 0.) 2519 */ 2520 if (vp == NULL) { 2521 NFSUNLOCKSTATE(); 2522 free(new_lfp, M_NFSDLOCKFILE); 2523 goto out; 2524 } 2525 2526 /* 2527 * Get the structure for the underlying file. 2528 */ 2529 if (getfhret) 2530 error = getfhret; 2531 else 2532 error = nfsrv_getlockfile(new_stp->ls_flags, &new_lfp, &lfp, 2533 NULL, 0); 2534 if (new_lfp) 2535 free(new_lfp, M_NFSDLOCKFILE); 2536 if (error) { 2537 NFSUNLOCKSTATE(); 2538 if (haslock) { 2539 NFSLOCKV4ROOTMUTEX(); 2540 nfsv4_unlock(&nfsv4rootfs_lock, 1); 2541 NFSUNLOCKV4ROOTMUTEX(); 2542 } 2543 goto out; 2544 } 2545 2546 /* 2547 * Search for a conflicting open/share. 2548 */ 2549 if (new_stp->ls_flags & NFSLCK_DELEGCUR) { 2550 /* 2551 * For Delegate_Cur, search for the matching Delegation, 2552 * which indicates no conflict. 2553 * An old delegation should have been recovered by the 2554 * client doing a Claim_DELEGATE_Prev, so I won't let 2555 * it match and return NFSERR_EXPIRED. Should I let it 2556 * match? 2557 */ 2558 LIST_FOREACH(stp, &lfp->lf_deleg, ls_file) { 2559 if (!(stp->ls_flags & NFSLCK_OLDDELEG) && 2560 (((nd->nd_flag & ND_NFSV41) != 0 && 2561 stateidp->seqid == 0) || 2562 stateidp->seqid == stp->ls_stateid.seqid) && 2563 !NFSBCMP(stateidp->other, stp->ls_stateid.other, 2564 NFSX_STATEIDOTHER)) 2565 break; 2566 } 2567 if (stp == LIST_END(&lfp->lf_deleg) || 2568 ((new_stp->ls_flags & NFSLCK_WRITEACCESS) && 2569 (stp->ls_flags & NFSLCK_DELEGREAD))) { 2570 NFSUNLOCKSTATE(); 2571 if (haslock) { 2572 NFSLOCKV4ROOTMUTEX(); 2573 nfsv4_unlock(&nfsv4rootfs_lock, 1); 2574 NFSUNLOCKV4ROOTMUTEX(); 2575 } 2576 error = NFSERR_EXPIRED; 2577 goto out; 2578 } 2579 } 2580 2581 /* 2582 * Check for access/deny bit conflicts. I check for the same 2583 * owner as well, in case the client didn't bother. 2584 */ 2585 LIST_FOREACH(stp, &lfp->lf_open, ls_file) { 2586 if (!(new_stp->ls_flags & NFSLCK_DELEGCUR) && 2587 (((new_stp->ls_flags & NFSLCK_ACCESSBITS) & 2588 ((stp->ls_flags>>NFSLCK_SHIFT) & NFSLCK_ACCESSBITS))|| 2589 ((stp->ls_flags & NFSLCK_ACCESSBITS) & 2590 ((new_stp->ls_flags>>NFSLCK_SHIFT)&NFSLCK_ACCESSBITS)))){ 2591 ret = nfsrv_clientconflict(stp->ls_clp,&haslock,vp,p); 2592 if (ret == 1) { 2593 /* 2594 * nfsrv_clientconflict() unlocks 2595 * state when it returns non-zero. 2596 */ 2597 goto tryagain; 2598 } 2599 if (ret == 2) 2600 error = NFSERR_PERM; 2601 else if (new_stp->ls_flags & NFSLCK_RECLAIM) 2602 error = NFSERR_RECLAIMCONFLICT; 2603 else 2604 error = NFSERR_SHAREDENIED; 2605 if (ret == 0) 2606 NFSUNLOCKSTATE(); 2607 if (haslock) { 2608 NFSLOCKV4ROOTMUTEX(); 2609 nfsv4_unlock(&nfsv4rootfs_lock, 1); 2610 NFSUNLOCKV4ROOTMUTEX(); 2611 } 2612 goto out; 2613 } 2614 } 2615 2616 /* 2617 * Check for a conflicting delegation. If one is found, call 2618 * nfsrv_delegconflict() to handle it. If the v4root lock hasn't 2619 * been set yet, it will get the lock. Otherwise, it will recall 2620 * the delegation. Then, we try try again... 2621 * (If NFSLCK_DELEGCUR is set, it has a delegation, so there 2622 * isn't a conflict.) 2623 * I currently believe the conflict algorithm to be: 2624 * For Open with Read Access and Deny None 2625 * - there is a conflict iff a different client has a write delegation 2626 * For Open with other Write Access or any Deny except None 2627 * - there is a conflict if a different client has any delegation 2628 * - there is a conflict if the same client has a read delegation 2629 * (The current consensus is that this last case should be 2630 * considered a conflict since the client with a read delegation 2631 * could have done an Open with ReadAccess and WriteDeny 2632 * locally and then not have checked for the WriteDeny.) 2633 * Don't check for a Reclaim, since that will be dealt with 2634 * by nfsrv_openctrl(). 2635 */ 2636 if (!(new_stp->ls_flags & 2637 (NFSLCK_DELEGPREV | NFSLCK_DELEGCUR | NFSLCK_RECLAIM))) { 2638 stp = LIST_FIRST(&lfp->lf_deleg); 2639 while (stp != LIST_END(&lfp->lf_deleg)) { 2640 nstp = LIST_NEXT(stp, ls_file); 2641 if ((readonly && stp->ls_clp != clp && 2642 (stp->ls_flags & NFSLCK_DELEGWRITE)) || 2643 (!readonly && (stp->ls_clp != clp || 2644 (stp->ls_flags & NFSLCK_DELEGREAD)))) { 2645 ret = nfsrv_delegconflict(stp, &haslock, p, vp); 2646 if (ret) { 2647 /* 2648 * nfsrv_delegconflict() unlocks state 2649 * when it returns non-zero. 2650 */ 2651 if (ret == -1) 2652 goto tryagain; 2653 error = ret; 2654 goto out; 2655 } 2656 } 2657 stp = nstp; 2658 } 2659 } 2660 NFSUNLOCKSTATE(); 2661 if (haslock) { 2662 NFSLOCKV4ROOTMUTEX(); 2663 nfsv4_unlock(&nfsv4rootfs_lock, 1); 2664 NFSUNLOCKV4ROOTMUTEX(); 2665 } 2666 2667 out: 2668 NFSEXITCODE2(error, nd); 2669 return (error); 2670 } 2671 2672 /* 2673 * Open control function to create/update open state for an open. 2674 */ 2675 int 2676 nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp, 2677 struct nfsstate **new_stpp, nfsquad_t clientid, nfsv4stateid_t *stateidp, 2678 nfsv4stateid_t *delegstateidp, u_int32_t *rflagsp, struct nfsexstuff *exp, 2679 NFSPROC_T *p, u_quad_t filerev) 2680 { 2681 struct nfsstate *new_stp = *new_stpp; 2682 struct nfsstate *stp, *nstp; 2683 struct nfsstate *openstp = NULL, *new_open, *ownerstp, *new_deleg; 2684 struct nfslockfile *lfp, *new_lfp; 2685 struct nfsclient *clp; 2686 int error = 0, haslock = 0, ret, delegate = 1, writedeleg = 1; 2687 int readonly = 0, cbret = 1, getfhret = 0; 2688 int gotstate = 0, len = 0; 2689 u_char *clidp = NULL; 2690 2691 if ((new_stp->ls_flags & NFSLCK_SHAREBITS) == NFSLCK_READACCESS) 2692 readonly = 1; 2693 /* 2694 * Check for restart conditions (client and server). 2695 * (Paranoia, should have been detected by nfsrv_opencheck().) 2696 * If an error does show up, return NFSERR_EXPIRED, since the 2697 * the seqid# has already been incremented. 2698 */ 2699 error = nfsrv_checkrestart(clientid, new_stp->ls_flags, 2700 &new_stp->ls_stateid, 0); 2701 if (error) { 2702 printf("Nfsd: openctrl unexpected restart err=%d\n", 2703 error); 2704 error = NFSERR_EXPIRED; 2705 goto out; 2706 } 2707 2708 clidp = malloc(NFSV4_OPAQUELIMIT, M_TEMP, M_WAITOK); 2709 tryagain: 2710 new_lfp = malloc(sizeof (struct nfslockfile), 2711 M_NFSDLOCKFILE, M_WAITOK); 2712 new_open = malloc(sizeof (struct nfsstate), 2713 M_NFSDSTATE, M_WAITOK); 2714 new_deleg = malloc(sizeof (struct nfsstate), 2715 M_NFSDSTATE, M_WAITOK); 2716 getfhret = nfsrv_getlockfh(vp, new_stp->ls_flags, new_lfp, 2717 NULL, p); 2718 NFSLOCKSTATE(); 2719 /* 2720 * Get the client structure. Since the linked lists could be changed 2721 * by other nfsd processes if this process does a tsleep(), one of 2722 * two things must be done. 2723 * 1 - don't tsleep() 2724 * or 2725 * 2 - get the nfsv4_lock() { indicated by haslock == 1 } 2726 * before using the lists, since this lock stops the other 2727 * nfsd. This should only be used for rare cases, since it 2728 * essentially single threads the nfsd. 2729 * At this time, it is only done for cases where the stable 2730 * storage file must be written prior to completion of state 2731 * expiration. 2732 */ 2733 error = nfsrv_getclient(clientid, CLOPS_RENEW, &clp, NULL, 2734 (nfsquad_t)((u_quad_t)0), 0, nd, p); 2735 if (!error && (clp->lc_flags & LCL_NEEDSCBNULL) && 2736 clp->lc_program) { 2737 /* 2738 * This happens on the first open for a client 2739 * that supports callbacks. 2740 */ 2741 NFSUNLOCKSTATE(); 2742 /* 2743 * Although nfsrv_docallback() will sleep, clp won't 2744 * go away, since they are only removed when the 2745 * nfsv4_lock() has blocked the nfsd threads. The 2746 * fields in clp can change, but having multiple 2747 * threads do this Null callback RPC should be 2748 * harmless. 2749 */ 2750 cbret = nfsrv_docallback(clp, NFSV4PROC_CBNULL, 2751 NULL, 0, NULL, NULL, NULL, 0, p); 2752 NFSLOCKSTATE(); 2753 clp->lc_flags &= ~LCL_NEEDSCBNULL; 2754 if (!cbret) 2755 clp->lc_flags |= LCL_CALLBACKSON; 2756 } 2757 2758 /* 2759 * Look up the open owner. See if it needs confirmation and 2760 * check the seq#, as required. 2761 */ 2762 if (!error) 2763 nfsrv_getowner(&clp->lc_open, new_stp, &ownerstp); 2764 2765 if (error) { 2766 NFSUNLOCKSTATE(); 2767 printf("Nfsd: openctrl unexpected state err=%d\n", 2768 error); 2769 free(new_lfp, M_NFSDLOCKFILE); 2770 free(new_open, M_NFSDSTATE); 2771 free(new_deleg, M_NFSDSTATE); 2772 if (haslock) { 2773 NFSLOCKV4ROOTMUTEX(); 2774 nfsv4_unlock(&nfsv4rootfs_lock, 1); 2775 NFSUNLOCKV4ROOTMUTEX(); 2776 } 2777 error = NFSERR_EXPIRED; 2778 goto out; 2779 } 2780 2781 if (new_stp->ls_flags & NFSLCK_RECLAIM) 2782 nfsrv_markstable(clp); 2783 2784 /* 2785 * Get the structure for the underlying file. 2786 */ 2787 if (getfhret) 2788 error = getfhret; 2789 else 2790 error = nfsrv_getlockfile(new_stp->ls_flags, &new_lfp, &lfp, 2791 NULL, 0); 2792 if (new_lfp) 2793 free(new_lfp, M_NFSDLOCKFILE); 2794 if (error) { 2795 NFSUNLOCKSTATE(); 2796 printf("Nfsd openctrl unexpected getlockfile err=%d\n", 2797 error); 2798 free(new_open, M_NFSDSTATE); 2799 free(new_deleg, M_NFSDSTATE); 2800 if (haslock) { 2801 NFSLOCKV4ROOTMUTEX(); 2802 nfsv4_unlock(&nfsv4rootfs_lock, 1); 2803 NFSUNLOCKV4ROOTMUTEX(); 2804 } 2805 goto out; 2806 } 2807 2808 /* 2809 * Search for a conflicting open/share. 2810 */ 2811 if (new_stp->ls_flags & NFSLCK_DELEGCUR) { 2812 /* 2813 * For Delegate_Cur, search for the matching Delegation, 2814 * which indicates no conflict. 2815 * An old delegation should have been recovered by the 2816 * client doing a Claim_DELEGATE_Prev, so I won't let 2817 * it match and return NFSERR_EXPIRED. Should I let it 2818 * match? 2819 */ 2820 LIST_FOREACH(stp, &lfp->lf_deleg, ls_file) { 2821 if (!(stp->ls_flags & NFSLCK_OLDDELEG) && 2822 (((nd->nd_flag & ND_NFSV41) != 0 && 2823 stateidp->seqid == 0) || 2824 stateidp->seqid == stp->ls_stateid.seqid) && 2825 !NFSBCMP(stateidp->other, stp->ls_stateid.other, 2826 NFSX_STATEIDOTHER)) 2827 break; 2828 } 2829 if (stp == LIST_END(&lfp->lf_deleg) || 2830 ((new_stp->ls_flags & NFSLCK_WRITEACCESS) && 2831 (stp->ls_flags & NFSLCK_DELEGREAD))) { 2832 NFSUNLOCKSTATE(); 2833 printf("Nfsd openctrl unexpected expiry\n"); 2834 free(new_open, M_NFSDSTATE); 2835 free(new_deleg, M_NFSDSTATE); 2836 if (haslock) { 2837 NFSLOCKV4ROOTMUTEX(); 2838 nfsv4_unlock(&nfsv4rootfs_lock, 1); 2839 NFSUNLOCKV4ROOTMUTEX(); 2840 } 2841 error = NFSERR_EXPIRED; 2842 goto out; 2843 } 2844 2845 /* 2846 * Don't issue a Delegation, since one already exists and 2847 * delay delegation timeout, as required. 2848 */ 2849 delegate = 0; 2850 nfsrv_delaydelegtimeout(stp); 2851 } 2852 2853 /* 2854 * Check for access/deny bit conflicts. I also check for the 2855 * same owner, since the client might not have bothered to check. 2856 * Also, note an open for the same file and owner, if found, 2857 * which is all we do here for Delegate_Cur, since conflict 2858 * checking is already done. 2859 */ 2860 LIST_FOREACH(stp, &lfp->lf_open, ls_file) { 2861 if (ownerstp && stp->ls_openowner == ownerstp) 2862 openstp = stp; 2863 if (!(new_stp->ls_flags & NFSLCK_DELEGCUR)) { 2864 /* 2865 * If another client has the file open, the only 2866 * delegation that can be issued is a Read delegation 2867 * and only if it is a Read open with Deny none. 2868 */ 2869 if (clp != stp->ls_clp) { 2870 if ((stp->ls_flags & NFSLCK_SHAREBITS) == 2871 NFSLCK_READACCESS) 2872 writedeleg = 0; 2873 else 2874 delegate = 0; 2875 } 2876 if(((new_stp->ls_flags & NFSLCK_ACCESSBITS) & 2877 ((stp->ls_flags>>NFSLCK_SHIFT) & NFSLCK_ACCESSBITS))|| 2878 ((stp->ls_flags & NFSLCK_ACCESSBITS) & 2879 ((new_stp->ls_flags>>NFSLCK_SHIFT)&NFSLCK_ACCESSBITS))){ 2880 ret = nfsrv_clientconflict(stp->ls_clp,&haslock,vp,p); 2881 if (ret == 1) { 2882 /* 2883 * nfsrv_clientconflict() unlocks state 2884 * when it returns non-zero. 2885 */ 2886 free(new_open, M_NFSDSTATE); 2887 free(new_deleg, M_NFSDSTATE); 2888 openstp = NULL; 2889 goto tryagain; 2890 } 2891 if (ret == 2) 2892 error = NFSERR_PERM; 2893 else if (new_stp->ls_flags & NFSLCK_RECLAIM) 2894 error = NFSERR_RECLAIMCONFLICT; 2895 else 2896 error = NFSERR_SHAREDENIED; 2897 if (ret == 0) 2898 NFSUNLOCKSTATE(); 2899 if (haslock) { 2900 NFSLOCKV4ROOTMUTEX(); 2901 nfsv4_unlock(&nfsv4rootfs_lock, 1); 2902 NFSUNLOCKV4ROOTMUTEX(); 2903 } 2904 free(new_open, M_NFSDSTATE); 2905 free(new_deleg, M_NFSDSTATE); 2906 printf("nfsd openctrl unexpected client cnfl\n"); 2907 goto out; 2908 } 2909 } 2910 } 2911 2912 /* 2913 * Check for a conflicting delegation. If one is found, call 2914 * nfsrv_delegconflict() to handle it. If the v4root lock hasn't 2915 * been set yet, it will get the lock. Otherwise, it will recall 2916 * the delegation. Then, we try try again... 2917 * (If NFSLCK_DELEGCUR is set, it has a delegation, so there 2918 * isn't a conflict.) 2919 * I currently believe the conflict algorithm to be: 2920 * For Open with Read Access and Deny None 2921 * - there is a conflict iff a different client has a write delegation 2922 * For Open with other Write Access or any Deny except None 2923 * - there is a conflict if a different client has any delegation 2924 * - there is a conflict if the same client has a read delegation 2925 * (The current consensus is that this last case should be 2926 * considered a conflict since the client with a read delegation 2927 * could have done an Open with ReadAccess and WriteDeny 2928 * locally and then not have checked for the WriteDeny.) 2929 */ 2930 if (!(new_stp->ls_flags & (NFSLCK_DELEGPREV | NFSLCK_DELEGCUR))) { 2931 stp = LIST_FIRST(&lfp->lf_deleg); 2932 while (stp != LIST_END(&lfp->lf_deleg)) { 2933 nstp = LIST_NEXT(stp, ls_file); 2934 if (stp->ls_clp != clp && (stp->ls_flags & NFSLCK_DELEGREAD)) 2935 writedeleg = 0; 2936 else 2937 delegate = 0; 2938 if ((readonly && stp->ls_clp != clp && 2939 (stp->ls_flags & NFSLCK_DELEGWRITE)) || 2940 (!readonly && (stp->ls_clp != clp || 2941 (stp->ls_flags & NFSLCK_DELEGREAD)))) { 2942 if (new_stp->ls_flags & NFSLCK_RECLAIM) { 2943 delegate = 2; 2944 } else { 2945 ret = nfsrv_delegconflict(stp, &haslock, p, vp); 2946 if (ret) { 2947 /* 2948 * nfsrv_delegconflict() unlocks state 2949 * when it returns non-zero. 2950 */ 2951 printf("Nfsd openctrl unexpected deleg cnfl\n"); 2952 free(new_open, M_NFSDSTATE); 2953 free(new_deleg, M_NFSDSTATE); 2954 if (ret == -1) { 2955 openstp = NULL; 2956 goto tryagain; 2957 } 2958 error = ret; 2959 goto out; 2960 } 2961 } 2962 } 2963 stp = nstp; 2964 } 2965 } 2966 2967 /* 2968 * We only get here if there was no open that conflicted. 2969 * If an open for the owner exists, or in the access/deny bits. 2970 * Otherwise it is a new open. If the open_owner hasn't been 2971 * confirmed, replace the open with the new one needing confirmation, 2972 * otherwise add the open. 2973 */ 2974 if (new_stp->ls_flags & NFSLCK_DELEGPREV) { 2975 /* 2976 * Handle NFSLCK_DELEGPREV by searching the old delegations for 2977 * a match. If found, just move the old delegation to the current 2978 * delegation list and issue open. If not found, return 2979 * NFSERR_EXPIRED. 2980 */ 2981 LIST_FOREACH(stp, &clp->lc_olddeleg, ls_list) { 2982 if (stp->ls_lfp == lfp) { 2983 /* Found it */ 2984 if (stp->ls_clp != clp) 2985 panic("olddeleg clp"); 2986 LIST_REMOVE(stp, ls_list); 2987 LIST_REMOVE(stp, ls_hash); 2988 stp->ls_flags &= ~NFSLCK_OLDDELEG; 2989 stp->ls_stateid.seqid = delegstateidp->seqid = 1; 2990 stp->ls_stateid.other[0] = delegstateidp->other[0] = 2991 clp->lc_clientid.lval[0]; 2992 stp->ls_stateid.other[1] = delegstateidp->other[1] = 2993 clp->lc_clientid.lval[1]; 2994 stp->ls_stateid.other[2] = delegstateidp->other[2] = 2995 nfsrv_nextstateindex(clp); 2996 stp->ls_compref = nd->nd_compref; 2997 LIST_INSERT_HEAD(&clp->lc_deleg, stp, ls_list); 2998 LIST_INSERT_HEAD(NFSSTATEHASH(clp, 2999 stp->ls_stateid), stp, ls_hash); 3000 if (stp->ls_flags & NFSLCK_DELEGWRITE) 3001 *rflagsp |= NFSV4OPEN_WRITEDELEGATE; 3002 else 3003 *rflagsp |= NFSV4OPEN_READDELEGATE; 3004 clp->lc_delegtime = NFSD_MONOSEC + 3005 nfsrv_lease + NFSRV_LEASEDELTA; 3006 3007 /* 3008 * Now, do the associated open. 3009 */ 3010 new_open->ls_stateid.seqid = 1; 3011 new_open->ls_stateid.other[0] = clp->lc_clientid.lval[0]; 3012 new_open->ls_stateid.other[1] = clp->lc_clientid.lval[1]; 3013 new_open->ls_stateid.other[2] = nfsrv_nextstateindex(clp); 3014 new_open->ls_flags = (new_stp->ls_flags&NFSLCK_DENYBITS)| 3015 NFSLCK_OPEN; 3016 if (stp->ls_flags & NFSLCK_DELEGWRITE) 3017 new_open->ls_flags |= (NFSLCK_READACCESS | 3018 NFSLCK_WRITEACCESS); 3019 else 3020 new_open->ls_flags |= NFSLCK_READACCESS; 3021 new_open->ls_uid = new_stp->ls_uid; 3022 new_open->ls_lfp = lfp; 3023 new_open->ls_clp = clp; 3024 LIST_INIT(&new_open->ls_open); 3025 LIST_INSERT_HEAD(&lfp->lf_open, new_open, ls_file); 3026 LIST_INSERT_HEAD(NFSSTATEHASH(clp, new_open->ls_stateid), 3027 new_open, ls_hash); 3028 /* 3029 * and handle the open owner 3030 */ 3031 if (ownerstp) { 3032 new_open->ls_openowner = ownerstp; 3033 LIST_INSERT_HEAD(&ownerstp->ls_open,new_open,ls_list); 3034 } else { 3035 new_open->ls_openowner = new_stp; 3036 new_stp->ls_flags = 0; 3037 nfsrvd_refcache(new_stp->ls_op); 3038 new_stp->ls_noopens = 0; 3039 LIST_INIT(&new_stp->ls_open); 3040 LIST_INSERT_HEAD(&new_stp->ls_open, new_open, ls_list); 3041 LIST_INSERT_HEAD(&clp->lc_open, new_stp, ls_list); 3042 *new_stpp = NULL; 3043 nfsstatsv1.srvopenowners++; 3044 nfsrv_openpluslock++; 3045 } 3046 openstp = new_open; 3047 new_open = NULL; 3048 nfsstatsv1.srvopens++; 3049 nfsrv_openpluslock++; 3050 break; 3051 } 3052 } 3053 if (stp == LIST_END(&clp->lc_olddeleg)) 3054 error = NFSERR_EXPIRED; 3055 } else if (new_stp->ls_flags & (NFSLCK_DELEGREAD | NFSLCK_DELEGWRITE)) { 3056 /* 3057 * Scan to see that no delegation for this client and file 3058 * doesn't already exist. 3059 * There also shouldn't yet be an Open for this file and 3060 * openowner. 3061 */ 3062 LIST_FOREACH(stp, &lfp->lf_deleg, ls_file) { 3063 if (stp->ls_clp == clp) 3064 break; 3065 } 3066 if (stp == LIST_END(&lfp->lf_deleg) && openstp == NULL) { 3067 /* 3068 * This is the Claim_Previous case with a delegation 3069 * type != Delegate_None. 3070 */ 3071 /* 3072 * First, add the delegation. (Although we must issue the 3073 * delegation, we can also ask for an immediate return.) 3074 */ 3075 new_deleg->ls_stateid.seqid = delegstateidp->seqid = 1; 3076 new_deleg->ls_stateid.other[0] = delegstateidp->other[0] = 3077 clp->lc_clientid.lval[0]; 3078 new_deleg->ls_stateid.other[1] = delegstateidp->other[1] = 3079 clp->lc_clientid.lval[1]; 3080 new_deleg->ls_stateid.other[2] = delegstateidp->other[2] = 3081 nfsrv_nextstateindex(clp); 3082 if (new_stp->ls_flags & NFSLCK_DELEGWRITE) { 3083 new_deleg->ls_flags = (NFSLCK_DELEGWRITE | 3084 NFSLCK_READACCESS | NFSLCK_WRITEACCESS); 3085 *rflagsp |= NFSV4OPEN_WRITEDELEGATE; 3086 nfsrv_writedelegcnt++; 3087 } else { 3088 new_deleg->ls_flags = (NFSLCK_DELEGREAD | 3089 NFSLCK_READACCESS); 3090 *rflagsp |= NFSV4OPEN_READDELEGATE; 3091 } 3092 new_deleg->ls_uid = new_stp->ls_uid; 3093 new_deleg->ls_lfp = lfp; 3094 new_deleg->ls_clp = clp; 3095 new_deleg->ls_filerev = filerev; 3096 new_deleg->ls_compref = nd->nd_compref; 3097 new_deleg->ls_lastrecall = 0; 3098 LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, ls_file); 3099 LIST_INSERT_HEAD(NFSSTATEHASH(clp, 3100 new_deleg->ls_stateid), new_deleg, ls_hash); 3101 LIST_INSERT_HEAD(&clp->lc_deleg, new_deleg, ls_list); 3102 new_deleg = NULL; 3103 if (delegate == 2 || nfsrv_issuedelegs == 0 || 3104 (clp->lc_flags & (LCL_CALLBACKSON | LCL_CBDOWN)) != 3105 LCL_CALLBACKSON || 3106 NFSRV_V4DELEGLIMIT(nfsrv_delegatecnt) || 3107 !NFSVNO_DELEGOK(vp)) 3108 *rflagsp |= NFSV4OPEN_RECALL; 3109 nfsstatsv1.srvdelegates++; 3110 nfsrv_openpluslock++; 3111 nfsrv_delegatecnt++; 3112 3113 /* 3114 * Now, do the associated open. 3115 */ 3116 new_open->ls_stateid.seqid = 1; 3117 new_open->ls_stateid.other[0] = clp->lc_clientid.lval[0]; 3118 new_open->ls_stateid.other[1] = clp->lc_clientid.lval[1]; 3119 new_open->ls_stateid.other[2] = nfsrv_nextstateindex(clp); 3120 new_open->ls_flags = (new_stp->ls_flags & NFSLCK_DENYBITS) | 3121 NFSLCK_OPEN; 3122 if (new_stp->ls_flags & NFSLCK_DELEGWRITE) 3123 new_open->ls_flags |= (NFSLCK_READACCESS | 3124 NFSLCK_WRITEACCESS); 3125 else 3126 new_open->ls_flags |= NFSLCK_READACCESS; 3127 new_open->ls_uid = new_stp->ls_uid; 3128 new_open->ls_lfp = lfp; 3129 new_open->ls_clp = clp; 3130 LIST_INIT(&new_open->ls_open); 3131 LIST_INSERT_HEAD(&lfp->lf_open, new_open, ls_file); 3132 LIST_INSERT_HEAD(NFSSTATEHASH(clp, new_open->ls_stateid), 3133 new_open, ls_hash); 3134 /* 3135 * and handle the open owner 3136 */ 3137 if (ownerstp) { 3138 new_open->ls_openowner = ownerstp; 3139 LIST_INSERT_HEAD(&ownerstp->ls_open, new_open, ls_list); 3140 } else { 3141 new_open->ls_openowner = new_stp; 3142 new_stp->ls_flags = 0; 3143 nfsrvd_refcache(new_stp->ls_op); 3144 new_stp->ls_noopens = 0; 3145 LIST_INIT(&new_stp->ls_open); 3146 LIST_INSERT_HEAD(&new_stp->ls_open, new_open, ls_list); 3147 LIST_INSERT_HEAD(&clp->lc_open, new_stp, ls_list); 3148 *new_stpp = NULL; 3149 nfsstatsv1.srvopenowners++; 3150 nfsrv_openpluslock++; 3151 } 3152 openstp = new_open; 3153 new_open = NULL; 3154 nfsstatsv1.srvopens++; 3155 nfsrv_openpluslock++; 3156 } else { 3157 error = NFSERR_RECLAIMCONFLICT; 3158 } 3159 } else if (ownerstp) { 3160 if (ownerstp->ls_flags & NFSLCK_NEEDSCONFIRM) { 3161 /* Replace the open */ 3162 if (ownerstp->ls_op) 3163 nfsrvd_derefcache(ownerstp->ls_op); 3164 ownerstp->ls_op = new_stp->ls_op; 3165 nfsrvd_refcache(ownerstp->ls_op); 3166 ownerstp->ls_seq = new_stp->ls_seq; 3167 *rflagsp |= NFSV4OPEN_RESULTCONFIRM; 3168 stp = LIST_FIRST(&ownerstp->ls_open); 3169 stp->ls_flags = (new_stp->ls_flags & NFSLCK_SHAREBITS) | 3170 NFSLCK_OPEN; 3171 stp->ls_stateid.seqid = 1; 3172 stp->ls_uid = new_stp->ls_uid; 3173 if (lfp != stp->ls_lfp) { 3174 LIST_REMOVE(stp, ls_file); 3175 LIST_INSERT_HEAD(&lfp->lf_open, stp, ls_file); 3176 stp->ls_lfp = lfp; 3177 } 3178 openstp = stp; 3179 } else if (openstp) { 3180 openstp->ls_flags |= (new_stp->ls_flags & NFSLCK_SHAREBITS); 3181 openstp->ls_stateid.seqid++; 3182 if ((nd->nd_flag & ND_NFSV41) != 0 && 3183 openstp->ls_stateid.seqid == 0) 3184 openstp->ls_stateid.seqid = 1; 3185 3186 /* 3187 * This is where we can choose to issue a delegation. 3188 */ 3189 if ((new_stp->ls_flags & NFSLCK_WANTNODELEG) != 0) 3190 *rflagsp |= NFSV4OPEN_WDNOTWANTED; 3191 else if (nfsrv_issuedelegs == 0) 3192 *rflagsp |= NFSV4OPEN_WDSUPPFTYPE; 3193 else if (NFSRV_V4DELEGLIMIT(nfsrv_delegatecnt)) 3194 *rflagsp |= NFSV4OPEN_WDRESOURCE; 3195 else if (delegate == 0 || writedeleg == 0 || 3196 NFSVNO_EXRDONLY(exp) || (readonly != 0 && 3197 nfsrv_writedelegifpos == 0) || 3198 !NFSVNO_DELEGOK(vp) || 3199 (new_stp->ls_flags & NFSLCK_WANTRDELEG) != 0 || 3200 (clp->lc_flags & (LCL_CALLBACKSON | LCL_CBDOWN)) != 3201 LCL_CALLBACKSON) 3202 *rflagsp |= NFSV4OPEN_WDCONTENTION; 3203 else { 3204 new_deleg->ls_stateid.seqid = delegstateidp->seqid = 1; 3205 new_deleg->ls_stateid.other[0] = delegstateidp->other[0] 3206 = clp->lc_clientid.lval[0]; 3207 new_deleg->ls_stateid.other[1] = delegstateidp->other[1] 3208 = clp->lc_clientid.lval[1]; 3209 new_deleg->ls_stateid.other[2] = delegstateidp->other[2] 3210 = nfsrv_nextstateindex(clp); 3211 new_deleg->ls_flags = (NFSLCK_DELEGWRITE | 3212 NFSLCK_READACCESS | NFSLCK_WRITEACCESS); 3213 *rflagsp |= NFSV4OPEN_WRITEDELEGATE; 3214 new_deleg->ls_uid = new_stp->ls_uid; 3215 new_deleg->ls_lfp = lfp; 3216 new_deleg->ls_clp = clp; 3217 new_deleg->ls_filerev = filerev; 3218 new_deleg->ls_compref = nd->nd_compref; 3219 new_deleg->ls_lastrecall = 0; 3220 nfsrv_writedelegcnt++; 3221 LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, ls_file); 3222 LIST_INSERT_HEAD(NFSSTATEHASH(clp, 3223 new_deleg->ls_stateid), new_deleg, ls_hash); 3224 LIST_INSERT_HEAD(&clp->lc_deleg, new_deleg, ls_list); 3225 new_deleg = NULL; 3226 nfsstatsv1.srvdelegates++; 3227 nfsrv_openpluslock++; 3228 nfsrv_delegatecnt++; 3229 } 3230 } else { 3231 new_open->ls_stateid.seqid = 1; 3232 new_open->ls_stateid.other[0] = clp->lc_clientid.lval[0]; 3233 new_open->ls_stateid.other[1] = clp->lc_clientid.lval[1]; 3234 new_open->ls_stateid.other[2] = nfsrv_nextstateindex(clp); 3235 new_open->ls_flags = (new_stp->ls_flags & NFSLCK_SHAREBITS)| 3236 NFSLCK_OPEN; 3237 new_open->ls_uid = new_stp->ls_uid; 3238 new_open->ls_openowner = ownerstp; 3239 new_open->ls_lfp = lfp; 3240 new_open->ls_clp = clp; 3241 LIST_INIT(&new_open->ls_open); 3242 LIST_INSERT_HEAD(&lfp->lf_open, new_open, ls_file); 3243 LIST_INSERT_HEAD(&ownerstp->ls_open, new_open, ls_list); 3244 LIST_INSERT_HEAD(NFSSTATEHASH(clp, new_open->ls_stateid), 3245 new_open, ls_hash); 3246 openstp = new_open; 3247 new_open = NULL; 3248 nfsstatsv1.srvopens++; 3249 nfsrv_openpluslock++; 3250 3251 /* 3252 * This is where we can choose to issue a delegation. 3253 */ 3254 if ((new_stp->ls_flags & NFSLCK_WANTNODELEG) != 0) 3255 *rflagsp |= NFSV4OPEN_WDNOTWANTED; 3256 else if (nfsrv_issuedelegs == 0) 3257 *rflagsp |= NFSV4OPEN_WDSUPPFTYPE; 3258 else if (NFSRV_V4DELEGLIMIT(nfsrv_delegatecnt)) 3259 *rflagsp |= NFSV4OPEN_WDRESOURCE; 3260 else if (delegate == 0 || (writedeleg == 0 && 3261 readonly == 0) || !NFSVNO_DELEGOK(vp) || 3262 (clp->lc_flags & (LCL_CALLBACKSON | LCL_CBDOWN)) != 3263 LCL_CALLBACKSON) 3264 *rflagsp |= NFSV4OPEN_WDCONTENTION; 3265 else { 3266 new_deleg->ls_stateid.seqid = delegstateidp->seqid = 1; 3267 new_deleg->ls_stateid.other[0] = delegstateidp->other[0] 3268 = clp->lc_clientid.lval[0]; 3269 new_deleg->ls_stateid.other[1] = delegstateidp->other[1] 3270 = clp->lc_clientid.lval[1]; 3271 new_deleg->ls_stateid.other[2] = delegstateidp->other[2] 3272 = nfsrv_nextstateindex(clp); 3273 if (writedeleg && !NFSVNO_EXRDONLY(exp) && 3274 (nfsrv_writedelegifpos || !readonly) && 3275 (new_stp->ls_flags & NFSLCK_WANTRDELEG) == 0) { 3276 new_deleg->ls_flags = (NFSLCK_DELEGWRITE | 3277 NFSLCK_READACCESS | NFSLCK_WRITEACCESS); 3278 *rflagsp |= NFSV4OPEN_WRITEDELEGATE; 3279 nfsrv_writedelegcnt++; 3280 } else { 3281 new_deleg->ls_flags = (NFSLCK_DELEGREAD | 3282 NFSLCK_READACCESS); 3283 *rflagsp |= NFSV4OPEN_READDELEGATE; 3284 } 3285 new_deleg->ls_uid = new_stp->ls_uid; 3286 new_deleg->ls_lfp = lfp; 3287 new_deleg->ls_clp = clp; 3288 new_deleg->ls_filerev = filerev; 3289 new_deleg->ls_compref = nd->nd_compref; 3290 new_deleg->ls_lastrecall = 0; 3291 LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, ls_file); 3292 LIST_INSERT_HEAD(NFSSTATEHASH(clp, 3293 new_deleg->ls_stateid), new_deleg, ls_hash); 3294 LIST_INSERT_HEAD(&clp->lc_deleg, new_deleg, ls_list); 3295 new_deleg = NULL; 3296 nfsstatsv1.srvdelegates++; 3297 nfsrv_openpluslock++; 3298 nfsrv_delegatecnt++; 3299 } 3300 } 3301 } else { 3302 /* 3303 * New owner case. Start the open_owner sequence with a 3304 * Needs confirmation (unless a reclaim) and hang the 3305 * new open off it. 3306 */ 3307 new_open->ls_stateid.seqid = 1; 3308 new_open->ls_stateid.other[0] = clp->lc_clientid.lval[0]; 3309 new_open->ls_stateid.other[1] = clp->lc_clientid.lval[1]; 3310 new_open->ls_stateid.other[2] = nfsrv_nextstateindex(clp); 3311 new_open->ls_flags = (new_stp->ls_flags & NFSLCK_SHAREBITS) | 3312 NFSLCK_OPEN; 3313 new_open->ls_uid = new_stp->ls_uid; 3314 LIST_INIT(&new_open->ls_open); 3315 new_open->ls_openowner = new_stp; 3316 new_open->ls_lfp = lfp; 3317 new_open->ls_clp = clp; 3318 LIST_INSERT_HEAD(&lfp->lf_open, new_open, ls_file); 3319 if (new_stp->ls_flags & NFSLCK_RECLAIM) { 3320 new_stp->ls_flags = 0; 3321 } else if ((nd->nd_flag & ND_NFSV41) != 0) { 3322 /* NFSv4.1 never needs confirmation. */ 3323 new_stp->ls_flags = 0; 3324 3325 /* 3326 * This is where we can choose to issue a delegation. 3327 */ 3328 if (delegate && nfsrv_issuedelegs && 3329 (writedeleg || readonly) && 3330 (clp->lc_flags & (LCL_CALLBACKSON | LCL_CBDOWN)) == 3331 LCL_CALLBACKSON && 3332 !NFSRV_V4DELEGLIMIT(nfsrv_delegatecnt) && 3333 NFSVNO_DELEGOK(vp) && 3334 ((nd->nd_flag & ND_NFSV41) == 0 || 3335 (new_stp->ls_flags & NFSLCK_WANTNODELEG) == 0)) { 3336 new_deleg->ls_stateid.seqid = 3337 delegstateidp->seqid = 1; 3338 new_deleg->ls_stateid.other[0] = 3339 delegstateidp->other[0] 3340 = clp->lc_clientid.lval[0]; 3341 new_deleg->ls_stateid.other[1] = 3342 delegstateidp->other[1] 3343 = clp->lc_clientid.lval[1]; 3344 new_deleg->ls_stateid.other[2] = 3345 delegstateidp->other[2] 3346 = nfsrv_nextstateindex(clp); 3347 if (writedeleg && !NFSVNO_EXRDONLY(exp) && 3348 (nfsrv_writedelegifpos || !readonly) && 3349 ((nd->nd_flag & ND_NFSV41) == 0 || 3350 (new_stp->ls_flags & NFSLCK_WANTRDELEG) == 3351 0)) { 3352 new_deleg->ls_flags = 3353 (NFSLCK_DELEGWRITE | 3354 NFSLCK_READACCESS | 3355 NFSLCK_WRITEACCESS); 3356 *rflagsp |= NFSV4OPEN_WRITEDELEGATE; 3357 nfsrv_writedelegcnt++; 3358 } else { 3359 new_deleg->ls_flags = 3360 (NFSLCK_DELEGREAD | 3361 NFSLCK_READACCESS); 3362 *rflagsp |= NFSV4OPEN_READDELEGATE; 3363 } 3364 new_deleg->ls_uid = new_stp->ls_uid; 3365 new_deleg->ls_lfp = lfp; 3366 new_deleg->ls_clp = clp; 3367 new_deleg->ls_filerev = filerev; 3368 new_deleg->ls_compref = nd->nd_compref; 3369 new_deleg->ls_lastrecall = 0; 3370 LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, 3371 ls_file); 3372 LIST_INSERT_HEAD(NFSSTATEHASH(clp, 3373 new_deleg->ls_stateid), new_deleg, ls_hash); 3374 LIST_INSERT_HEAD(&clp->lc_deleg, new_deleg, 3375 ls_list); 3376 new_deleg = NULL; 3377 nfsstatsv1.srvdelegates++; 3378 nfsrv_openpluslock++; 3379 nfsrv_delegatecnt++; 3380 } 3381 /* 3382 * Since NFSv4.1 never does an OpenConfirm, the first 3383 * open state will be acquired here. 3384 */ 3385 if (!(clp->lc_flags & LCL_STAMPEDSTABLE)) { 3386 clp->lc_flags |= LCL_STAMPEDSTABLE; 3387 len = clp->lc_idlen; 3388 NFSBCOPY(clp->lc_id, clidp, len); 3389 gotstate = 1; 3390 } 3391 } else { 3392 *rflagsp |= NFSV4OPEN_RESULTCONFIRM; 3393 new_stp->ls_flags = NFSLCK_NEEDSCONFIRM; 3394 } 3395 nfsrvd_refcache(new_stp->ls_op); 3396 new_stp->ls_noopens = 0; 3397 LIST_INIT(&new_stp->ls_open); 3398 LIST_INSERT_HEAD(&new_stp->ls_open, new_open, ls_list); 3399 LIST_INSERT_HEAD(&clp->lc_open, new_stp, ls_list); 3400 LIST_INSERT_HEAD(NFSSTATEHASH(clp, new_open->ls_stateid), 3401 new_open, ls_hash); 3402 openstp = new_open; 3403 new_open = NULL; 3404 *new_stpp = NULL; 3405 nfsstatsv1.srvopens++; 3406 nfsrv_openpluslock++; 3407 nfsstatsv1.srvopenowners++; 3408 nfsrv_openpluslock++; 3409 } 3410 if (!error) { 3411 stateidp->seqid = openstp->ls_stateid.seqid; 3412 stateidp->other[0] = openstp->ls_stateid.other[0]; 3413 stateidp->other[1] = openstp->ls_stateid.other[1]; 3414 stateidp->other[2] = openstp->ls_stateid.other[2]; 3415 } 3416 NFSUNLOCKSTATE(); 3417 if (haslock) { 3418 NFSLOCKV4ROOTMUTEX(); 3419 nfsv4_unlock(&nfsv4rootfs_lock, 1); 3420 NFSUNLOCKV4ROOTMUTEX(); 3421 } 3422 if (new_open) 3423 free(new_open, M_NFSDSTATE); 3424 if (new_deleg) 3425 free(new_deleg, M_NFSDSTATE); 3426 3427 /* 3428 * If the NFSv4.1 client just acquired its first open, write a timestamp 3429 * to the stable storage file. 3430 */ 3431 if (gotstate != 0) { 3432 nfsrv_writestable(clidp, len, NFSNST_NEWSTATE, p); 3433 nfsrv_backupstable(); 3434 } 3435 3436 out: 3437 free(clidp, M_TEMP); 3438 NFSEXITCODE2(error, nd); 3439 return (error); 3440 } 3441 3442 /* 3443 * Open update. Does the confirm, downgrade and close. 3444 */ 3445 int 3446 nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid, 3447 nfsv4stateid_t *stateidp, struct nfsrv_descript *nd, NFSPROC_T *p, 3448 int *retwriteaccessp) 3449 { 3450 struct nfsstate *stp; 3451 struct nfsclient *clp; 3452 struct nfslockfile *lfp; 3453 u_int32_t bits; 3454 int error = 0, gotstate = 0, len = 0; 3455 u_char *clidp = NULL; 3456 3457 /* 3458 * Check for restart conditions (client and server). 3459 */ 3460 error = nfsrv_checkrestart(clientid, new_stp->ls_flags, 3461 &new_stp->ls_stateid, 0); 3462 if (error) 3463 goto out; 3464 3465 clidp = malloc(NFSV4_OPAQUELIMIT, M_TEMP, M_WAITOK); 3466 NFSLOCKSTATE(); 3467 /* 3468 * Get the open structure via clientid and stateid. 3469 */ 3470 error = nfsrv_getclient(clientid, CLOPS_RENEW, &clp, NULL, 3471 (nfsquad_t)((u_quad_t)0), 0, nd, p); 3472 if (!error) 3473 error = nfsrv_getstate(clp, &new_stp->ls_stateid, 3474 new_stp->ls_flags, &stp); 3475 3476 /* 3477 * Sanity check the open. 3478 */ 3479 if (!error && (!(stp->ls_flags & NFSLCK_OPEN) || 3480 (!(new_stp->ls_flags & NFSLCK_CONFIRM) && 3481 (stp->ls_openowner->ls_flags & NFSLCK_NEEDSCONFIRM)) || 3482 ((new_stp->ls_flags & NFSLCK_CONFIRM) && 3483 (!(stp->ls_openowner->ls_flags & NFSLCK_NEEDSCONFIRM))))) 3484 error = NFSERR_BADSTATEID; 3485 3486 if (!error) 3487 error = nfsrv_checkseqid(nd, new_stp->ls_seq, 3488 stp->ls_openowner, new_stp->ls_op); 3489 if (!error && stp->ls_stateid.seqid != new_stp->ls_stateid.seqid && 3490 (((nd->nd_flag & ND_NFSV41) == 0 && 3491 !(new_stp->ls_flags & NFSLCK_CONFIRM)) || 3492 ((nd->nd_flag & ND_NFSV41) != 0 && 3493 new_stp->ls_stateid.seqid != 0))) 3494 error = NFSERR_OLDSTATEID; 3495 if (!error && vp->v_type != VREG) { 3496 if (vp->v_type == VDIR) 3497 error = NFSERR_ISDIR; 3498 else 3499 error = NFSERR_INVAL; 3500 } 3501 3502 if (error) { 3503 /* 3504 * If a client tries to confirm an Open with a bad 3505 * seqid# and there are no byte range locks or other Opens 3506 * on the openowner, just throw it away, so the next use of the 3507 * openowner will start a fresh seq#. 3508 */ 3509 if (error == NFSERR_BADSEQID && 3510 (new_stp->ls_flags & NFSLCK_CONFIRM) && 3511 nfsrv_nootherstate(stp)) 3512 nfsrv_freeopenowner(stp->ls_openowner, 0, p); 3513 NFSUNLOCKSTATE(); 3514 goto out; 3515 } 3516 3517 /* 3518 * Set the return stateid. 3519 */ 3520 stateidp->seqid = stp->ls_stateid.seqid + 1; 3521 if ((nd->nd_flag & ND_NFSV41) != 0 && stateidp->seqid == 0) 3522 stateidp->seqid = 1; 3523 stateidp->other[0] = stp->ls_stateid.other[0]; 3524 stateidp->other[1] = stp->ls_stateid.other[1]; 3525 stateidp->other[2] = stp->ls_stateid.other[2]; 3526 /* 3527 * Now, handle the three cases. 3528 */ 3529 if (new_stp->ls_flags & NFSLCK_CONFIRM) { 3530 /* 3531 * If the open doesn't need confirmation, it seems to me that 3532 * there is a client error, but I'll just log it and keep going? 3533 */ 3534 if (!(stp->ls_openowner->ls_flags & NFSLCK_NEEDSCONFIRM)) 3535 printf("Nfsv4d: stray open confirm\n"); 3536 stp->ls_openowner->ls_flags = 0; 3537 stp->ls_stateid.seqid++; 3538 if ((nd->nd_flag & ND_NFSV41) != 0 && 3539 stp->ls_stateid.seqid == 0) 3540 stp->ls_stateid.seqid = 1; 3541 if (!(clp->lc_flags & LCL_STAMPEDSTABLE)) { 3542 clp->lc_flags |= LCL_STAMPEDSTABLE; 3543 len = clp->lc_idlen; 3544 NFSBCOPY(clp->lc_id, clidp, len); 3545 gotstate = 1; 3546 } 3547 NFSUNLOCKSTATE(); 3548 } else if (new_stp->ls_flags & NFSLCK_CLOSE) { 3549 lfp = stp->ls_lfp; 3550 if (retwriteaccessp != NULL) { 3551 if ((stp->ls_flags & NFSLCK_WRITEACCESS) != 0) 3552 *retwriteaccessp = 1; 3553 else 3554 *retwriteaccessp = 0; 3555 } 3556 if (nfsrv_dolocallocks != 0 && !LIST_EMPTY(&stp->ls_open)) { 3557 /* Get the lf lock */ 3558 nfsrv_locklf(lfp); 3559 NFSUNLOCKSTATE(); 3560 ASSERT_VOP_ELOCKED(vp, "nfsrv_openupdate"); 3561 NFSVOPUNLOCK(vp); 3562 if (nfsrv_freeopen(stp, vp, 1, p) == 0) { 3563 NFSLOCKSTATE(); 3564 nfsrv_unlocklf(lfp); 3565 NFSUNLOCKSTATE(); 3566 } 3567 NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); 3568 } else { 3569 (void) nfsrv_freeopen(stp, NULL, 0, p); 3570 NFSUNLOCKSTATE(); 3571 } 3572 } else { 3573 /* 3574 * Update the share bits, making sure that the new set are a 3575 * subset of the old ones. 3576 */ 3577 bits = (new_stp->ls_flags & NFSLCK_SHAREBITS); 3578 if (~(stp->ls_flags) & bits) { 3579 NFSUNLOCKSTATE(); 3580 error = NFSERR_INVAL; 3581 goto out; 3582 } 3583 stp->ls_flags = (bits | NFSLCK_OPEN); 3584 stp->ls_stateid.seqid++; 3585 if ((nd->nd_flag & ND_NFSV41) != 0 && 3586 stp->ls_stateid.seqid == 0) 3587 stp->ls_stateid.seqid = 1; 3588 NFSUNLOCKSTATE(); 3589 } 3590 3591 /* 3592 * If the client just confirmed its first open, write a timestamp 3593 * to the stable storage file. 3594 */ 3595 if (gotstate != 0) { 3596 nfsrv_writestable(clidp, len, NFSNST_NEWSTATE, p); 3597 nfsrv_backupstable(); 3598 } 3599 3600 out: 3601 free(clidp, M_TEMP); 3602 NFSEXITCODE2(error, nd); 3603 return (error); 3604 } 3605 3606 /* 3607 * Delegation update. Does the purge and return. 3608 */ 3609 int 3610 nfsrv_delegupdate(struct nfsrv_descript *nd, nfsquad_t clientid, 3611 nfsv4stateid_t *stateidp, vnode_t vp, int op, struct ucred *cred, 3612 NFSPROC_T *p, int *retwriteaccessp) 3613 { 3614 struct nfsstate *stp; 3615 struct nfsclient *clp; 3616 int error = 0; 3617 fhandle_t fh; 3618 3619 /* 3620 * Do a sanity check against the file handle for DelegReturn. 3621 */ 3622 if (vp) { 3623 error = nfsvno_getfh(vp, &fh, p); 3624 if (error) 3625 goto out; 3626 } 3627 /* 3628 * Check for restart conditions (client and server). 3629 */ 3630 if (op == NFSV4OP_DELEGRETURN) 3631 error = nfsrv_checkrestart(clientid, NFSLCK_DELEGRETURN, 3632 stateidp, 0); 3633 else 3634 error = nfsrv_checkrestart(clientid, NFSLCK_DELEGPURGE, 3635 stateidp, 0); 3636 3637 NFSLOCKSTATE(); 3638 /* 3639 * Get the open structure via clientid and stateid. 3640 */ 3641 if (!error) 3642 error = nfsrv_getclient(clientid, CLOPS_RENEW, &clp, NULL, 3643 (nfsquad_t)((u_quad_t)0), 0, nd, p); 3644 if (error) { 3645 if (error == NFSERR_CBPATHDOWN) 3646 error = 0; 3647 if (error == NFSERR_STALECLIENTID && op == NFSV4OP_DELEGRETURN) 3648 error = NFSERR_STALESTATEID; 3649 } 3650 if (!error && op == NFSV4OP_DELEGRETURN) { 3651 error = nfsrv_getstate(clp, stateidp, NFSLCK_DELEGRETURN, &stp); 3652 if (!error && stp->ls_stateid.seqid != stateidp->seqid && 3653 ((nd->nd_flag & ND_NFSV41) == 0 || stateidp->seqid != 0)) 3654 error = NFSERR_OLDSTATEID; 3655 } 3656 /* 3657 * NFSERR_EXPIRED means that the state has gone away, 3658 * so Delegations have been purged. Just return ok. 3659 */ 3660 if (error == NFSERR_EXPIRED && op == NFSV4OP_DELEGPURGE) { 3661 NFSUNLOCKSTATE(); 3662 error = 0; 3663 goto out; 3664 } 3665 if (error) { 3666 NFSUNLOCKSTATE(); 3667 goto out; 3668 } 3669 3670 if (op == NFSV4OP_DELEGRETURN) { 3671 if (NFSBCMP((caddr_t)&fh, (caddr_t)&stp->ls_lfp->lf_fh, 3672 sizeof (fhandle_t))) { 3673 NFSUNLOCKSTATE(); 3674 error = NFSERR_BADSTATEID; 3675 goto out; 3676 } 3677 if (retwriteaccessp != NULL) { 3678 if ((stp->ls_flags & NFSLCK_DELEGWRITE) != 0) 3679 *retwriteaccessp = 1; 3680 else 3681 *retwriteaccessp = 0; 3682 } 3683 nfsrv_freedeleg(stp); 3684 } else { 3685 nfsrv_freedeleglist(&clp->lc_olddeleg); 3686 } 3687 NFSUNLOCKSTATE(); 3688 error = 0; 3689 3690 out: 3691 NFSEXITCODE(error); 3692 return (error); 3693 } 3694 3695 /* 3696 * Release lock owner. 3697 */ 3698 int 3699 nfsrv_releaselckown(struct nfsstate *new_stp, nfsquad_t clientid, 3700 NFSPROC_T *p) 3701 { 3702 struct nfsstate *stp, *nstp, *openstp, *ownstp; 3703 struct nfsclient *clp; 3704 int error = 0; 3705 3706 /* 3707 * Check for restart conditions (client and server). 3708 */ 3709 error = nfsrv_checkrestart(clientid, new_stp->ls_flags, 3710 &new_stp->ls_stateid, 0); 3711 if (error) 3712 goto out; 3713 3714 NFSLOCKSTATE(); 3715 /* 3716 * Get the lock owner by name. 3717 */ 3718 error = nfsrv_getclient(clientid, CLOPS_RENEW, &clp, NULL, 3719 (nfsquad_t)((u_quad_t)0), 0, NULL, p); 3720 if (error) { 3721 NFSUNLOCKSTATE(); 3722 goto out; 3723 } 3724 LIST_FOREACH(ownstp, &clp->lc_open, ls_list) { 3725 LIST_FOREACH(openstp, &ownstp->ls_open, ls_list) { 3726 stp = LIST_FIRST(&openstp->ls_open); 3727 while (stp != LIST_END(&openstp->ls_open)) { 3728 nstp = LIST_NEXT(stp, ls_list); 3729 /* 3730 * If the owner matches, check for locks and 3731 * then free or return an error. 3732 */ 3733 if (stp->ls_ownerlen == new_stp->ls_ownerlen && 3734 !NFSBCMP(stp->ls_owner, new_stp->ls_owner, 3735 stp->ls_ownerlen)){ 3736 if (LIST_EMPTY(&stp->ls_lock)) { 3737 nfsrv_freelockowner(stp, NULL, 0, p); 3738 } else { 3739 NFSUNLOCKSTATE(); 3740 error = NFSERR_LOCKSHELD; 3741 goto out; 3742 } 3743 } 3744 stp = nstp; 3745 } 3746 } 3747 } 3748 NFSUNLOCKSTATE(); 3749 3750 out: 3751 NFSEXITCODE(error); 3752 return (error); 3753 } 3754 3755 /* 3756 * Get the file handle for a lock structure. 3757 */ 3758 static int 3759 nfsrv_getlockfh(vnode_t vp, u_short flags, struct nfslockfile *new_lfp, 3760 fhandle_t *nfhp, NFSPROC_T *p) 3761 { 3762 fhandle_t *fhp = NULL; 3763 int error; 3764 3765 /* 3766 * For lock, use the new nfslock structure, otherwise just 3767 * a fhandle_t on the stack. 3768 */ 3769 if (flags & NFSLCK_OPEN) { 3770 KASSERT(new_lfp != NULL, ("nfsrv_getlockfh: new_lfp NULL")); 3771 fhp = &new_lfp->lf_fh; 3772 } else if (nfhp) { 3773 fhp = nfhp; 3774 } else { 3775 panic("nfsrv_getlockfh"); 3776 } 3777 error = nfsvno_getfh(vp, fhp, p); 3778 NFSEXITCODE(error); 3779 return (error); 3780 } 3781 3782 /* 3783 * Get an nfs lock structure. Allocate one, as required, and return a 3784 * pointer to it. 3785 * Returns an NFSERR_xxx upon failure or -1 to indicate no current lock. 3786 */ 3787 static int 3788 nfsrv_getlockfile(u_short flags, struct nfslockfile **new_lfpp, 3789 struct nfslockfile **lfpp, fhandle_t *nfhp, int lockit) 3790 { 3791 struct nfslockfile *lfp; 3792 fhandle_t *fhp = NULL, *tfhp; 3793 struct nfslockhashhead *hp; 3794 struct nfslockfile *new_lfp = NULL; 3795 3796 /* 3797 * For lock, use the new nfslock structure, otherwise just 3798 * a fhandle_t on the stack. 3799 */ 3800 if (flags & NFSLCK_OPEN) { 3801 new_lfp = *new_lfpp; 3802 fhp = &new_lfp->lf_fh; 3803 } else if (nfhp) { 3804 fhp = nfhp; 3805 } else { 3806 panic("nfsrv_getlockfile"); 3807 } 3808 3809 hp = NFSLOCKHASH(fhp); 3810 LIST_FOREACH(lfp, hp, lf_hash) { 3811 tfhp = &lfp->lf_fh; 3812 if (NFSVNO_CMPFH(fhp, tfhp)) { 3813 if (lockit) 3814 nfsrv_locklf(lfp); 3815 *lfpp = lfp; 3816 return (0); 3817 } 3818 } 3819 if (!(flags & NFSLCK_OPEN)) 3820 return (-1); 3821 3822 /* 3823 * No match, so chain the new one into the list. 3824 */ 3825 LIST_INIT(&new_lfp->lf_open); 3826 LIST_INIT(&new_lfp->lf_lock); 3827 LIST_INIT(&new_lfp->lf_deleg); 3828 LIST_INIT(&new_lfp->lf_locallock); 3829 LIST_INIT(&new_lfp->lf_rollback); 3830 new_lfp->lf_locallock_lck.nfslock_usecnt = 0; 3831 new_lfp->lf_locallock_lck.nfslock_lock = 0; 3832 new_lfp->lf_usecount = 0; 3833 LIST_INSERT_HEAD(hp, new_lfp, lf_hash); 3834 *lfpp = new_lfp; 3835 *new_lfpp = NULL; 3836 return (0); 3837 } 3838 3839 /* 3840 * This function adds a nfslock lock structure to the list for the associated 3841 * nfsstate and nfslockfile structures. It will be inserted after the 3842 * entry pointed at by insert_lop. 3843 */ 3844 static void 3845 nfsrv_insertlock(struct nfslock *new_lop, struct nfslock *insert_lop, 3846 struct nfsstate *stp, struct nfslockfile *lfp) 3847 { 3848 struct nfslock *lop, *nlop; 3849 3850 new_lop->lo_stp = stp; 3851 new_lop->lo_lfp = lfp; 3852 3853 if (stp != NULL) { 3854 /* Insert in increasing lo_first order */ 3855 lop = LIST_FIRST(&lfp->lf_lock); 3856 if (lop == LIST_END(&lfp->lf_lock) || 3857 new_lop->lo_first <= lop->lo_first) { 3858 LIST_INSERT_HEAD(&lfp->lf_lock, new_lop, lo_lckfile); 3859 } else { 3860 nlop = LIST_NEXT(lop, lo_lckfile); 3861 while (nlop != LIST_END(&lfp->lf_lock) && 3862 nlop->lo_first < new_lop->lo_first) { 3863 lop = nlop; 3864 nlop = LIST_NEXT(lop, lo_lckfile); 3865 } 3866 LIST_INSERT_AFTER(lop, new_lop, lo_lckfile); 3867 } 3868 } else { 3869 new_lop->lo_lckfile.le_prev = NULL; /* list not used */ 3870 } 3871 3872 /* 3873 * Insert after insert_lop, which is overloaded as stp or lfp for 3874 * an empty list. 3875 */ 3876 if (stp == NULL && (struct nfslockfile *)insert_lop == lfp) 3877 LIST_INSERT_HEAD(&lfp->lf_locallock, new_lop, lo_lckowner); 3878 else if ((struct nfsstate *)insert_lop == stp) 3879 LIST_INSERT_HEAD(&stp->ls_lock, new_lop, lo_lckowner); 3880 else 3881 LIST_INSERT_AFTER(insert_lop, new_lop, lo_lckowner); 3882 if (stp != NULL) { 3883 nfsstatsv1.srvlocks++; 3884 nfsrv_openpluslock++; 3885 } 3886 } 3887 3888 /* 3889 * This function updates the locking for a lock owner and given file. It 3890 * maintains a list of lock ranges ordered on increasing file offset that 3891 * are NFSLCK_READ or NFSLCK_WRITE and non-overlapping (aka POSIX style). 3892 * It always adds new_lop to the list and sometimes uses the one pointed 3893 * at by other_lopp. 3894 */ 3895 static void 3896 nfsrv_updatelock(struct nfsstate *stp, struct nfslock **new_lopp, 3897 struct nfslock **other_lopp, struct nfslockfile *lfp) 3898 { 3899 struct nfslock *new_lop = *new_lopp; 3900 struct nfslock *lop, *tlop, *ilop; 3901 struct nfslock *other_lop = *other_lopp; 3902 int unlock = 0, myfile = 0; 3903 u_int64_t tmp; 3904 3905 /* 3906 * Work down the list until the lock is merged. 3907 */ 3908 if (new_lop->lo_flags & NFSLCK_UNLOCK) 3909 unlock = 1; 3910 if (stp != NULL) { 3911 ilop = (struct nfslock *)stp; 3912 lop = LIST_FIRST(&stp->ls_lock); 3913 } else { 3914 ilop = (struct nfslock *)lfp; 3915 lop = LIST_FIRST(&lfp->lf_locallock); 3916 } 3917 while (lop != NULL) { 3918 /* 3919 * Only check locks for this file that aren't before the start of 3920 * new lock's range. 3921 */ 3922 if (lop->lo_lfp == lfp) { 3923 myfile = 1; 3924 if (lop->lo_end >= new_lop->lo_first) { 3925 if (new_lop->lo_end < lop->lo_first) { 3926 /* 3927 * If the new lock ends before the start of the 3928 * current lock's range, no merge, just insert 3929 * the new lock. 3930 */ 3931 break; 3932 } 3933 if (new_lop->lo_flags == lop->lo_flags || 3934 (new_lop->lo_first <= lop->lo_first && 3935 new_lop->lo_end >= lop->lo_end)) { 3936 /* 3937 * This lock can be absorbed by the new lock/unlock. 3938 * This happens when it covers the entire range 3939 * of the old lock or is contiguous 3940 * with the old lock and is of the same type or an 3941 * unlock. 3942 */ 3943 if (lop->lo_first < new_lop->lo_first) 3944 new_lop->lo_first = lop->lo_first; 3945 if (lop->lo_end > new_lop->lo_end) 3946 new_lop->lo_end = lop->lo_end; 3947 tlop = lop; 3948 lop = LIST_NEXT(lop, lo_lckowner); 3949 nfsrv_freenfslock(tlop); 3950 continue; 3951 } 3952 3953 /* 3954 * All these cases are for contiguous locks that are not the 3955 * same type, so they can't be merged. 3956 */ 3957 if (new_lop->lo_first <= lop->lo_first) { 3958 /* 3959 * This case is where the new lock overlaps with the 3960 * first part of the old lock. Move the start of the 3961 * old lock to just past the end of the new lock. The 3962 * new lock will be inserted in front of the old, since 3963 * ilop hasn't been updated. (We are done now.) 3964 */ 3965 lop->lo_first = new_lop->lo_end; 3966 break; 3967 } 3968 if (new_lop->lo_end >= lop->lo_end) { 3969 /* 3970 * This case is where the new lock overlaps with the 3971 * end of the old lock's range. Move the old lock's 3972 * end to just before the new lock's first and insert 3973 * the new lock after the old lock. 3974 * Might not be done yet, since the new lock could 3975 * overlap further locks with higher ranges. 3976 */ 3977 lop->lo_end = new_lop->lo_first; 3978 ilop = lop; 3979 lop = LIST_NEXT(lop, lo_lckowner); 3980 continue; 3981 } 3982 /* 3983 * The final case is where the new lock's range is in the 3984 * middle of the current lock's and splits the current lock 3985 * up. Use *other_lopp to handle the second part of the 3986 * split old lock range. (We are done now.) 3987 * For unlock, we use new_lop as other_lop and tmp, since 3988 * other_lop and new_lop are the same for this case. 3989 * We noted the unlock case above, so we don't need 3990 * new_lop->lo_flags any longer. 3991 */ 3992 tmp = new_lop->lo_first; 3993 if (other_lop == NULL) { 3994 if (!unlock) 3995 panic("nfsd srv update unlock"); 3996 other_lop = new_lop; 3997 *new_lopp = NULL; 3998 } 3999 other_lop->lo_first = new_lop->lo_end; 4000 other_lop->lo_end = lop->lo_end; 4001 other_lop->lo_flags = lop->lo_flags; 4002 other_lop->lo_stp = stp; 4003 other_lop->lo_lfp = lfp; 4004 lop->lo_end = tmp; 4005 nfsrv_insertlock(other_lop, lop, stp, lfp); 4006 *other_lopp = NULL; 4007 ilop = lop; 4008 break; 4009 } 4010 } 4011 ilop = lop; 4012 lop = LIST_NEXT(lop, lo_lckowner); 4013 if (myfile && (lop == NULL || lop->lo_lfp != lfp)) 4014 break; 4015 } 4016 4017 /* 4018 * Insert the new lock in the list at the appropriate place. 4019 */ 4020 if (!unlock) { 4021 nfsrv_insertlock(new_lop, ilop, stp, lfp); 4022 *new_lopp = NULL; 4023 } 4024 } 4025 4026 /* 4027 * This function handles sequencing of locks, etc. 4028 * It returns an error that indicates what the caller should do. 4029 */ 4030 static int 4031 nfsrv_checkseqid(struct nfsrv_descript *nd, u_int32_t seqid, 4032 struct nfsstate *stp, struct nfsrvcache *op) 4033 { 4034 int error = 0; 4035 4036 if ((nd->nd_flag & ND_NFSV41) != 0) 4037 /* NFSv4.1 ignores the open_seqid and lock_seqid. */ 4038 goto out; 4039 if (op != nd->nd_rp) 4040 panic("nfsrvstate checkseqid"); 4041 if (!(op->rc_flag & RC_INPROG)) 4042 panic("nfsrvstate not inprog"); 4043 if (stp->ls_op && stp->ls_op->rc_refcnt <= 0) { 4044 printf("refcnt=%d\n", stp->ls_op->rc_refcnt); 4045 panic("nfsrvstate op refcnt"); 4046 } 4047 4048 /* If ND_ERELOOKUP is set, the seqid has already been handled. */ 4049 if ((nd->nd_flag & ND_ERELOOKUP) != 0) 4050 goto out; 4051 4052 if ((stp->ls_seq + 1) == seqid) { 4053 if (stp->ls_op) 4054 nfsrvd_derefcache(stp->ls_op); 4055 stp->ls_op = op; 4056 nfsrvd_refcache(op); 4057 stp->ls_seq = seqid; 4058 goto out; 4059 } else if (stp->ls_seq == seqid && stp->ls_op && 4060 op->rc_xid == stp->ls_op->rc_xid && 4061 op->rc_refcnt == 0 && 4062 op->rc_reqlen == stp->ls_op->rc_reqlen && 4063 op->rc_cksum == stp->ls_op->rc_cksum) { 4064 if (stp->ls_op->rc_flag & RC_INPROG) { 4065 error = NFSERR_DONTREPLY; 4066 goto out; 4067 } 4068 nd->nd_rp = stp->ls_op; 4069 nd->nd_rp->rc_flag |= RC_INPROG; 4070 nfsrvd_delcache(op); 4071 error = NFSERR_REPLYFROMCACHE; 4072 goto out; 4073 } 4074 error = NFSERR_BADSEQID; 4075 4076 out: 4077 NFSEXITCODE2(error, nd); 4078 return (error); 4079 } 4080 4081 /* 4082 * Get the client ip address for callbacks. If the strings can't be parsed, 4083 * just set lc_program to 0 to indicate no callbacks are possible. 4084 * (For cases where the address can't be parsed or is 0.0.0.0.0.0, set 4085 * the address to the client's transport address. This won't be used 4086 * for callbacks, but can be printed out by nfsstats for info.) 4087 * Return error if the xdr can't be parsed, 0 otherwise. 4088 */ 4089 int 4090 nfsrv_getclientipaddr(struct nfsrv_descript *nd, struct nfsclient *clp) 4091 { 4092 u_int32_t *tl; 4093 u_char *cp, *cp2; 4094 int i, j, maxalen = 0, minalen = 0; 4095 sa_family_t af; 4096 #ifdef INET 4097 struct sockaddr_in *rin = NULL, *sin; 4098 #endif 4099 #ifdef INET6 4100 struct sockaddr_in6 *rin6 = NULL, *sin6; 4101 #endif 4102 u_char *addr; 4103 int error = 0, cantparse = 0; 4104 union { 4105 in_addr_t ival; 4106 u_char cval[4]; 4107 } ip; 4108 union { 4109 in_port_t sval; 4110 u_char cval[2]; 4111 } port; 4112 4113 /* 8 is the maximum length of the port# string. */ 4114 addr = malloc(INET6_ADDRSTRLEN + 8, M_TEMP, M_WAITOK); 4115 clp->lc_req.nr_client = NULL; 4116 clp->lc_req.nr_lock = 0; 4117 af = AF_UNSPEC; 4118 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 4119 i = fxdr_unsigned(int, *tl); 4120 if (i >= 3 && i <= 4) { 4121 error = nfsrv_mtostr(nd, addr, i); 4122 if (error) 4123 goto nfsmout; 4124 #ifdef INET 4125 if (!strcmp(addr, "tcp")) { 4126 clp->lc_flags |= LCL_TCPCALLBACK; 4127 clp->lc_req.nr_sotype = SOCK_STREAM; 4128 clp->lc_req.nr_soproto = IPPROTO_TCP; 4129 af = AF_INET; 4130 } else if (!strcmp(addr, "udp")) { 4131 clp->lc_req.nr_sotype = SOCK_DGRAM; 4132 clp->lc_req.nr_soproto = IPPROTO_UDP; 4133 af = AF_INET; 4134 } 4135 #endif 4136 #ifdef INET6 4137 if (af == AF_UNSPEC) { 4138 if (!strcmp(addr, "tcp6")) { 4139 clp->lc_flags |= LCL_TCPCALLBACK; 4140 clp->lc_req.nr_sotype = SOCK_STREAM; 4141 clp->lc_req.nr_soproto = IPPROTO_TCP; 4142 af = AF_INET6; 4143 } else if (!strcmp(addr, "udp6")) { 4144 clp->lc_req.nr_sotype = SOCK_DGRAM; 4145 clp->lc_req.nr_soproto = IPPROTO_UDP; 4146 af = AF_INET6; 4147 } 4148 } 4149 #endif 4150 if (af == AF_UNSPEC) { 4151 cantparse = 1; 4152 } 4153 } else { 4154 cantparse = 1; 4155 if (i > 0) { 4156 error = nfsm_advance(nd, NFSM_RNDUP(i), -1); 4157 if (error) 4158 goto nfsmout; 4159 } 4160 } 4161 /* 4162 * The caller has allocated clp->lc_req.nr_nam to be large enough 4163 * for either AF_INET or AF_INET6 and zeroed out the contents. 4164 * maxalen is set to the maximum length of the host IP address string 4165 * plus 8 for the maximum length of the port#. 4166 * minalen is set to the minimum length of the host IP address string 4167 * plus 4 for the minimum length of the port#. 4168 * These lengths do not include NULL termination, 4169 * so INET[6]_ADDRSTRLEN - 1 is used in the calculations. 4170 */ 4171 switch (af) { 4172 #ifdef INET 4173 case AF_INET: 4174 rin = (struct sockaddr_in *)clp->lc_req.nr_nam; 4175 rin->sin_family = AF_INET; 4176 rin->sin_len = sizeof(struct sockaddr_in); 4177 maxalen = INET_ADDRSTRLEN - 1 + 8; 4178 minalen = 7 + 4; 4179 break; 4180 #endif 4181 #ifdef INET6 4182 case AF_INET6: 4183 rin6 = (struct sockaddr_in6 *)clp->lc_req.nr_nam; 4184 rin6->sin6_family = AF_INET6; 4185 rin6->sin6_len = sizeof(struct sockaddr_in6); 4186 maxalen = INET6_ADDRSTRLEN - 1 + 8; 4187 minalen = 3 + 4; 4188 break; 4189 #endif 4190 } 4191 NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); 4192 i = fxdr_unsigned(int, *tl); 4193 if (i < 0) { 4194 error = NFSERR_BADXDR; 4195 goto nfsmout; 4196 } else if (i == 0) { 4197 cantparse = 1; 4198 } else if (!cantparse && i <= maxalen && i >= minalen) { 4199 error = nfsrv_mtostr(nd, addr, i); 4200 if (error) 4201 goto nfsmout; 4202 4203 /* 4204 * Parse out the address fields. We expect 6 decimal numbers 4205 * separated by '.'s for AF_INET and two decimal numbers 4206 * preceeded by '.'s for AF_INET6. 4207 */ 4208 cp = NULL; 4209 switch (af) { 4210 #ifdef INET6 4211 /* 4212 * For AF_INET6, first parse the host address. 4213 */ 4214 case AF_INET6: 4215 cp = strchr(addr, '.'); 4216 if (cp != NULL) { 4217 *cp++ = '\0'; 4218 if (inet_pton(af, addr, &rin6->sin6_addr) == 1) 4219 i = 4; 4220 else { 4221 cp = NULL; 4222 cantparse = 1; 4223 } 4224 } 4225 break; 4226 #endif 4227 #ifdef INET 4228 case AF_INET: 4229 cp = addr; 4230 i = 0; 4231 break; 4232 #endif 4233 } 4234 while (cp != NULL && *cp && i < 6) { 4235 cp2 = cp; 4236 while (*cp2 && *cp2 != '.') 4237 cp2++; 4238 if (*cp2) 4239 *cp2++ = '\0'; 4240 else if (i != 5) { 4241 cantparse = 1; 4242 break; 4243 } 4244 j = nfsrv_getipnumber(cp); 4245 if (j >= 0) { 4246 if (i < 4) 4247 ip.cval[3 - i] = j; 4248 else 4249 port.cval[5 - i] = j; 4250 } else { 4251 cantparse = 1; 4252 break; 4253 } 4254 cp = cp2; 4255 i++; 4256 } 4257 if (!cantparse) { 4258 /* 4259 * The host address INADDR_ANY is (mis)used to indicate 4260 * "there is no valid callback address". 4261 */ 4262 switch (af) { 4263 #ifdef INET6 4264 case AF_INET6: 4265 if (!IN6_ARE_ADDR_EQUAL(&rin6->sin6_addr, 4266 &in6addr_any)) 4267 rin6->sin6_port = htons(port.sval); 4268 else 4269 cantparse = 1; 4270 break; 4271 #endif 4272 #ifdef INET 4273 case AF_INET: 4274 if (ip.ival != INADDR_ANY) { 4275 rin->sin_addr.s_addr = htonl(ip.ival); 4276 rin->sin_port = htons(port.sval); 4277 } else { 4278 cantparse = 1; 4279 } 4280 break; 4281 #endif 4282 } 4283 } 4284 } else { 4285 cantparse = 1; 4286 if (i > 0) { 4287 error = nfsm_advance(nd, NFSM_RNDUP(i), -1); 4288 if (error) 4289 goto nfsmout; 4290 } 4291 } 4292 if (cantparse) { 4293 switch (nd->nd_nam->sa_family) { 4294 #ifdef INET 4295 case AF_INET: 4296 sin = (struct sockaddr_in *)nd->nd_nam; 4297 rin = (struct sockaddr_in *)clp->lc_req.nr_nam; 4298 rin->sin_family = AF_INET; 4299 rin->sin_len = sizeof(struct sockaddr_in); 4300 rin->sin_addr.s_addr = sin->sin_addr.s_addr; 4301 rin->sin_port = 0x0; 4302 break; 4303 #endif 4304 #ifdef INET6 4305 case AF_INET6: 4306 sin6 = (struct sockaddr_in6 *)nd->nd_nam; 4307 rin6 = (struct sockaddr_in6 *)clp->lc_req.nr_nam; 4308 rin6->sin6_family = AF_INET6; 4309 rin6->sin6_len = sizeof(struct sockaddr_in6); 4310 rin6->sin6_addr = sin6->sin6_addr; 4311 rin6->sin6_port = 0x0; 4312 break; 4313 #endif 4314 } 4315 clp->lc_program = 0; 4316 } 4317 nfsmout: 4318 free(addr, M_TEMP); 4319 NFSEXITCODE2(error, nd); 4320 return (error); 4321 } 4322 4323 /* 4324 * Turn a string of up to three decimal digits into a number. Return -1 upon 4325 * error. 4326 */ 4327 static int 4328 nfsrv_getipnumber(u_char *cp) 4329 { 4330 int i = 0, j = 0; 4331 4332 while (*cp) { 4333 if (j > 2 || *cp < '0' || *cp > '9') 4334 return (-1); 4335 i *= 10; 4336 i += (*cp - '0'); 4337 cp++; 4338 j++; 4339 } 4340 if (i < 256) 4341 return (i); 4342 return (-1); 4343 } 4344 4345 /* 4346 * This function checks for restart conditions. 4347 */ 4348 static int 4349 nfsrv_checkrestart(nfsquad_t clientid, u_int32_t flags, 4350 nfsv4stateid_t *stateidp, int specialid) 4351 { 4352 int ret = 0; 4353 4354 /* 4355 * First check for a server restart. Open, LockT, ReleaseLockOwner 4356 * and DelegPurge have a clientid, the rest a stateid. 4357 */ 4358 if (flags & 4359 (NFSLCK_OPEN | NFSLCK_TEST | NFSLCK_RELEASE | NFSLCK_DELEGPURGE)) { 4360 if (clientid.lval[0] != nfsrvboottime) { 4361 ret = NFSERR_STALECLIENTID; 4362 goto out; 4363 } 4364 } else if (stateidp->other[0] != nfsrvboottime && 4365 specialid == 0) { 4366 ret = NFSERR_STALESTATEID; 4367 goto out; 4368 } 4369 4370 /* 4371 * Read, Write, Setattr and LockT can return NFSERR_GRACE and do 4372 * not use a lock/open owner seqid#, so the check can be done now. 4373 * (The others will be checked, as required, later.) 4374 */ 4375 if (!(flags & (NFSLCK_CHECK | NFSLCK_TEST))) 4376 goto out; 4377 4378 NFSLOCKSTATE(); 4379 ret = nfsrv_checkgrace(NULL, NULL, flags); 4380 NFSUNLOCKSTATE(); 4381 4382 out: 4383 NFSEXITCODE(ret); 4384 return (ret); 4385 } 4386 4387 /* 4388 * Check for grace. 4389 */ 4390 static int 4391 nfsrv_checkgrace(struct nfsrv_descript *nd, struct nfsclient *clp, 4392 u_int32_t flags) 4393 { 4394 int error = 0, notreclaimed; 4395 struct nfsrv_stable *sp; 4396 4397 if ((nfsrv_stablefirst.nsf_flags & (NFSNSF_UPDATEDONE | 4398 NFSNSF_GRACEOVER)) == 0) { 4399 /* 4400 * First, check to see if all of the clients have done a 4401 * ReclaimComplete. If so, grace can end now. 4402 */ 4403 notreclaimed = 0; 4404 LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) { 4405 if ((sp->nst_flag & NFSNST_RECLAIMED) == 0) { 4406 notreclaimed = 1; 4407 break; 4408 } 4409 } 4410 if (notreclaimed == 0) 4411 nfsrv_stablefirst.nsf_flags |= (NFSNSF_GRACEOVER | 4412 NFSNSF_NEEDLOCK); 4413 } 4414 4415 if ((nfsrv_stablefirst.nsf_flags & NFSNSF_GRACEOVER) != 0) { 4416 if (flags & NFSLCK_RECLAIM) { 4417 error = NFSERR_NOGRACE; 4418 goto out; 4419 } 4420 } else { 4421 if (!(flags & NFSLCK_RECLAIM)) { 4422 error = NFSERR_GRACE; 4423 goto out; 4424 } 4425 if (nd != NULL && clp != NULL && 4426 (nd->nd_flag & ND_NFSV41) != 0 && 4427 (clp->lc_flags & LCL_RECLAIMCOMPLETE) != 0) { 4428 error = NFSERR_NOGRACE; 4429 goto out; 4430 } 4431 4432 /* 4433 * If grace is almost over and we are still getting Reclaims, 4434 * extend grace a bit. 4435 */ 4436 if ((NFSD_MONOSEC + NFSRV_LEASEDELTA) > 4437 nfsrv_stablefirst.nsf_eograce) 4438 nfsrv_stablefirst.nsf_eograce = NFSD_MONOSEC + 4439 NFSRV_LEASEDELTA; 4440 } 4441 4442 out: 4443 NFSEXITCODE(error); 4444 return (error); 4445 } 4446 4447 /* 4448 * Do a server callback. 4449 * The "trunc" argument is slightly overloaded and refers to different 4450 * boolean arguments for CBRECALL and CBLAYOUTRECALL. 4451 */ 4452 static int 4453 nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, 4454 int trunc, fhandle_t *fhp, struct nfsvattr *nap, nfsattrbit_t *attrbitp, 4455 int laytype, NFSPROC_T *p) 4456 { 4457 struct mbuf *m; 4458 u_int32_t *tl; 4459 struct nfsrv_descript *nd; 4460 struct ucred *cred; 4461 int error = 0, slotpos; 4462 u_int32_t callback; 4463 struct nfsdsession *sep = NULL; 4464 uint64_t tval; 4465 bool dotls; 4466 4467 nd = malloc(sizeof(*nd), M_TEMP, M_WAITOK | M_ZERO); 4468 cred = newnfs_getcred(); 4469 NFSLOCKSTATE(); /* mostly for lc_cbref++ */ 4470 if (clp->lc_flags & LCL_NEEDSCONFIRM) { 4471 NFSUNLOCKSTATE(); 4472 panic("docallb"); 4473 } 4474 clp->lc_cbref++; 4475 4476 /* 4477 * Fill the callback program# and version into the request 4478 * structure for newnfs_connect() to use. 4479 */ 4480 clp->lc_req.nr_prog = clp->lc_program; 4481 #ifdef notnow 4482 if ((clp->lc_flags & LCL_NFSV41) != 0) 4483 clp->lc_req.nr_vers = NFSV41_CBVERS; 4484 else 4485 #endif 4486 clp->lc_req.nr_vers = NFSV4_CBVERS; 4487 4488 /* 4489 * First, fill in some of the fields of nd and cr. 4490 */ 4491 nd->nd_flag = ND_NFSV4; 4492 if (clp->lc_flags & LCL_GSS) 4493 nd->nd_flag |= ND_KERBV; 4494 if ((clp->lc_flags & LCL_NFSV41) != 0) 4495 nd->nd_flag |= ND_NFSV41; 4496 if ((clp->lc_flags & LCL_NFSV42) != 0) 4497 nd->nd_flag |= ND_NFSV42; 4498 nd->nd_repstat = 0; 4499 cred->cr_uid = clp->lc_uid; 4500 cred->cr_gid = clp->lc_gid; 4501 callback = clp->lc_callback; 4502 NFSUNLOCKSTATE(); 4503 cred->cr_ngroups = 1; 4504 4505 /* 4506 * Get the first mbuf for the request. 4507 */ 4508 MGET(m, M_WAITOK, MT_DATA); 4509 m->m_len = 0; 4510 nd->nd_mreq = nd->nd_mb = m; 4511 nd->nd_bpos = mtod(m, caddr_t); 4512 4513 /* 4514 * and build the callback request. 4515 */ 4516 if (procnum == NFSV4OP_CBGETATTR) { 4517 nd->nd_procnum = NFSV4PROC_CBCOMPOUND; 4518 error = nfsrv_cbcallargs(nd, clp, callback, NFSV4OP_CBGETATTR, 4519 "CB Getattr", &sep, &slotpos); 4520 if (error != 0) { 4521 m_freem(nd->nd_mreq); 4522 goto errout; 4523 } 4524 (void)nfsm_fhtom(nd, (u_int8_t *)fhp, NFSX_MYFH, 0); 4525 (void)nfsrv_putattrbit(nd, attrbitp); 4526 } else if (procnum == NFSV4OP_CBRECALL) { 4527 nd->nd_procnum = NFSV4PROC_CBCOMPOUND; 4528 error = nfsrv_cbcallargs(nd, clp, callback, NFSV4OP_CBRECALL, 4529 "CB Recall", &sep, &slotpos); 4530 if (error != 0) { 4531 m_freem(nd->nd_mreq); 4532 goto errout; 4533 } 4534 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_STATEID); 4535 *tl++ = txdr_unsigned(stateidp->seqid); 4536 NFSBCOPY((caddr_t)stateidp->other, (caddr_t)tl, 4537 NFSX_STATEIDOTHER); 4538 tl += (NFSX_STATEIDOTHER / NFSX_UNSIGNED); 4539 if (trunc) 4540 *tl = newnfs_true; 4541 else 4542 *tl = newnfs_false; 4543 (void)nfsm_fhtom(nd, (u_int8_t *)fhp, NFSX_MYFH, 0); 4544 } else if (procnum == NFSV4OP_CBLAYOUTRECALL) { 4545 NFSD_DEBUG(4, "docallback layout recall\n"); 4546 nd->nd_procnum = NFSV4PROC_CBCOMPOUND; 4547 error = nfsrv_cbcallargs(nd, clp, callback, 4548 NFSV4OP_CBLAYOUTRECALL, "CB Reclayout", &sep, &slotpos); 4549 NFSD_DEBUG(4, "aft cbcallargs=%d\n", error); 4550 if (error != 0) { 4551 m_freem(nd->nd_mreq); 4552 goto errout; 4553 } 4554 NFSM_BUILD(tl, u_int32_t *, 4 * NFSX_UNSIGNED); 4555 *tl++ = txdr_unsigned(laytype); 4556 *tl++ = txdr_unsigned(NFSLAYOUTIOMODE_ANY); 4557 if (trunc) 4558 *tl++ = newnfs_true; 4559 else 4560 *tl++ = newnfs_false; 4561 *tl = txdr_unsigned(NFSV4LAYOUTRET_FILE); 4562 nfsm_fhtom(nd, (uint8_t *)fhp, NFSX_MYFH, 0); 4563 NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_HYPER + NFSX_STATEID); 4564 tval = 0; 4565 txdr_hyper(tval, tl); tl += 2; 4566 tval = UINT64_MAX; 4567 txdr_hyper(tval, tl); tl += 2; 4568 *tl++ = txdr_unsigned(stateidp->seqid); 4569 NFSBCOPY(stateidp->other, tl, NFSX_STATEIDOTHER); 4570 tl += (NFSX_STATEIDOTHER / NFSX_UNSIGNED); 4571 NFSD_DEBUG(4, "aft args\n"); 4572 } else if (procnum == NFSV4PROC_CBNULL) { 4573 nd->nd_procnum = NFSV4PROC_CBNULL; 4574 if ((clp->lc_flags & LCL_NFSV41) != 0) { 4575 error = nfsv4_getcbsession(clp, &sep); 4576 if (error != 0) { 4577 m_freem(nd->nd_mreq); 4578 goto errout; 4579 } 4580 } 4581 } else { 4582 error = NFSERR_SERVERFAULT; 4583 m_freem(nd->nd_mreq); 4584 goto errout; 4585 } 4586 4587 /* 4588 * Call newnfs_connect(), as required, and then newnfs_request(). 4589 */ 4590 dotls = false; 4591 if ((clp->lc_flags & LCL_TLSCB) != 0) 4592 dotls = true; 4593 (void) newnfs_sndlock(&clp->lc_req.nr_lock); 4594 if (clp->lc_req.nr_client == NULL) { 4595 if ((clp->lc_flags & LCL_NFSV41) != 0) { 4596 error = ECONNREFUSED; 4597 if (procnum != NFSV4PROC_CBNULL) 4598 nfsv4_freeslot(&sep->sess_cbsess, slotpos, 4599 true); 4600 nfsrv_freesession(sep, NULL); 4601 } else if (nd->nd_procnum == NFSV4PROC_CBNULL) 4602 error = newnfs_connect(NULL, &clp->lc_req, cred, 4603 NULL, 1, dotls, &clp->lc_req.nr_client); 4604 else 4605 error = newnfs_connect(NULL, &clp->lc_req, cred, 4606 NULL, 3, dotls, &clp->lc_req.nr_client); 4607 } 4608 newnfs_sndunlock(&clp->lc_req.nr_lock); 4609 NFSD_DEBUG(4, "aft sndunlock=%d\n", error); 4610 if (!error) { 4611 if ((nd->nd_flag & ND_NFSV41) != 0) { 4612 KASSERT(sep != NULL, ("sep NULL")); 4613 if (sep->sess_cbsess.nfsess_xprt != NULL) 4614 error = newnfs_request(nd, NULL, clp, 4615 &clp->lc_req, NULL, NULL, cred, 4616 clp->lc_program, clp->lc_req.nr_vers, NULL, 4617 1, NULL, &sep->sess_cbsess); 4618 else { 4619 /* 4620 * This should probably never occur, but if a 4621 * client somehow does an RPC without a 4622 * SequenceID Op that causes a callback just 4623 * after the nfsd threads have been terminated 4624 * and restared we could conceivably get here 4625 * without a backchannel xprt. 4626 */ 4627 printf("nfsrv_docallback: no xprt\n"); 4628 error = ECONNREFUSED; 4629 } 4630 NFSD_DEBUG(4, "aft newnfs_request=%d\n", error); 4631 if (error != 0 && procnum != NFSV4PROC_CBNULL) { 4632 /* 4633 * It is likely that the callback was never 4634 * processed by the client and, as such, 4635 * the sequence# for the session slot needs 4636 * to be backed up by one to avoid a 4637 * NFSERR_SEQMISORDERED error reply. 4638 * For the unlikely case where the callback 4639 * was processed by the client, this will 4640 * make the next callback on the slot 4641 * appear to be a retry. 4642 * Since callbacks never specify that the 4643 * reply be cached, this "apparent retry" 4644 * should not be a problem. 4645 */ 4646 nfsv4_freeslot(&sep->sess_cbsess, slotpos, 4647 true); 4648 } 4649 nfsrv_freesession(sep, NULL); 4650 } else 4651 error = newnfs_request(nd, NULL, clp, &clp->lc_req, 4652 NULL, NULL, cred, clp->lc_program, 4653 clp->lc_req.nr_vers, NULL, 1, NULL, NULL); 4654 } 4655 errout: 4656 NFSFREECRED(cred); 4657 4658 /* 4659 * If error is set here, the Callback path isn't working 4660 * properly, so twiddle the appropriate LCL_ flags. 4661 * (nd_repstat != 0 indicates the Callback path is working, 4662 * but the callback failed on the client.) 4663 */ 4664 if (error) { 4665 /* 4666 * Mark the callback pathway down, which disabled issuing 4667 * of delegations and gets Renew to return NFSERR_CBPATHDOWN. 4668 */ 4669 NFSLOCKSTATE(); 4670 clp->lc_flags |= LCL_CBDOWN; 4671 NFSUNLOCKSTATE(); 4672 } else { 4673 /* 4674 * Callback worked. If the callback path was down, disable 4675 * callbacks, so no more delegations will be issued. (This 4676 * is done on the assumption that the callback pathway is 4677 * flakey.) 4678 */ 4679 NFSLOCKSTATE(); 4680 if (clp->lc_flags & LCL_CBDOWN) 4681 clp->lc_flags &= ~(LCL_CBDOWN | LCL_CALLBACKSON); 4682 NFSUNLOCKSTATE(); 4683 if (nd->nd_repstat) { 4684 error = nd->nd_repstat; 4685 NFSD_DEBUG(1, "nfsrv_docallback op=%d err=%d\n", 4686 procnum, error); 4687 } else if (error == 0 && procnum == NFSV4OP_CBGETATTR) 4688 error = nfsv4_loadattr(nd, NULL, nap, NULL, NULL, 0, 4689 NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, 4690 p, NULL); 4691 m_freem(nd->nd_mrep); 4692 } 4693 NFSLOCKSTATE(); 4694 clp->lc_cbref--; 4695 if ((clp->lc_flags & LCL_WAKEUPWANTED) && clp->lc_cbref == 0) { 4696 clp->lc_flags &= ~LCL_WAKEUPWANTED; 4697 wakeup(clp); 4698 } 4699 NFSUNLOCKSTATE(); 4700 4701 free(nd, M_TEMP); 4702 NFSEXITCODE(error); 4703 return (error); 4704 } 4705 4706 /* 4707 * Set up the compound RPC for the callback. 4708 */ 4709 static int 4710 nfsrv_cbcallargs(struct nfsrv_descript *nd, struct nfsclient *clp, 4711 uint32_t callback, int op, const char *optag, struct nfsdsession **sepp, 4712 int *slotposp) 4713 { 4714 uint32_t *tl; 4715 int error, len; 4716 4717 len = strlen(optag); 4718 (void)nfsm_strtom(nd, optag, len); 4719 NFSM_BUILD(tl, uint32_t *, 4 * NFSX_UNSIGNED); 4720 if ((nd->nd_flag & ND_NFSV41) != 0) { 4721 if ((nd->nd_flag & ND_NFSV42) != 0) 4722 *tl++ = txdr_unsigned(NFSV42_MINORVERSION); 4723 else 4724 *tl++ = txdr_unsigned(NFSV41_MINORVERSION); 4725 *tl++ = txdr_unsigned(callback); 4726 *tl++ = txdr_unsigned(2); 4727 *tl = txdr_unsigned(NFSV4OP_CBSEQUENCE); 4728 error = nfsv4_setcbsequence(nd, clp, 1, sepp, slotposp); 4729 if (error != 0) 4730 return (error); 4731 NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); 4732 *tl = txdr_unsigned(op); 4733 } else { 4734 *tl++ = txdr_unsigned(NFSV4_MINORVERSION); 4735 *tl++ = txdr_unsigned(callback); 4736 *tl++ = txdr_unsigned(1); 4737 *tl = txdr_unsigned(op); 4738 } 4739 return (0); 4740 } 4741 4742 /* 4743 * Return the next index# for a clientid. Mostly just increment and return 4744 * the next one, but... if the 32bit unsigned does actually wrap around, 4745 * it should be rebooted. 4746 * At an average rate of one new client per second, it will wrap around in 4747 * approximately 136 years. (I think the server will have been shut 4748 * down or rebooted before then.) 4749 */ 4750 static u_int32_t 4751 nfsrv_nextclientindex(void) 4752 { 4753 static u_int32_t client_index = 0; 4754 4755 client_index++; 4756 if (client_index != 0) 4757 return (client_index); 4758 4759 printf("%s: out of clientids\n", __func__); 4760 return (client_index); 4761 } 4762 4763 /* 4764 * Return the next index# for a stateid. Mostly just increment and return 4765 * the next one, but... if the 32bit unsigned does actually wrap around 4766 * (will a BSD server stay up that long?), find 4767 * new start and end values. 4768 */ 4769 static u_int32_t 4770 nfsrv_nextstateindex(struct nfsclient *clp) 4771 { 4772 struct nfsstate *stp; 4773 int i; 4774 u_int32_t canuse, min_index, max_index; 4775 4776 if (!(clp->lc_flags & LCL_INDEXNOTOK)) { 4777 clp->lc_stateindex++; 4778 if (clp->lc_stateindex != clp->lc_statemaxindex) 4779 return (clp->lc_stateindex); 4780 } 4781 4782 /* 4783 * Yuck, we've hit the end. 4784 * Look for a new min and max. 4785 */ 4786 min_index = 0; 4787 max_index = 0xffffffff; 4788 for (i = 0; i < nfsrv_statehashsize; i++) { 4789 LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) { 4790 if (stp->ls_stateid.other[2] > 0x80000000) { 4791 if (stp->ls_stateid.other[2] < max_index) 4792 max_index = stp->ls_stateid.other[2]; 4793 } else { 4794 if (stp->ls_stateid.other[2] > min_index) 4795 min_index = stp->ls_stateid.other[2]; 4796 } 4797 } 4798 } 4799 4800 /* 4801 * Yikes, highly unlikely, but I'll handle it anyhow. 4802 */ 4803 if (min_index == 0x80000000 && max_index == 0x80000001) { 4804 canuse = 0; 4805 /* 4806 * Loop around until we find an unused entry. Return that 4807 * and set LCL_INDEXNOTOK, so the search will continue next time. 4808 * (This is one of those rare cases where a goto is the 4809 * cleanest way to code the loop.) 4810 */ 4811 tryagain: 4812 for (i = 0; i < nfsrv_statehashsize; i++) { 4813 LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) { 4814 if (stp->ls_stateid.other[2] == canuse) { 4815 canuse++; 4816 goto tryagain; 4817 } 4818 } 4819 } 4820 clp->lc_flags |= LCL_INDEXNOTOK; 4821 return (canuse); 4822 } 4823 4824 /* 4825 * Ok to start again from min + 1. 4826 */ 4827 clp->lc_stateindex = min_index + 1; 4828 clp->lc_statemaxindex = max_index; 4829 clp->lc_flags &= ~LCL_INDEXNOTOK; 4830 return (clp->lc_stateindex); 4831 } 4832 4833 /* 4834 * The following functions handle the stable storage file that deals with 4835 * the edge conditions described in RFC3530 Sec. 8.6.3. 4836 * The file is as follows: 4837 * - a single record at the beginning that has the lease time of the 4838 * previous server instance (before the last reboot) and the nfsrvboottime 4839 * values for the previous server boots. 4840 * These previous boot times are used to ensure that the current 4841 * nfsrvboottime does not, somehow, get set to a previous one. 4842 * (This is important so that Stale ClientIDs and StateIDs can 4843 * be recognized.) 4844 * The number of previous nfsvrboottime values precedes the list. 4845 * - followed by some number of appended records with: 4846 * - client id string 4847 * - flag that indicates it is a record revoking state via lease 4848 * expiration or similar 4849 * OR has successfully acquired state. 4850 * These structures vary in length, with the client string at the end, up 4851 * to NFSV4_OPAQUELIMIT in size. 4852 * 4853 * At the end of the grace period, the file is truncated, the first 4854 * record is rewritten with updated information and any acquired state 4855 * records for successful reclaims of state are written. 4856 * 4857 * Subsequent records are appended when the first state is issued to 4858 * a client and when state is revoked for a client. 4859 * 4860 * When reading the file in, state issued records that come later in 4861 * the file override older ones, since the append log is in cronological order. 4862 * If, for some reason, the file can't be read, the grace period is 4863 * immediately terminated and all reclaims get NFSERR_NOGRACE. 4864 */ 4865 4866 /* 4867 * Read in the stable storage file. Called by nfssvc() before the nfsd 4868 * processes start servicing requests. 4869 */ 4870 void 4871 nfsrv_setupstable(NFSPROC_T *p) 4872 { 4873 struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; 4874 struct nfsrv_stable *sp, *nsp; 4875 struct nfst_rec *tsp; 4876 int error, i, tryagain; 4877 off_t off = 0; 4878 ssize_t aresid, len; 4879 4880 /* 4881 * If NFSNSF_UPDATEDONE is set, this is a restart of the nfsds without 4882 * a reboot, so state has not been lost. 4883 */ 4884 if (sf->nsf_flags & NFSNSF_UPDATEDONE) 4885 return; 4886 /* 4887 * Set Grace over just until the file reads successfully. 4888 */ 4889 nfsrvboottime = time_second; 4890 LIST_INIT(&sf->nsf_head); 4891 sf->nsf_flags = (NFSNSF_GRACEOVER | NFSNSF_NEEDLOCK); 4892 sf->nsf_eograce = NFSD_MONOSEC + NFSRV_LEASEDELTA; 4893 if (sf->nsf_fp == NULL) 4894 return; 4895 error = NFSD_RDWR(UIO_READ, NFSFPVNODE(sf->nsf_fp), 4896 (caddr_t)&sf->nsf_rec, sizeof (struct nfsf_rec), off, UIO_SYSSPACE, 4897 0, NFSFPCRED(sf->nsf_fp), &aresid, p); 4898 if (error || aresid || sf->nsf_numboots == 0 || 4899 sf->nsf_numboots > NFSNSF_MAXNUMBOOTS) 4900 return; 4901 4902 /* 4903 * Now, read in the boottimes. 4904 */ 4905 sf->nsf_bootvals = (time_t *)malloc((sf->nsf_numboots + 1) * 4906 sizeof (time_t), M_TEMP, M_WAITOK); 4907 off = sizeof (struct nfsf_rec); 4908 error = NFSD_RDWR(UIO_READ, NFSFPVNODE(sf->nsf_fp), 4909 (caddr_t)sf->nsf_bootvals, sf->nsf_numboots * sizeof (time_t), off, 4910 UIO_SYSSPACE, 0, NFSFPCRED(sf->nsf_fp), &aresid, p); 4911 if (error || aresid) { 4912 free(sf->nsf_bootvals, M_TEMP); 4913 sf->nsf_bootvals = NULL; 4914 return; 4915 } 4916 4917 /* 4918 * Make sure this nfsrvboottime is different from all recorded 4919 * previous ones. 4920 */ 4921 do { 4922 tryagain = 0; 4923 for (i = 0; i < sf->nsf_numboots; i++) { 4924 if (nfsrvboottime == sf->nsf_bootvals[i]) { 4925 nfsrvboottime++; 4926 tryagain = 1; 4927 break; 4928 } 4929 } 4930 } while (tryagain); 4931 4932 sf->nsf_flags |= NFSNSF_OK; 4933 off += (sf->nsf_numboots * sizeof (time_t)); 4934 4935 /* 4936 * Read through the file, building a list of records for grace 4937 * checking. 4938 * Each record is between sizeof (struct nfst_rec) and 4939 * sizeof (struct nfst_rec) + NFSV4_OPAQUELIMIT - 1 4940 * and is actually sizeof (struct nfst_rec) + nst_len - 1. 4941 */ 4942 tsp = (struct nfst_rec *)malloc(sizeof (struct nfst_rec) + 4943 NFSV4_OPAQUELIMIT - 1, M_TEMP, M_WAITOK); 4944 do { 4945 error = NFSD_RDWR(UIO_READ, NFSFPVNODE(sf->nsf_fp), 4946 (caddr_t)tsp, sizeof (struct nfst_rec) + NFSV4_OPAQUELIMIT - 1, 4947 off, UIO_SYSSPACE, 0, NFSFPCRED(sf->nsf_fp), &aresid, p); 4948 len = (sizeof (struct nfst_rec) + NFSV4_OPAQUELIMIT - 1) - aresid; 4949 if (error || (len > 0 && (len < sizeof (struct nfst_rec) || 4950 len < (sizeof (struct nfst_rec) + tsp->len - 1)))) { 4951 /* 4952 * Yuck, the file has been corrupted, so just return 4953 * after clearing out any restart state, so the grace period 4954 * is over. 4955 */ 4956 LIST_FOREACH_SAFE(sp, &sf->nsf_head, nst_list, nsp) { 4957 LIST_REMOVE(sp, nst_list); 4958 free(sp, M_TEMP); 4959 } 4960 free(tsp, M_TEMP); 4961 sf->nsf_flags &= ~NFSNSF_OK; 4962 free(sf->nsf_bootvals, M_TEMP); 4963 sf->nsf_bootvals = NULL; 4964 return; 4965 } 4966 if (len > 0) { 4967 off += sizeof (struct nfst_rec) + tsp->len - 1; 4968 /* 4969 * Search the list for a matching client. 4970 */ 4971 LIST_FOREACH(sp, &sf->nsf_head, nst_list) { 4972 if (tsp->len == sp->nst_len && 4973 !NFSBCMP(tsp->client, sp->nst_client, tsp->len)) 4974 break; 4975 } 4976 if (sp == LIST_END(&sf->nsf_head)) { 4977 sp = (struct nfsrv_stable *)malloc(tsp->len + 4978 sizeof (struct nfsrv_stable) - 1, M_TEMP, 4979 M_WAITOK); 4980 NFSBCOPY((caddr_t)tsp, (caddr_t)&sp->nst_rec, 4981 sizeof (struct nfst_rec) + tsp->len - 1); 4982 LIST_INSERT_HEAD(&sf->nsf_head, sp, nst_list); 4983 } else { 4984 if (tsp->flag == NFSNST_REVOKE) 4985 sp->nst_flag |= NFSNST_REVOKE; 4986 else 4987 /* 4988 * A subsequent timestamp indicates the client 4989 * did a setclientid/confirm and any previous 4990 * revoke is no longer relevant. 4991 */ 4992 sp->nst_flag &= ~NFSNST_REVOKE; 4993 } 4994 } 4995 } while (len > 0); 4996 free(tsp, M_TEMP); 4997 sf->nsf_flags = NFSNSF_OK; 4998 sf->nsf_eograce = NFSD_MONOSEC + sf->nsf_lease + 4999 NFSRV_LEASEDELTA; 5000 } 5001 5002 /* 5003 * Update the stable storage file, now that the grace period is over. 5004 */ 5005 void 5006 nfsrv_updatestable(NFSPROC_T *p) 5007 { 5008 struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; 5009 struct nfsrv_stable *sp, *nsp; 5010 int i; 5011 struct nfsvattr nva; 5012 vnode_t vp; 5013 #if defined(__FreeBSD_version) && (__FreeBSD_version >= 500000) 5014 mount_t mp = NULL; 5015 #endif 5016 int error; 5017 5018 if (sf->nsf_fp == NULL || (sf->nsf_flags & NFSNSF_UPDATEDONE)) 5019 return; 5020 sf->nsf_flags |= NFSNSF_UPDATEDONE; 5021 /* 5022 * Ok, we need to rewrite the stable storage file. 5023 * - truncate to 0 length 5024 * - write the new first structure 5025 * - loop through the data structures, writing out any that 5026 * have timestamps older than the old boot 5027 */ 5028 if (sf->nsf_bootvals) { 5029 sf->nsf_numboots++; 5030 for (i = sf->nsf_numboots - 2; i >= 0; i--) 5031 sf->nsf_bootvals[i + 1] = sf->nsf_bootvals[i]; 5032 } else { 5033 sf->nsf_numboots = 1; 5034 sf->nsf_bootvals = (time_t *)malloc(sizeof (time_t), 5035 M_TEMP, M_WAITOK); 5036 } 5037 sf->nsf_bootvals[0] = nfsrvboottime; 5038 sf->nsf_lease = nfsrv_lease; 5039 NFSVNO_ATTRINIT(&nva); 5040 NFSVNO_SETATTRVAL(&nva, size, 0); 5041 vp = NFSFPVNODE(sf->nsf_fp); 5042 vn_start_write(vp, &mp, V_WAIT); 5043 if (NFSVOPLOCK(vp, LK_EXCLUSIVE) == 0) { 5044 error = nfsvno_setattr(vp, &nva, NFSFPCRED(sf->nsf_fp), p, 5045 NULL); 5046 NFSVOPUNLOCK(vp); 5047 } else 5048 error = EPERM; 5049 vn_finished_write(mp); 5050 if (!error) 5051 error = NFSD_RDWR(UIO_WRITE, vp, 5052 (caddr_t)&sf->nsf_rec, sizeof (struct nfsf_rec), (off_t)0, 5053 UIO_SYSSPACE, IO_SYNC, NFSFPCRED(sf->nsf_fp), NULL, p); 5054 if (!error) 5055 error = NFSD_RDWR(UIO_WRITE, vp, 5056 (caddr_t)sf->nsf_bootvals, 5057 sf->nsf_numboots * sizeof (time_t), 5058 (off_t)(sizeof (struct nfsf_rec)), 5059 UIO_SYSSPACE, IO_SYNC, NFSFPCRED(sf->nsf_fp), NULL, p); 5060 free(sf->nsf_bootvals, M_TEMP); 5061 sf->nsf_bootvals = NULL; 5062 if (error) { 5063 sf->nsf_flags &= ~NFSNSF_OK; 5064 printf("EEK! Can't write NfsV4 stable storage file\n"); 5065 return; 5066 } 5067 sf->nsf_flags |= NFSNSF_OK; 5068 5069 /* 5070 * Loop through the list and write out timestamp records for 5071 * any clients that successfully reclaimed state. 5072 */ 5073 LIST_FOREACH_SAFE(sp, &sf->nsf_head, nst_list, nsp) { 5074 if (sp->nst_flag & NFSNST_GOTSTATE) { 5075 nfsrv_writestable(sp->nst_client, sp->nst_len, 5076 NFSNST_NEWSTATE, p); 5077 sp->nst_clp->lc_flags |= LCL_STAMPEDSTABLE; 5078 } 5079 LIST_REMOVE(sp, nst_list); 5080 free(sp, M_TEMP); 5081 } 5082 nfsrv_backupstable(); 5083 } 5084 5085 /* 5086 * Append a record to the stable storage file. 5087 */ 5088 void 5089 nfsrv_writestable(u_char *client, int len, int flag, NFSPROC_T *p) 5090 { 5091 struct nfsrv_stablefirst *sf = &nfsrv_stablefirst; 5092 struct nfst_rec *sp; 5093 int error; 5094 5095 if (!(sf->nsf_flags & NFSNSF_OK) || sf->nsf_fp == NULL) 5096 return; 5097 sp = (struct nfst_rec *)malloc(sizeof (struct nfst_rec) + 5098 len - 1, M_TEMP, M_WAITOK); 5099 sp->len = len; 5100 NFSBCOPY(client, sp->client, len); 5101 sp->flag = flag; 5102 error = NFSD_RDWR(UIO_WRITE, NFSFPVNODE(sf->nsf_fp), 5103 (caddr_t)sp, sizeof (struct nfst_rec) + len - 1, (off_t)0, 5104 UIO_SYSSPACE, (IO_SYNC | IO_APPEND), NFSFPCRED(sf->nsf_fp), NULL, p); 5105 free(sp, M_TEMP); 5106 if (error) { 5107 sf->nsf_flags &= ~NFSNSF_OK; 5108 printf("EEK! Can't write NfsV4 stable storage file\n"); 5109 } 5110 } 5111 5112 /* 5113 * This function is called during the grace period to mark a client 5114 * that successfully reclaimed state. 5115 */ 5116 static void 5117 nfsrv_markstable(struct nfsclient *clp) 5118 { 5119 struct nfsrv_stable *sp; 5120 5121 /* 5122 * First find the client structure. 5123 */ 5124 LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) { 5125 if (sp->nst_len == clp->lc_idlen && 5126 !NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len)) 5127 break; 5128 } 5129 if (sp == LIST_END(&nfsrv_stablefirst.nsf_head)) 5130 return; 5131 5132 /* 5133 * Now, just mark it and set the nfsclient back pointer. 5134 */ 5135 sp->nst_flag |= NFSNST_GOTSTATE; 5136 sp->nst_clp = clp; 5137 } 5138 5139 /* 5140 * This function is called when a NFSv4.1 client does a ReclaimComplete. 5141 * Very similar to nfsrv_markstable(), except for the flag being set. 5142 */ 5143 static void 5144 nfsrv_markreclaim(struct nfsclient *clp) 5145 { 5146 struct nfsrv_stable *sp; 5147 5148 /* 5149 * First find the client structure. 5150 */ 5151 LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) { 5152 if (sp->nst_len == clp->lc_idlen && 5153 !NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len)) 5154 break; 5155 } 5156 if (sp == LIST_END(&nfsrv_stablefirst.nsf_head)) 5157 return; 5158 5159 /* 5160 * Now, just set the flag. 5161 */ 5162 sp->nst_flag |= NFSNST_RECLAIMED; 5163 } 5164 5165 /* 5166 * This function is called for a reclaim, to see if it gets grace. 5167 * It returns 0 if a reclaim is allowed, 1 otherwise. 5168 */ 5169 static int 5170 nfsrv_checkstable(struct nfsclient *clp) 5171 { 5172 struct nfsrv_stable *sp; 5173 5174 /* 5175 * First, find the entry for the client. 5176 */ 5177 LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) { 5178 if (sp->nst_len == clp->lc_idlen && 5179 !NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len)) 5180 break; 5181 } 5182 5183 /* 5184 * If not in the list, state was revoked or no state was issued 5185 * since the previous reboot, a reclaim is denied. 5186 */ 5187 if (sp == LIST_END(&nfsrv_stablefirst.nsf_head) || 5188 (sp->nst_flag & NFSNST_REVOKE) || 5189 !(nfsrv_stablefirst.nsf_flags & NFSNSF_OK)) 5190 return (1); 5191 return (0); 5192 } 5193 5194 /* 5195 * Test for and try to clear out a conflicting client. This is called by 5196 * nfsrv_lockctrl() and nfsrv_openctrl() when conflicts with other clients 5197 * a found. 5198 * The trick here is that it can't revoke a conflicting client with an 5199 * expired lease unless it holds the v4root lock, so... 5200 * If no v4root lock, get the lock and return 1 to indicate "try again". 5201 * Return 0 to indicate the conflict can't be revoked and 1 to indicate 5202 * the revocation worked and the conflicting client is "bye, bye", so it 5203 * can be tried again. 5204 * Return 2 to indicate that the vnode is VIRF_DOOMED after NFSVOPLOCK(). 5205 * Unlocks State before a non-zero value is returned. 5206 */ 5207 static int 5208 nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, vnode_t vp, 5209 NFSPROC_T *p) 5210 { 5211 int gotlock, lktype = 0; 5212 5213 /* 5214 * If lease hasn't expired, we can't fix it. 5215 */ 5216 if (clp->lc_expiry >= NFSD_MONOSEC || 5217 !(nfsrv_stablefirst.nsf_flags & NFSNSF_UPDATEDONE)) 5218 return (0); 5219 if (*haslockp == 0) { 5220 NFSUNLOCKSTATE(); 5221 if (vp != NULL) { 5222 lktype = NFSVOPISLOCKED(vp); 5223 NFSVOPUNLOCK(vp); 5224 } 5225 NFSLOCKV4ROOTMUTEX(); 5226 nfsv4_relref(&nfsv4rootfs_lock); 5227 do { 5228 gotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL, 5229 NFSV4ROOTLOCKMUTEXPTR, NULL); 5230 } while (!gotlock); 5231 NFSUNLOCKV4ROOTMUTEX(); 5232 *haslockp = 1; 5233 if (vp != NULL) { 5234 NFSVOPLOCK(vp, lktype | LK_RETRY); 5235 if (VN_IS_DOOMED(vp)) 5236 return (2); 5237 } 5238 return (1); 5239 } 5240 NFSUNLOCKSTATE(); 5241 5242 /* 5243 * Ok, we can expire the conflicting client. 5244 */ 5245 nfsrv_writestable(clp->lc_id, clp->lc_idlen, NFSNST_REVOKE, p); 5246 nfsrv_backupstable(); 5247 nfsrv_cleanclient(clp, p); 5248 nfsrv_freedeleglist(&clp->lc_deleg); 5249 nfsrv_freedeleglist(&clp->lc_olddeleg); 5250 LIST_REMOVE(clp, lc_hash); 5251 nfsrv_zapclient(clp, p); 5252 return (1); 5253 } 5254 5255 /* 5256 * Resolve a delegation conflict. 5257 * Returns 0 to indicate the conflict was resolved without sleeping. 5258 * Return -1 to indicate that the caller should check for conflicts again. 5259 * Return > 0 for an error that should be returned, normally NFSERR_DELAY. 5260 * 5261 * Also, manipulate the nfsv4root_lock, as required. It isn't changed 5262 * for a return of 0, since there was no sleep and it could be required 5263 * later. It is released for a return of NFSERR_DELAY, since the caller 5264 * will return that error. It is released when a sleep was done waiting 5265 * for the delegation to be returned or expire (so that other nfsds can 5266 * handle ops). Then, it must be acquired for the write to stable storage. 5267 * (This function is somewhat similar to nfsrv_clientconflict(), but 5268 * the semantics differ in a couple of subtle ways. The return of 0 5269 * indicates the conflict was resolved without sleeping here, not 5270 * that the conflict can't be resolved and the handling of nfsv4root_lock 5271 * differs, as noted above.) 5272 * Unlocks State before returning a non-zero value. 5273 */ 5274 static int 5275 nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p, 5276 vnode_t vp) 5277 { 5278 struct nfsclient *clp = stp->ls_clp; 5279 int gotlock, error, lktype = 0, retrycnt, zapped_clp; 5280 nfsv4stateid_t tstateid; 5281 fhandle_t tfh; 5282 5283 /* 5284 * If the conflict is with an old delegation... 5285 */ 5286 if (stp->ls_flags & NFSLCK_OLDDELEG) { 5287 /* 5288 * You can delete it, if it has expired. 5289 */ 5290 if (clp->lc_delegtime < NFSD_MONOSEC) { 5291 nfsrv_freedeleg(stp); 5292 NFSUNLOCKSTATE(); 5293 error = -1; 5294 goto out; 5295 } 5296 NFSUNLOCKSTATE(); 5297 /* 5298 * During this delay, the old delegation could expire or it 5299 * could be recovered by the client via an Open with 5300 * CLAIM_DELEGATE_PREV. 5301 * Release the nfsv4root_lock, if held. 5302 */ 5303 if (*haslockp) { 5304 *haslockp = 0; 5305 NFSLOCKV4ROOTMUTEX(); 5306 nfsv4_unlock(&nfsv4rootfs_lock, 1); 5307 NFSUNLOCKV4ROOTMUTEX(); 5308 } 5309 error = NFSERR_DELAY; 5310 goto out; 5311 } 5312 5313 /* 5314 * It's a current delegation, so: 5315 * - check to see if the delegation has expired 5316 * - if so, get the v4root lock and then expire it 5317 */ 5318 if ((stp->ls_flags & NFSLCK_DELEGRECALL) == 0 || (stp->ls_lastrecall < 5319 NFSD_MONOSEC && clp->lc_expiry >= NFSD_MONOSEC && 5320 stp->ls_delegtime >= NFSD_MONOSEC)) { 5321 /* 5322 * - do a recall callback, since not yet done 5323 * For now, never allow truncate to be set. To use 5324 * truncate safely, it must be guaranteed that the 5325 * Remove, Rename or Setattr with size of 0 will 5326 * succeed and that would require major changes to 5327 * the VFS/Vnode OPs. 5328 * Set the expiry time large enough so that it won't expire 5329 * until after the callback, then set it correctly, once 5330 * the callback is done. (The delegation will now time 5331 * out whether or not the Recall worked ok. The timeout 5332 * will be extended when ops are done on the delegation 5333 * stateid, up to the timelimit.) 5334 */ 5335 if ((stp->ls_flags & NFSLCK_DELEGRECALL) == 0) { 5336 stp->ls_delegtime = NFSD_MONOSEC + (2 * nfsrv_lease) + 5337 NFSRV_LEASEDELTA; 5338 stp->ls_delegtimelimit = NFSD_MONOSEC + (6 * 5339 nfsrv_lease) + NFSRV_LEASEDELTA; 5340 stp->ls_flags |= NFSLCK_DELEGRECALL; 5341 } 5342 stp->ls_lastrecall = time_uptime + 1; 5343 5344 /* 5345 * Loop NFSRV_CBRETRYCNT times while the CBRecall replies 5346 * NFSERR_BADSTATEID or NFSERR_BADHANDLE. This is done 5347 * in order to try and avoid a race that could happen 5348 * when a CBRecall request passed the Open reply with 5349 * the delegation in it when transitting the network. 5350 * Since nfsrv_docallback will sleep, don't use stp after 5351 * the call. 5352 */ 5353 NFSBCOPY((caddr_t)&stp->ls_stateid, (caddr_t)&tstateid, 5354 sizeof (tstateid)); 5355 NFSBCOPY((caddr_t)&stp->ls_lfp->lf_fh, (caddr_t)&tfh, 5356 sizeof (tfh)); 5357 NFSUNLOCKSTATE(); 5358 if (*haslockp) { 5359 *haslockp = 0; 5360 NFSLOCKV4ROOTMUTEX(); 5361 nfsv4_unlock(&nfsv4rootfs_lock, 1); 5362 NFSUNLOCKV4ROOTMUTEX(); 5363 } 5364 retrycnt = 0; 5365 do { 5366 error = nfsrv_docallback(clp, NFSV4OP_CBRECALL, 5367 &tstateid, 0, &tfh, NULL, NULL, 0, p); 5368 retrycnt++; 5369 } while ((error == NFSERR_BADSTATEID || 5370 error == NFSERR_BADHANDLE) && retrycnt < NFSV4_CBRETRYCNT); 5371 error = NFSERR_DELAY; 5372 goto out; 5373 } 5374 5375 if (clp->lc_expiry >= NFSD_MONOSEC && 5376 stp->ls_delegtime >= NFSD_MONOSEC) { 5377 NFSUNLOCKSTATE(); 5378 /* 5379 * A recall has been done, but it has not yet expired. 5380 * So, RETURN_DELAY. 5381 */ 5382 if (*haslockp) { 5383 *haslockp = 0; 5384 NFSLOCKV4ROOTMUTEX(); 5385 nfsv4_unlock(&nfsv4rootfs_lock, 1); 5386 NFSUNLOCKV4ROOTMUTEX(); 5387 } 5388 error = NFSERR_DELAY; 5389 goto out; 5390 } 5391 5392 /* 5393 * If we don't yet have the lock, just get it and then return, 5394 * since we need that before deleting expired state, such as 5395 * this delegation. 5396 * When getting the lock, unlock the vnode, so other nfsds that 5397 * are in progress, won't get stuck waiting for the vnode lock. 5398 */ 5399 if (*haslockp == 0) { 5400 NFSUNLOCKSTATE(); 5401 if (vp != NULL) { 5402 lktype = NFSVOPISLOCKED(vp); 5403 NFSVOPUNLOCK(vp); 5404 } 5405 NFSLOCKV4ROOTMUTEX(); 5406 nfsv4_relref(&nfsv4rootfs_lock); 5407 do { 5408 gotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL, 5409 NFSV4ROOTLOCKMUTEXPTR, NULL); 5410 } while (!gotlock); 5411 NFSUNLOCKV4ROOTMUTEX(); 5412 *haslockp = 1; 5413 if (vp != NULL) { 5414 NFSVOPLOCK(vp, lktype | LK_RETRY); 5415 if (VN_IS_DOOMED(vp)) { 5416 *haslockp = 0; 5417 NFSLOCKV4ROOTMUTEX(); 5418 nfsv4_unlock(&nfsv4rootfs_lock, 1); 5419 NFSUNLOCKV4ROOTMUTEX(); 5420 error = NFSERR_PERM; 5421 goto out; 5422 } 5423 } 5424 error = -1; 5425 goto out; 5426 } 5427 5428 NFSUNLOCKSTATE(); 5429 /* 5430 * Ok, we can delete the expired delegation. 5431 * First, write the Revoke record to stable storage and then 5432 * clear out the conflict. 5433 * Since all other nfsd threads are now blocked, we can safely 5434 * sleep without the state changing. 5435 */ 5436 nfsrv_writestable(clp->lc_id, clp->lc_idlen, NFSNST_REVOKE, p); 5437 nfsrv_backupstable(); 5438 if (clp->lc_expiry < NFSD_MONOSEC) { 5439 nfsrv_cleanclient(clp, p); 5440 nfsrv_freedeleglist(&clp->lc_deleg); 5441 nfsrv_freedeleglist(&clp->lc_olddeleg); 5442 LIST_REMOVE(clp, lc_hash); 5443 zapped_clp = 1; 5444 } else { 5445 nfsrv_freedeleg(stp); 5446 zapped_clp = 0; 5447 } 5448 if (zapped_clp) 5449 nfsrv_zapclient(clp, p); 5450 error = -1; 5451 5452 out: 5453 NFSEXITCODE(error); 5454 return (error); 5455 } 5456 5457 /* 5458 * Check for a remove allowed, if remove is set to 1 and get rid of 5459 * delegations. 5460 */ 5461 int 5462 nfsrv_checkremove(vnode_t vp, int remove, struct nfsrv_descript *nd, 5463 nfsquad_t clientid, NFSPROC_T *p) 5464 { 5465 struct nfsclient *clp; 5466 struct nfsstate *stp; 5467 struct nfslockfile *lfp; 5468 int error, haslock = 0; 5469 fhandle_t nfh; 5470 5471 clp = NULL; 5472 /* 5473 * First, get the lock file structure. 5474 * (A return of -1 means no associated state, so remove ok.) 5475 */ 5476 error = nfsrv_getlockfh(vp, NFSLCK_CHECK, NULL, &nfh, p); 5477 tryagain: 5478 NFSLOCKSTATE(); 5479 if (error == 0 && clientid.qval != 0) 5480 error = nfsrv_getclient(clientid, CLOPS_RENEW, &clp, NULL, 5481 (nfsquad_t)((u_quad_t)0), 0, nd, p); 5482 if (!error) 5483 error = nfsrv_getlockfile(NFSLCK_CHECK, NULL, &lfp, &nfh, 0); 5484 if (error) { 5485 NFSUNLOCKSTATE(); 5486 if (haslock) { 5487 NFSLOCKV4ROOTMUTEX(); 5488 nfsv4_unlock(&nfsv4rootfs_lock, 1); 5489 NFSUNLOCKV4ROOTMUTEX(); 5490 } 5491 if (error == -1) 5492 error = 0; 5493 goto out; 5494 } 5495 5496 /* 5497 * Now, we must Recall any delegations. 5498 */ 5499 error = nfsrv_cleandeleg(vp, lfp, clp, &haslock, p); 5500 if (error) { 5501 /* 5502 * nfsrv_cleandeleg() unlocks state for non-zero 5503 * return. 5504 */ 5505 if (error == -1) 5506 goto tryagain; 5507 if (haslock) { 5508 NFSLOCKV4ROOTMUTEX(); 5509 nfsv4_unlock(&nfsv4rootfs_lock, 1); 5510 NFSUNLOCKV4ROOTMUTEX(); 5511 } 5512 goto out; 5513 } 5514 5515 /* 5516 * Now, look for a conflicting open share. 5517 */ 5518 if (remove) { 5519 /* 5520 * If the entry in the directory was the last reference to the 5521 * corresponding filesystem object, the object can be destroyed 5522 * */ 5523 if(lfp->lf_usecount>1) 5524 LIST_FOREACH(stp, &lfp->lf_open, ls_file) { 5525 if (stp->ls_flags & NFSLCK_WRITEDENY) { 5526 error = NFSERR_FILEOPEN; 5527 break; 5528 } 5529 } 5530 } 5531 5532 NFSUNLOCKSTATE(); 5533 if (haslock) { 5534 NFSLOCKV4ROOTMUTEX(); 5535 nfsv4_unlock(&nfsv4rootfs_lock, 1); 5536 NFSUNLOCKV4ROOTMUTEX(); 5537 } 5538 5539 out: 5540 NFSEXITCODE(error); 5541 return (error); 5542 } 5543 5544 /* 5545 * Clear out all delegations for the file referred to by lfp. 5546 * May return NFSERR_DELAY, if there will be a delay waiting for 5547 * delegations to expire. 5548 * Returns -1 to indicate it slept while recalling a delegation. 5549 * This function has the side effect of deleting the nfslockfile structure, 5550 * if it no longer has associated state and didn't have to sleep. 5551 * Unlocks State before a non-zero value is returned. 5552 */ 5553 static int 5554 nfsrv_cleandeleg(vnode_t vp, struct nfslockfile *lfp, 5555 struct nfsclient *clp, int *haslockp, NFSPROC_T *p) 5556 { 5557 struct nfsstate *stp, *nstp; 5558 int ret = 0; 5559 5560 stp = LIST_FIRST(&lfp->lf_deleg); 5561 while (stp != LIST_END(&lfp->lf_deleg)) { 5562 nstp = LIST_NEXT(stp, ls_file); 5563 if (stp->ls_clp != clp) { 5564 ret = nfsrv_delegconflict(stp, haslockp, p, vp); 5565 if (ret) { 5566 /* 5567 * nfsrv_delegconflict() unlocks state 5568 * when it returns non-zero. 5569 */ 5570 goto out; 5571 } 5572 } 5573 stp = nstp; 5574 } 5575 out: 5576 NFSEXITCODE(ret); 5577 return (ret); 5578 } 5579 5580 /* 5581 * There are certain operations that, when being done outside of NFSv4, 5582 * require that any NFSv4 delegation for the file be recalled. 5583 * This function is to be called for those cases: 5584 * VOP_RENAME() - When a delegation is being recalled for any reason, 5585 * the client may have to do Opens against the server, using the file's 5586 * final component name. If the file has been renamed on the server, 5587 * that component name will be incorrect and the Open will fail. 5588 * VOP_REMOVE() - Theoretically, a client could Open a file after it has 5589 * been removed on the server, if there is a delegation issued to 5590 * that client for the file. I say "theoretically" since clients 5591 * normally do an Access Op before the Open and that Access Op will 5592 * fail with ESTALE. Note that NFSv2 and 3 don't even do Opens, so 5593 * they will detect the file's removal in the same manner. (There is 5594 * one case where RFC3530 allows a client to do an Open without first 5595 * doing an Access Op, which is passage of a check against the ACE 5596 * returned with a Write delegation, but current practice is to ignore 5597 * the ACE and always do an Access Op.) 5598 * Since the functions can only be called with an unlocked vnode, this 5599 * can't be done at this time. 5600 * VOP_ADVLOCK() - When a client holds a delegation, it can issue byte range 5601 * locks locally in the client, which are not visible to the server. To 5602 * deal with this, issuing of delegations for a vnode must be disabled 5603 * and all delegations for the vnode recalled. This is done via the 5604 * second function, using the VV_DISABLEDELEG vflag on the vnode. 5605 */ 5606 void 5607 nfsd_recalldelegation(vnode_t vp, NFSPROC_T *p) 5608 { 5609 time_t starttime; 5610 int error; 5611 5612 /* 5613 * First, check to see if the server is currently running and it has 5614 * been called for a regular file when issuing delegations. 5615 */ 5616 if (newnfs_numnfsd == 0 || vp->v_type != VREG || 5617 nfsrv_issuedelegs == 0) 5618 return; 5619 5620 KASSERT((NFSVOPISLOCKED(vp) != LK_EXCLUSIVE), ("vp %p is locked", vp)); 5621 /* 5622 * First, get a reference on the nfsv4rootfs_lock so that an 5623 * exclusive lock cannot be acquired by another thread. 5624 */ 5625 NFSLOCKV4ROOTMUTEX(); 5626 nfsv4_getref(&nfsv4rootfs_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, NULL); 5627 NFSUNLOCKV4ROOTMUTEX(); 5628 5629 /* 5630 * Now, call nfsrv_checkremove() in a loop while it returns 5631 * NFSERR_DELAY. Return upon any other error or when timed out. 5632 */ 5633 starttime = NFSD_MONOSEC; 5634 do { 5635 if (NFSVOPLOCK(vp, LK_EXCLUSIVE) == 0) { 5636 error = nfsrv_checkremove(vp, 0, NULL, 5637 (nfsquad_t)((u_quad_t)0), p); 5638 NFSVOPUNLOCK(vp); 5639 } else 5640 error = EPERM; 5641 if (error == NFSERR_DELAY) { 5642 if (NFSD_MONOSEC - starttime > NFS_REMOVETIMEO) 5643 break; 5644 /* Sleep for a short period of time */ 5645 (void) nfs_catnap(PZERO, 0, "nfsremove"); 5646 } 5647 } while (error == NFSERR_DELAY); 5648 NFSLOCKV4ROOTMUTEX(); 5649 nfsv4_relref(&nfsv4rootfs_lock); 5650 NFSUNLOCKV4ROOTMUTEX(); 5651 } 5652 5653 void 5654 nfsd_disabledelegation(vnode_t vp, NFSPROC_T *p) 5655 { 5656 5657 #ifdef VV_DISABLEDELEG 5658 /* 5659 * First, flag issuance of delegations disabled. 5660 */ 5661 atomic_set_long(&vp->v_vflag, VV_DISABLEDELEG); 5662 #endif 5663 5664 /* 5665 * Then call nfsd_recalldelegation() to get rid of all extant 5666 * delegations. 5667 */ 5668 nfsd_recalldelegation(vp, p); 5669 } 5670 5671 /* 5672 * Check for conflicting locks, etc. and then get rid of delegations. 5673 * (At one point I thought that I should get rid of delegations for any 5674 * Setattr, since it could potentially disallow the I/O op (read or write) 5675 * allowed by the delegation. However, Setattr Ops that aren't changing 5676 * the size get a stateid of all 0s, so you can't tell if it is a delegation 5677 * for the same client or a different one, so I decided to only get rid 5678 * of delegations for other clients when the size is being changed.) 5679 * In general, a Setattr can disable NFS I/O Ops that are outstanding, such 5680 * as Write backs, even if there is no delegation, so it really isn't any 5681 * different?) 5682 */ 5683 int 5684 nfsrv_checksetattr(vnode_t vp, struct nfsrv_descript *nd, 5685 nfsv4stateid_t *stateidp, struct nfsvattr *nvap, nfsattrbit_t *attrbitp, 5686 struct nfsexstuff *exp, NFSPROC_T *p) 5687 { 5688 struct nfsstate st, *stp = &st; 5689 struct nfslock lo, *lop = &lo; 5690 int error = 0; 5691 nfsquad_t clientid; 5692 5693 if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_SIZE)) { 5694 stp->ls_flags = (NFSLCK_CHECK | NFSLCK_WRITEACCESS); 5695 lop->lo_first = nvap->na_size; 5696 } else { 5697 stp->ls_flags = 0; 5698 lop->lo_first = 0; 5699 } 5700 if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_OWNER) || 5701 NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_OWNERGROUP) || 5702 NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_MODE) || 5703 NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_ACL)) 5704 stp->ls_flags |= NFSLCK_SETATTR; 5705 if (stp->ls_flags == 0) 5706 goto out; 5707 lop->lo_end = NFS64BITSSET; 5708 lop->lo_flags = NFSLCK_WRITE; 5709 stp->ls_ownerlen = 0; 5710 stp->ls_op = NULL; 5711 stp->ls_uid = nd->nd_cred->cr_uid; 5712 stp->ls_stateid.seqid = stateidp->seqid; 5713 clientid.lval[0] = stp->ls_stateid.other[0] = stateidp->other[0]; 5714 clientid.lval[1] = stp->ls_stateid.other[1] = stateidp->other[1]; 5715 stp->ls_stateid.other[2] = stateidp->other[2]; 5716 error = nfsrv_lockctrl(vp, &stp, &lop, NULL, clientid, 5717 stateidp, exp, nd, p); 5718 5719 out: 5720 NFSEXITCODE2(error, nd); 5721 return (error); 5722 } 5723 5724 /* 5725 * Check for a write delegation and do a CBGETATTR if there is one, updating 5726 * the attributes, as required. 5727 * Should I return an error if I can't get the attributes? (For now, I'll 5728 * just return ok. 5729 */ 5730 int 5731 nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp, 5732 struct nfsvattr *nvap, nfsattrbit_t *attrbitp, NFSPROC_T *p) 5733 { 5734 struct nfsstate *stp; 5735 struct nfslockfile *lfp; 5736 struct nfsclient *clp; 5737 struct nfsvattr nva; 5738 fhandle_t nfh; 5739 int error = 0; 5740 nfsattrbit_t cbbits; 5741 u_quad_t delegfilerev; 5742 5743 NFSCBGETATTR_ATTRBIT(attrbitp, &cbbits); 5744 if (!NFSNONZERO_ATTRBIT(&cbbits)) 5745 goto out; 5746 if (nfsrv_writedelegcnt == 0) 5747 goto out; 5748 5749 /* 5750 * Get the lock file structure. 5751 * (A return of -1 means no associated state, so return ok.) 5752 */ 5753 error = nfsrv_getlockfh(vp, NFSLCK_CHECK, NULL, &nfh, p); 5754 NFSLOCKSTATE(); 5755 if (!error) 5756 error = nfsrv_getlockfile(NFSLCK_CHECK, NULL, &lfp, &nfh, 0); 5757 if (error) { 5758 NFSUNLOCKSTATE(); 5759 if (error == -1) 5760 error = 0; 5761 goto out; 5762 } 5763 5764 /* 5765 * Now, look for a write delegation. 5766 */ 5767 LIST_FOREACH(stp, &lfp->lf_deleg, ls_file) { 5768 if (stp->ls_flags & NFSLCK_DELEGWRITE) 5769 break; 5770 } 5771 if (stp == LIST_END(&lfp->lf_deleg)) { 5772 NFSUNLOCKSTATE(); 5773 goto out; 5774 } 5775 clp = stp->ls_clp; 5776 5777 /* If the clientid is not confirmed, ignore the delegation. */ 5778 if (clp->lc_flags & LCL_NEEDSCONFIRM) { 5779 NFSUNLOCKSTATE(); 5780 goto out; 5781 } 5782 5783 delegfilerev = stp->ls_filerev; 5784 /* 5785 * If the Write delegation was issued as a part of this Compound RPC 5786 * or if we have an Implied Clientid (used in a previous Op in this 5787 * compound) and it is the client the delegation was issued to, 5788 * just return ok. 5789 * I also assume that it is from the same client iff the network 5790 * host IP address is the same as the callback address. (Not 5791 * exactly correct by the RFC, but avoids a lot of Getattr 5792 * callbacks.) 5793 */ 5794 if (nd->nd_compref == stp->ls_compref || 5795 ((nd->nd_flag & ND_IMPLIEDCLID) && 5796 clp->lc_clientid.qval == nd->nd_clientid.qval) || 5797 nfsaddr2_match(clp->lc_req.nr_nam, nd->nd_nam)) { 5798 NFSUNLOCKSTATE(); 5799 goto out; 5800 } 5801 5802 /* 5803 * We are now done with the delegation state structure, 5804 * so the statelock can be released and we can now tsleep(). 5805 */ 5806 5807 /* 5808 * Now, we must do the CB Getattr callback, to see if Change or Size 5809 * has changed. 5810 */ 5811 if (clp->lc_expiry >= NFSD_MONOSEC) { 5812 NFSUNLOCKSTATE(); 5813 NFSVNO_ATTRINIT(&nva); 5814 nva.na_filerev = NFS64BITSSET; 5815 error = nfsrv_docallback(clp, NFSV4OP_CBGETATTR, NULL, 5816 0, &nfh, &nva, &cbbits, 0, p); 5817 if (!error) { 5818 if ((nva.na_filerev != NFS64BITSSET && 5819 nva.na_filerev > delegfilerev) || 5820 (NFSVNO_ISSETSIZE(&nva) && 5821 nva.na_size != nvap->na_size)) { 5822 error = nfsvno_updfilerev(vp, nvap, nd, p); 5823 if (NFSVNO_ISSETSIZE(&nva)) 5824 nvap->na_size = nva.na_size; 5825 } 5826 } else 5827 error = 0; /* Ignore callback errors for now. */ 5828 } else { 5829 NFSUNLOCKSTATE(); 5830 } 5831 5832 out: 5833 NFSEXITCODE2(error, nd); 5834 return (error); 5835 } 5836 5837 /* 5838 * This function looks for openowners that haven't had any opens for 5839 * a while and throws them away. Called by an nfsd when NFSNSF_NOOPENS 5840 * is set. 5841 */ 5842 void 5843 nfsrv_throwawayopens(NFSPROC_T *p) 5844 { 5845 struct nfsclient *clp, *nclp; 5846 struct nfsstate *stp, *nstp; 5847 int i; 5848 5849 NFSLOCKSTATE(); 5850 nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NOOPENS; 5851 /* 5852 * For each client... 5853 */ 5854 for (i = 0; i < nfsrv_clienthashsize; i++) { 5855 LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) { 5856 LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) { 5857 if (LIST_EMPTY(&stp->ls_open) && 5858 (stp->ls_noopens > NFSNOOPEN || 5859 (nfsrv_openpluslock * 2) > 5860 nfsrv_v4statelimit)) 5861 nfsrv_freeopenowner(stp, 0, p); 5862 } 5863 } 5864 } 5865 NFSUNLOCKSTATE(); 5866 } 5867 5868 /* 5869 * This function checks to see if the credentials are the same. 5870 * Returns 1 for not same, 0 otherwise. 5871 */ 5872 static int 5873 nfsrv_notsamecredname(struct nfsrv_descript *nd, struct nfsclient *clp) 5874 { 5875 5876 if (nd->nd_flag & ND_GSS) { 5877 if (!(clp->lc_flags & LCL_GSS)) 5878 return (1); 5879 if (clp->lc_flags & LCL_NAME) { 5880 if (nd->nd_princlen != clp->lc_namelen || 5881 NFSBCMP(nd->nd_principal, clp->lc_name, 5882 clp->lc_namelen)) 5883 return (1); 5884 else 5885 return (0); 5886 } 5887 if (nd->nd_cred->cr_uid == clp->lc_uid) 5888 return (0); 5889 else 5890 return (1); 5891 } else if (clp->lc_flags & LCL_GSS) 5892 return (1); 5893 /* 5894 * For AUTH_SYS, allow the same uid or root. (This is underspecified 5895 * in RFC3530, which talks about principals, but doesn't say anything 5896 * about uids for AUTH_SYS.) 5897 */ 5898 if (nd->nd_cred->cr_uid == clp->lc_uid || nd->nd_cred->cr_uid == 0) 5899 return (0); 5900 else 5901 return (1); 5902 } 5903 5904 /* 5905 * Calculate the lease expiry time. 5906 */ 5907 static time_t 5908 nfsrv_leaseexpiry(void) 5909 { 5910 5911 if (nfsrv_stablefirst.nsf_eograce > NFSD_MONOSEC) 5912 return (NFSD_MONOSEC + 2 * (nfsrv_lease + NFSRV_LEASEDELTA)); 5913 return (NFSD_MONOSEC + nfsrv_lease + NFSRV_LEASEDELTA); 5914 } 5915 5916 /* 5917 * Delay the delegation timeout as far as ls_delegtimelimit, as required. 5918 */ 5919 static void 5920 nfsrv_delaydelegtimeout(struct nfsstate *stp) 5921 { 5922 5923 if ((stp->ls_flags & NFSLCK_DELEGRECALL) == 0) 5924 return; 5925 5926 if ((stp->ls_delegtime + 15) > NFSD_MONOSEC && 5927 stp->ls_delegtime < stp->ls_delegtimelimit) { 5928 stp->ls_delegtime += nfsrv_lease; 5929 if (stp->ls_delegtime > stp->ls_delegtimelimit) 5930 stp->ls_delegtime = stp->ls_delegtimelimit; 5931 } 5932 } 5933 5934 /* 5935 * This function checks to see if there is any other state associated 5936 * with the openowner for this Open. 5937 * It returns 1 if there is no other state, 0 otherwise. 5938 */ 5939 static int 5940 nfsrv_nootherstate(struct nfsstate *stp) 5941 { 5942 struct nfsstate *tstp; 5943 5944 LIST_FOREACH(tstp, &stp->ls_openowner->ls_open, ls_list) { 5945 if (tstp != stp || !LIST_EMPTY(&tstp->ls_lock)) 5946 return (0); 5947 } 5948 return (1); 5949 } 5950 5951 /* 5952 * Create a list of lock deltas (changes to local byte range locking 5953 * that can be rolled back using the list) and apply the changes via 5954 * nfsvno_advlock(). Optionally, lock the list. It is expected that either 5955 * the rollback or update function will be called after this. 5956 * It returns an error (and rolls back, as required), if any nfsvno_advlock() 5957 * call fails. If it returns an error, it will unlock the list. 5958 */ 5959 static int 5960 nfsrv_locallock(vnode_t vp, struct nfslockfile *lfp, int flags, 5961 uint64_t first, uint64_t end, struct nfslockconflict *cfp, NFSPROC_T *p) 5962 { 5963 struct nfslock *lop, *nlop; 5964 int error = 0; 5965 5966 /* Loop through the list of locks. */ 5967 lop = LIST_FIRST(&lfp->lf_locallock); 5968 while (first < end && lop != NULL) { 5969 nlop = LIST_NEXT(lop, lo_lckowner); 5970 if (first >= lop->lo_end) { 5971 /* not there yet */ 5972 lop = nlop; 5973 } else if (first < lop->lo_first) { 5974 /* new one starts before entry in list */ 5975 if (end <= lop->lo_first) { 5976 /* no overlap between old and new */ 5977 error = nfsrv_dolocal(vp, lfp, flags, 5978 NFSLCK_UNLOCK, first, end, cfp, p); 5979 if (error != 0) 5980 break; 5981 first = end; 5982 } else { 5983 /* handle fragment overlapped with new one */ 5984 error = nfsrv_dolocal(vp, lfp, flags, 5985 NFSLCK_UNLOCK, first, lop->lo_first, cfp, 5986 p); 5987 if (error != 0) 5988 break; 5989 first = lop->lo_first; 5990 } 5991 } else { 5992 /* new one overlaps this entry in list */ 5993 if (end <= lop->lo_end) { 5994 /* overlaps all of new one */ 5995 error = nfsrv_dolocal(vp, lfp, flags, 5996 lop->lo_flags, first, end, cfp, p); 5997 if (error != 0) 5998 break; 5999 first = end; 6000 } else { 6001 /* handle fragment overlapped with new one */ 6002 error = nfsrv_dolocal(vp, lfp, flags, 6003 lop->lo_flags, first, lop->lo_end, cfp, p); 6004 if (error != 0) 6005 break; 6006 first = lop->lo_end; 6007 lop = nlop; 6008 } 6009 } 6010 } 6011 if (first < end && error == 0) 6012 /* handle fragment past end of list */ 6013 error = nfsrv_dolocal(vp, lfp, flags, NFSLCK_UNLOCK, first, 6014 end, cfp, p); 6015 6016 NFSEXITCODE(error); 6017 return (error); 6018 } 6019 6020 /* 6021 * Local lock unlock. Unlock all byte ranges that are no longer locked 6022 * by NFSv4. To do this, unlock any subranges of first-->end that 6023 * do not overlap with the byte ranges of any lock in the lfp->lf_lock 6024 * list. This list has all locks for the file held by other 6025 * <clientid, lockowner> tuples. The list is ordered by increasing 6026 * lo_first value, but may have entries that overlap each other, for 6027 * the case of read locks. 6028 */ 6029 static void 6030 nfsrv_localunlock(vnode_t vp, struct nfslockfile *lfp, uint64_t init_first, 6031 uint64_t init_end, NFSPROC_T *p) 6032 { 6033 struct nfslock *lop; 6034 uint64_t first, end, prevfirst __unused; 6035 6036 first = init_first; 6037 end = init_end; 6038 while (first < init_end) { 6039 /* Loop through all nfs locks, adjusting first and end */ 6040 prevfirst = 0; 6041 LIST_FOREACH(lop, &lfp->lf_lock, lo_lckfile) { 6042 KASSERT(prevfirst <= lop->lo_first, 6043 ("nfsv4 locks out of order")); 6044 KASSERT(lop->lo_first < lop->lo_end, 6045 ("nfsv4 bogus lock")); 6046 prevfirst = lop->lo_first; 6047 if (first >= lop->lo_first && 6048 first < lop->lo_end) 6049 /* 6050 * Overlaps with initial part, so trim 6051 * off that initial part by moving first past 6052 * it. 6053 */ 6054 first = lop->lo_end; 6055 else if (end > lop->lo_first && 6056 lop->lo_first > first) { 6057 /* 6058 * This lock defines the end of the 6059 * segment to unlock, so set end to the 6060 * start of it and break out of the loop. 6061 */ 6062 end = lop->lo_first; 6063 break; 6064 } 6065 if (first >= end) 6066 /* 6067 * There is no segment left to do, so 6068 * break out of this loop and then exit 6069 * the outer while() since first will be set 6070 * to end, which must equal init_end here. 6071 */ 6072 break; 6073 } 6074 if (first < end) { 6075 /* Unlock this segment */ 6076 (void) nfsrv_dolocal(vp, lfp, NFSLCK_UNLOCK, 6077 NFSLCK_READ, first, end, NULL, p); 6078 nfsrv_locallock_commit(lfp, NFSLCK_UNLOCK, 6079 first, end); 6080 } 6081 /* 6082 * Now move past this segment and look for any further 6083 * segment in the range, if there is one. 6084 */ 6085 first = end; 6086 end = init_end; 6087 } 6088 } 6089 6090 /* 6091 * Do the local lock operation and update the rollback list, as required. 6092 * Perform the rollback and return the error if nfsvno_advlock() fails. 6093 */ 6094 static int 6095 nfsrv_dolocal(vnode_t vp, struct nfslockfile *lfp, int flags, int oldflags, 6096 uint64_t first, uint64_t end, struct nfslockconflict *cfp, NFSPROC_T *p) 6097 { 6098 struct nfsrollback *rlp; 6099 int error = 0, ltype, oldltype; 6100 6101 if (flags & NFSLCK_WRITE) 6102 ltype = F_WRLCK; 6103 else if (flags & NFSLCK_READ) 6104 ltype = F_RDLCK; 6105 else 6106 ltype = F_UNLCK; 6107 if (oldflags & NFSLCK_WRITE) 6108 oldltype = F_WRLCK; 6109 else if (oldflags & NFSLCK_READ) 6110 oldltype = F_RDLCK; 6111 else 6112 oldltype = F_UNLCK; 6113 if (ltype == oldltype || (oldltype == F_WRLCK && ltype == F_RDLCK)) 6114 /* nothing to do */ 6115 goto out; 6116 error = nfsvno_advlock(vp, ltype, first, end, p); 6117 if (error != 0) { 6118 if (cfp != NULL) { 6119 cfp->cl_clientid.lval[0] = 0; 6120 cfp->cl_clientid.lval[1] = 0; 6121 cfp->cl_first = 0; 6122 cfp->cl_end = NFS64BITSSET; 6123 cfp->cl_flags = NFSLCK_WRITE; 6124 cfp->cl_ownerlen = 5; 6125 NFSBCOPY("LOCAL", cfp->cl_owner, 5); 6126 } 6127 nfsrv_locallock_rollback(vp, lfp, p); 6128 } else if (ltype != F_UNLCK) { 6129 rlp = malloc(sizeof (struct nfsrollback), M_NFSDROLLBACK, 6130 M_WAITOK); 6131 rlp->rlck_first = first; 6132 rlp->rlck_end = end; 6133 rlp->rlck_type = oldltype; 6134 LIST_INSERT_HEAD(&lfp->lf_rollback, rlp, rlck_list); 6135 } 6136 6137 out: 6138 NFSEXITCODE(error); 6139 return (error); 6140 } 6141 6142 /* 6143 * Roll back local lock changes and free up the rollback list. 6144 */ 6145 static void 6146 nfsrv_locallock_rollback(vnode_t vp, struct nfslockfile *lfp, NFSPROC_T *p) 6147 { 6148 struct nfsrollback *rlp, *nrlp; 6149 6150 LIST_FOREACH_SAFE(rlp, &lfp->lf_rollback, rlck_list, nrlp) { 6151 (void) nfsvno_advlock(vp, rlp->rlck_type, rlp->rlck_first, 6152 rlp->rlck_end, p); 6153 free(rlp, M_NFSDROLLBACK); 6154 } 6155 LIST_INIT(&lfp->lf_rollback); 6156 } 6157 6158 /* 6159 * Update local lock list and delete rollback list (ie now committed to the 6160 * local locks). Most of the work is done by the internal function. 6161 */ 6162 static void 6163 nfsrv_locallock_commit(struct nfslockfile *lfp, int flags, uint64_t first, 6164 uint64_t end) 6165 { 6166 struct nfsrollback *rlp, *nrlp; 6167 struct nfslock *new_lop, *other_lop; 6168 6169 new_lop = malloc(sizeof (struct nfslock), M_NFSDLOCK, M_WAITOK); 6170 if (flags & (NFSLCK_READ | NFSLCK_WRITE)) 6171 other_lop = malloc(sizeof (struct nfslock), M_NFSDLOCK, 6172 M_WAITOK); 6173 else 6174 other_lop = NULL; 6175 new_lop->lo_flags = flags; 6176 new_lop->lo_first = first; 6177 new_lop->lo_end = end; 6178 nfsrv_updatelock(NULL, &new_lop, &other_lop, lfp); 6179 if (new_lop != NULL) 6180 free(new_lop, M_NFSDLOCK); 6181 if (other_lop != NULL) 6182 free(other_lop, M_NFSDLOCK); 6183 6184 /* and get rid of the rollback list */ 6185 LIST_FOREACH_SAFE(rlp, &lfp->lf_rollback, rlck_list, nrlp) 6186 free(rlp, M_NFSDROLLBACK); 6187 LIST_INIT(&lfp->lf_rollback); 6188 } 6189 6190 /* 6191 * Lock the struct nfslockfile for local lock updating. 6192 */ 6193 static void 6194 nfsrv_locklf(struct nfslockfile *lfp) 6195 { 6196 int gotlock; 6197 6198 /* lf_usecount ensures *lfp won't be free'd */ 6199 lfp->lf_usecount++; 6200 do { 6201 gotlock = nfsv4_lock(&lfp->lf_locallock_lck, 1, NULL, 6202 NFSSTATEMUTEXPTR, NULL); 6203 } while (gotlock == 0); 6204 lfp->lf_usecount--; 6205 } 6206 6207 /* 6208 * Unlock the struct nfslockfile after local lock updating. 6209 */ 6210 static void 6211 nfsrv_unlocklf(struct nfslockfile *lfp) 6212 { 6213 6214 nfsv4_unlock(&lfp->lf_locallock_lck, 0); 6215 } 6216 6217 /* 6218 * Clear out all state for the NFSv4 server. 6219 * Must be called by a thread that can sleep when no nfsds are running. 6220 */ 6221 void 6222 nfsrv_throwawayallstate(NFSPROC_T *p) 6223 { 6224 struct nfsclient *clp, *nclp; 6225 struct nfslockfile *lfp, *nlfp; 6226 int i; 6227 6228 /* 6229 * For each client, clean out the state and then free the structure. 6230 */ 6231 for (i = 0; i < nfsrv_clienthashsize; i++) { 6232 LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) { 6233 nfsrv_cleanclient(clp, p); 6234 nfsrv_freedeleglist(&clp->lc_deleg); 6235 nfsrv_freedeleglist(&clp->lc_olddeleg); 6236 free(clp->lc_stateid, M_NFSDCLIENT); 6237 free(clp, M_NFSDCLIENT); 6238 } 6239 } 6240 6241 /* 6242 * Also, free up any remaining lock file structures. 6243 */ 6244 for (i = 0; i < nfsrv_lockhashsize; i++) { 6245 LIST_FOREACH_SAFE(lfp, &nfslockhash[i], lf_hash, nlfp) { 6246 printf("nfsd unload: fnd a lock file struct\n"); 6247 nfsrv_freenfslockfile(lfp); 6248 } 6249 } 6250 6251 /* And get rid of the deviceid structures and layouts. */ 6252 nfsrv_freealllayoutsanddevids(); 6253 } 6254 6255 /* 6256 * Check the sequence# for the session and slot provided as an argument. 6257 * Also, renew the lease if the session will return NFS_OK. 6258 */ 6259 int 6260 nfsrv_checksequence(struct nfsrv_descript *nd, uint32_t sequenceid, 6261 uint32_t *highest_slotidp, uint32_t *target_highest_slotidp, int cache_this, 6262 uint32_t *sflagsp, NFSPROC_T *p) 6263 { 6264 struct nfsdsession *sep; 6265 struct nfssessionhash *shp; 6266 int error; 6267 6268 shp = NFSSESSIONHASH(nd->nd_sessionid); 6269 NFSLOCKSESSION(shp); 6270 sep = nfsrv_findsession(nd->nd_sessionid); 6271 if (sep == NULL) { 6272 NFSUNLOCKSESSION(shp); 6273 return (NFSERR_BADSESSION); 6274 } 6275 error = nfsv4_seqsession(sequenceid, nd->nd_slotid, *highest_slotidp, 6276 sep->sess_slots, NULL, NFSV4_SLOTS - 1); 6277 if (error != 0) { 6278 NFSUNLOCKSESSION(shp); 6279 return (error); 6280 } 6281 if (cache_this != 0) 6282 nd->nd_flag |= ND_SAVEREPLY; 6283 /* Renew the lease. */ 6284 sep->sess_clp->lc_expiry = nfsrv_leaseexpiry(); 6285 nd->nd_clientid.qval = sep->sess_clp->lc_clientid.qval; 6286 nd->nd_flag |= ND_IMPLIEDCLID; 6287 6288 /* Save maximum request and reply sizes. */ 6289 nd->nd_maxreq = sep->sess_maxreq; 6290 nd->nd_maxresp = sep->sess_maxresp; 6291 6292 *sflagsp = 0; 6293 if (sep->sess_clp->lc_req.nr_client == NULL || 6294 (sep->sess_clp->lc_flags & LCL_CBDOWN) != 0) 6295 *sflagsp |= NFSV4SEQ_CBPATHDOWN; 6296 NFSUNLOCKSESSION(shp); 6297 if (error == NFSERR_EXPIRED) { 6298 *sflagsp |= NFSV4SEQ_EXPIREDALLSTATEREVOKED; 6299 error = 0; 6300 } else if (error == NFSERR_ADMINREVOKED) { 6301 *sflagsp |= NFSV4SEQ_ADMINSTATEREVOKED; 6302 error = 0; 6303 } 6304 *highest_slotidp = *target_highest_slotidp = NFSV4_SLOTS - 1; 6305 return (0); 6306 } 6307 6308 /* 6309 * Check/set reclaim complete for this session/clientid. 6310 */ 6311 int 6312 nfsrv_checkreclaimcomplete(struct nfsrv_descript *nd, int onefs) 6313 { 6314 struct nfsdsession *sep; 6315 struct nfssessionhash *shp; 6316 int error = 0; 6317 6318 shp = NFSSESSIONHASH(nd->nd_sessionid); 6319 NFSLOCKSTATE(); 6320 NFSLOCKSESSION(shp); 6321 sep = nfsrv_findsession(nd->nd_sessionid); 6322 if (sep == NULL) { 6323 NFSUNLOCKSESSION(shp); 6324 NFSUNLOCKSTATE(); 6325 return (NFSERR_BADSESSION); 6326 } 6327 6328 if (onefs != 0) 6329 sep->sess_clp->lc_flags |= LCL_RECLAIMONEFS; 6330 /* Check to see if reclaim complete has already happened. */ 6331 else if ((sep->sess_clp->lc_flags & LCL_RECLAIMCOMPLETE) != 0) 6332 error = NFSERR_COMPLETEALREADY; 6333 else { 6334 sep->sess_clp->lc_flags |= LCL_RECLAIMCOMPLETE; 6335 nfsrv_markreclaim(sep->sess_clp); 6336 } 6337 NFSUNLOCKSESSION(shp); 6338 NFSUNLOCKSTATE(); 6339 return (error); 6340 } 6341 6342 /* 6343 * Cache the reply in a session slot. 6344 */ 6345 void 6346 nfsrv_cache_session(struct nfsrv_descript *nd, struct mbuf **m) 6347 { 6348 struct nfsdsession *sep; 6349 struct nfssessionhash *shp; 6350 char *buf, *cp; 6351 #ifdef INET 6352 struct sockaddr_in *sin; 6353 #endif 6354 #ifdef INET6 6355 struct sockaddr_in6 *sin6; 6356 #endif 6357 6358 shp = NFSSESSIONHASH(nd->nd_sessionid); 6359 NFSLOCKSESSION(shp); 6360 sep = nfsrv_findsession(nd->nd_sessionid); 6361 if (sep == NULL) { 6362 NFSUNLOCKSESSION(shp); 6363 if ((nfsrv_stablefirst.nsf_flags & NFSNSF_GRACEOVER) != 0) { 6364 buf = malloc(INET6_ADDRSTRLEN, M_TEMP, M_WAITOK); 6365 switch (nd->nd_nam->sa_family) { 6366 #ifdef INET 6367 case AF_INET: 6368 sin = (struct sockaddr_in *)nd->nd_nam; 6369 cp = inet_ntop(sin->sin_family, 6370 &sin->sin_addr.s_addr, buf, 6371 INET6_ADDRSTRLEN); 6372 break; 6373 #endif 6374 #ifdef INET6 6375 case AF_INET6: 6376 sin6 = (struct sockaddr_in6 *)nd->nd_nam; 6377 cp = inet_ntop(sin6->sin6_family, 6378 &sin6->sin6_addr, buf, INET6_ADDRSTRLEN); 6379 break; 6380 #endif 6381 default: 6382 cp = NULL; 6383 } 6384 if (cp != NULL) 6385 printf("nfsrv_cache_session: no session " 6386 "IPaddr=%s, check NFS clients for unique " 6387 "/etc/hostid's\n", cp); 6388 else 6389 printf("nfsrv_cache_session: no session, " 6390 "check NFS clients for unique " 6391 "/etc/hostid's\n"); 6392 free(buf, M_TEMP); 6393 } 6394 m_freem(*m); 6395 return; 6396 } 6397 nfsv4_seqsess_cacherep(nd->nd_slotid, sep->sess_slots, nd->nd_repstat, 6398 m); 6399 NFSUNLOCKSESSION(shp); 6400 } 6401 6402 /* 6403 * Search for a session that matches the sessionid. 6404 */ 6405 static struct nfsdsession * 6406 nfsrv_findsession(uint8_t *sessionid) 6407 { 6408 struct nfsdsession *sep; 6409 struct nfssessionhash *shp; 6410 6411 shp = NFSSESSIONHASH(sessionid); 6412 LIST_FOREACH(sep, &shp->list, sess_hash) { 6413 if (!NFSBCMP(sessionid, sep->sess_sessionid, NFSX_V4SESSIONID)) 6414 break; 6415 } 6416 return (sep); 6417 } 6418 6419 /* 6420 * Destroy a session. 6421 */ 6422 int 6423 nfsrv_destroysession(struct nfsrv_descript *nd, uint8_t *sessionid) 6424 { 6425 int error, igotlock, samesess; 6426 6427 samesess = 0; 6428 if (!NFSBCMP(sessionid, nd->nd_sessionid, NFSX_V4SESSIONID) && 6429 (nd->nd_flag & ND_HASSEQUENCE) != 0) { 6430 samesess = 1; 6431 if ((nd->nd_flag & ND_LASTOP) == 0) 6432 return (NFSERR_BADSESSION); 6433 } 6434 6435 /* Lock out other nfsd threads */ 6436 NFSLOCKV4ROOTMUTEX(); 6437 nfsv4_relref(&nfsv4rootfs_lock); 6438 do { 6439 igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL, 6440 NFSV4ROOTLOCKMUTEXPTR, NULL); 6441 } while (igotlock == 0); 6442 NFSUNLOCKV4ROOTMUTEX(); 6443 6444 error = nfsrv_freesession(NULL, sessionid); 6445 if (error == 0 && samesess != 0) 6446 nd->nd_flag &= ~ND_HASSEQUENCE; 6447 6448 NFSLOCKV4ROOTMUTEX(); 6449 nfsv4_unlock(&nfsv4rootfs_lock, 1); 6450 NFSUNLOCKV4ROOTMUTEX(); 6451 return (error); 6452 } 6453 6454 /* 6455 * Bind a connection to a session. 6456 * For now, only certain variants are supported, since the current session 6457 * structure can only handle a single backchannel entry, which will be 6458 * applied to all connections if it is set. 6459 */ 6460 int 6461 nfsrv_bindconnsess(struct nfsrv_descript *nd, uint8_t *sessionid, int *foreaftp) 6462 { 6463 struct nfssessionhash *shp; 6464 struct nfsdsession *sep; 6465 struct nfsclient *clp; 6466 SVCXPRT *savxprt; 6467 int error; 6468 6469 error = 0; 6470 savxprt = NULL; 6471 shp = NFSSESSIONHASH(sessionid); 6472 NFSLOCKSTATE(); 6473 NFSLOCKSESSION(shp); 6474 sep = nfsrv_findsession(sessionid); 6475 if (sep != NULL) { 6476 clp = sep->sess_clp; 6477 if (*foreaftp == NFSCDFC4_BACK || 6478 *foreaftp == NFSCDFC4_BACK_OR_BOTH || 6479 *foreaftp == NFSCDFC4_FORE_OR_BOTH) { 6480 /* Try to set up a backchannel. */ 6481 if (clp->lc_req.nr_client == NULL) { 6482 NFSD_DEBUG(2, "nfsrv_bindconnsess: acquire " 6483 "backchannel\n"); 6484 clp->lc_req.nr_client = (struct __rpc_client *) 6485 clnt_bck_create(nd->nd_xprt->xp_socket, 6486 sep->sess_cbprogram, NFSV4_CBVERS); 6487 } 6488 if (clp->lc_req.nr_client != NULL) { 6489 NFSD_DEBUG(2, "nfsrv_bindconnsess: set up " 6490 "backchannel\n"); 6491 savxprt = sep->sess_cbsess.nfsess_xprt; 6492 SVC_ACQUIRE(nd->nd_xprt); 6493 CLNT_ACQUIRE(clp->lc_req.nr_client); 6494 nd->nd_xprt->xp_p2 = clp->lc_req.nr_client; 6495 /* Disable idle timeout. */ 6496 nd->nd_xprt->xp_idletimeout = 0; 6497 sep->sess_cbsess.nfsess_xprt = nd->nd_xprt; 6498 sep->sess_crflags |= NFSV4CRSESS_CONNBACKCHAN; 6499 clp->lc_flags |= LCL_DONEBINDCONN | 6500 LCL_NEEDSCBNULL; 6501 clp->lc_flags &= ~LCL_CBDOWN; 6502 if (*foreaftp == NFSCDFS4_BACK) 6503 *foreaftp = NFSCDFS4_BACK; 6504 else 6505 *foreaftp = NFSCDFS4_BOTH; 6506 } else if (*foreaftp != NFSCDFC4_BACK) { 6507 NFSD_DEBUG(2, "nfsrv_bindconnsess: can't set " 6508 "up backchannel\n"); 6509 sep->sess_crflags &= ~NFSV4CRSESS_CONNBACKCHAN; 6510 clp->lc_flags |= LCL_DONEBINDCONN; 6511 *foreaftp = NFSCDFS4_FORE; 6512 } else { 6513 error = NFSERR_NOTSUPP; 6514 printf("nfsrv_bindconnsess: Can't add " 6515 "backchannel\n"); 6516 } 6517 } else { 6518 NFSD_DEBUG(2, "nfsrv_bindconnsess: Set forechannel\n"); 6519 clp->lc_flags |= LCL_DONEBINDCONN; 6520 *foreaftp = NFSCDFS4_FORE; 6521 } 6522 } else 6523 error = NFSERR_BADSESSION; 6524 NFSUNLOCKSESSION(shp); 6525 NFSUNLOCKSTATE(); 6526 if (savxprt != NULL) 6527 SVC_RELEASE(savxprt); 6528 return (error); 6529 } 6530 6531 /* 6532 * Free up a session structure. 6533 */ 6534 static int 6535 nfsrv_freesession(struct nfsdsession *sep, uint8_t *sessionid) 6536 { 6537 struct nfssessionhash *shp; 6538 int i; 6539 6540 NFSLOCKSTATE(); 6541 if (sep == NULL) { 6542 shp = NFSSESSIONHASH(sessionid); 6543 NFSLOCKSESSION(shp); 6544 sep = nfsrv_findsession(sessionid); 6545 } else { 6546 shp = NFSSESSIONHASH(sep->sess_sessionid); 6547 NFSLOCKSESSION(shp); 6548 } 6549 if (sep != NULL) { 6550 sep->sess_refcnt--; 6551 if (sep->sess_refcnt > 0) { 6552 NFSUNLOCKSESSION(shp); 6553 NFSUNLOCKSTATE(); 6554 return (NFSERR_BACKCHANBUSY); 6555 } 6556 LIST_REMOVE(sep, sess_hash); 6557 LIST_REMOVE(sep, sess_list); 6558 } 6559 NFSUNLOCKSESSION(shp); 6560 NFSUNLOCKSTATE(); 6561 if (sep == NULL) 6562 return (NFSERR_BADSESSION); 6563 for (i = 0; i < NFSV4_SLOTS; i++) 6564 if (sep->sess_slots[i].nfssl_reply != NULL) 6565 m_freem(sep->sess_slots[i].nfssl_reply); 6566 if (sep->sess_cbsess.nfsess_xprt != NULL) 6567 SVC_RELEASE(sep->sess_cbsess.nfsess_xprt); 6568 free(sep, M_NFSDSESSION); 6569 return (0); 6570 } 6571 6572 /* 6573 * Free a stateid. 6574 * RFC5661 says that it should fail when there are associated opens, locks 6575 * or delegations. Since stateids represent opens, I don't see how you can 6576 * free an open stateid (it will be free'd when closed), so this function 6577 * only works for lock stateids (freeing the lock_owner) or delegations. 6578 */ 6579 int 6580 nfsrv_freestateid(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, 6581 NFSPROC_T *p) 6582 { 6583 struct nfsclient *clp; 6584 struct nfsstate *stp; 6585 int error; 6586 6587 NFSLOCKSTATE(); 6588 /* 6589 * Look up the stateid 6590 */ 6591 error = nfsrv_getclient((nfsquad_t)((u_quad_t)0), CLOPS_RENEW, &clp, 6592 NULL, (nfsquad_t)((u_quad_t)0), 0, nd, p); 6593 if (error == 0) { 6594 /* First, check for a delegation. */ 6595 LIST_FOREACH(stp, &clp->lc_deleg, ls_list) { 6596 if (!NFSBCMP(stp->ls_stateid.other, stateidp->other, 6597 NFSX_STATEIDOTHER)) 6598 break; 6599 } 6600 if (stp != NULL) { 6601 nfsrv_freedeleg(stp); 6602 NFSUNLOCKSTATE(); 6603 return (error); 6604 } 6605 } 6606 /* Not a delegation, try for a lock_owner. */ 6607 if (error == 0) 6608 error = nfsrv_getstate(clp, stateidp, 0, &stp); 6609 if (error == 0 && ((stp->ls_flags & (NFSLCK_OPEN | NFSLCK_DELEGREAD | 6610 NFSLCK_DELEGWRITE)) != 0 || (stp->ls_flags & NFSLCK_LOCK) == 0)) 6611 /* Not a lock_owner stateid. */ 6612 error = NFSERR_LOCKSHELD; 6613 if (error == 0 && !LIST_EMPTY(&stp->ls_lock)) 6614 error = NFSERR_LOCKSHELD; 6615 if (error == 0) 6616 nfsrv_freelockowner(stp, NULL, 0, p); 6617 NFSUNLOCKSTATE(); 6618 return (error); 6619 } 6620 6621 /* 6622 * Test a stateid. 6623 */ 6624 int 6625 nfsrv_teststateid(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp, 6626 NFSPROC_T *p) 6627 { 6628 struct nfsclient *clp; 6629 struct nfsstate *stp; 6630 int error; 6631 6632 NFSLOCKSTATE(); 6633 /* 6634 * Look up the stateid 6635 */ 6636 error = nfsrv_getclient((nfsquad_t)((u_quad_t)0), CLOPS_RENEW, &clp, 6637 NULL, (nfsquad_t)((u_quad_t)0), 0, nd, p); 6638 if (error == 0) 6639 error = nfsrv_getstate(clp, stateidp, 0, &stp); 6640 if (error == 0 && stateidp->seqid != 0 && 6641 SEQ_LT(stateidp->seqid, stp->ls_stateid.seqid)) 6642 error = NFSERR_OLDSTATEID; 6643 NFSUNLOCKSTATE(); 6644 return (error); 6645 } 6646 6647 /* 6648 * Generate the xdr for an NFSv4.1 CBSequence Operation. 6649 */ 6650 static int 6651 nfsv4_setcbsequence(struct nfsrv_descript *nd, struct nfsclient *clp, 6652 int dont_replycache, struct nfsdsession **sepp, int *slotposp) 6653 { 6654 struct nfsdsession *sep; 6655 uint32_t *tl, slotseq = 0; 6656 int maxslot; 6657 uint8_t sessionid[NFSX_V4SESSIONID]; 6658 int error; 6659 6660 error = nfsv4_getcbsession(clp, sepp); 6661 if (error != 0) 6662 return (error); 6663 sep = *sepp; 6664 nfsv4_sequencelookup(NULL, &sep->sess_cbsess, slotposp, &maxslot, 6665 &slotseq, sessionid, true); 6666 KASSERT(maxslot >= 0, ("nfsv4_setcbsequence neg maxslot")); 6667 6668 /* Build the Sequence arguments. */ 6669 NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID + 5 * NFSX_UNSIGNED); 6670 bcopy(sessionid, tl, NFSX_V4SESSIONID); 6671 tl += NFSX_V4SESSIONID / NFSX_UNSIGNED; 6672 nd->nd_slotseq = tl; 6673 nd->nd_slotid = *slotposp; 6674 nd->nd_flag |= ND_HASSLOTID; 6675 *tl++ = txdr_unsigned(slotseq); 6676 *tl++ = txdr_unsigned(*slotposp); 6677 *tl++ = txdr_unsigned(maxslot); 6678 if (dont_replycache == 0) 6679 *tl++ = newnfs_true; 6680 else 6681 *tl++ = newnfs_false; 6682 *tl = 0; /* No referring call list, for now. */ 6683 nd->nd_flag |= ND_HASSEQUENCE; 6684 return (0); 6685 } 6686 6687 /* 6688 * Get a session for the callback. 6689 */ 6690 static int 6691 nfsv4_getcbsession(struct nfsclient *clp, struct nfsdsession **sepp) 6692 { 6693 struct nfsdsession *sep; 6694 6695 NFSLOCKSTATE(); 6696 LIST_FOREACH(sep, &clp->lc_session, sess_list) { 6697 if ((sep->sess_crflags & NFSV4CRSESS_CONNBACKCHAN) != 0) 6698 break; 6699 } 6700 if (sep == NULL) { 6701 NFSUNLOCKSTATE(); 6702 return (NFSERR_BADSESSION); 6703 } 6704 sep->sess_refcnt++; 6705 *sepp = sep; 6706 NFSUNLOCKSTATE(); 6707 return (0); 6708 } 6709 6710 /* 6711 * Free up all backchannel xprts. This needs to be done when the nfsd threads 6712 * exit, since those transports will all be going away. 6713 * This is only called after all the nfsd threads are done performing RPCs, 6714 * so locking shouldn't be an issue. 6715 */ 6716 void 6717 nfsrv_freeallbackchannel_xprts(void) 6718 { 6719 struct nfsdsession *sep; 6720 struct nfsclient *clp; 6721 SVCXPRT *xprt; 6722 int i; 6723 6724 for (i = 0; i < nfsrv_clienthashsize; i++) { 6725 LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) { 6726 LIST_FOREACH(sep, &clp->lc_session, sess_list) { 6727 xprt = sep->sess_cbsess.nfsess_xprt; 6728 sep->sess_cbsess.nfsess_xprt = NULL; 6729 if (xprt != NULL) 6730 SVC_RELEASE(xprt); 6731 } 6732 } 6733 } 6734 } 6735 6736 /* 6737 * Do a layout commit. Actually just call nfsrv_updatemdsattr(). 6738 * I have no idea if the rest of these arguments will ever be useful? 6739 */ 6740 int 6741 nfsrv_layoutcommit(struct nfsrv_descript *nd, vnode_t vp, int layouttype, 6742 int hasnewoff, uint64_t newoff, uint64_t offset, uint64_t len, 6743 int hasnewmtime, struct timespec *newmtimep, int reclaim, 6744 nfsv4stateid_t *stateidp, int maxcnt, char *layp, int *hasnewsizep, 6745 uint64_t *newsizep, struct ucred *cred, NFSPROC_T *p) 6746 { 6747 struct nfsvattr na; 6748 int error; 6749 6750 error = nfsrv_updatemdsattr(vp, &na, p); 6751 if (error == 0) { 6752 *hasnewsizep = 1; 6753 *newsizep = na.na_size; 6754 } 6755 return (error); 6756 } 6757 6758 /* 6759 * Try and get a layout. 6760 */ 6761 int 6762 nfsrv_layoutget(struct nfsrv_descript *nd, vnode_t vp, struct nfsexstuff *exp, 6763 int layouttype, int *iomode, uint64_t *offset, uint64_t *len, 6764 uint64_t minlen, nfsv4stateid_t *stateidp, int maxcnt, int *retonclose, 6765 int *layoutlenp, char *layp, struct ucred *cred, NFSPROC_T *p) 6766 { 6767 struct nfslayouthash *lhyp; 6768 struct nfslayout *lyp; 6769 char *devid; 6770 fhandle_t fh, *dsfhp; 6771 int error, mirrorcnt; 6772 6773 if (nfsrv_devidcnt == 0) 6774 return (NFSERR_UNKNLAYOUTTYPE); 6775 6776 if (*offset != 0) 6777 printf("nfsrv_layoutget: off=%ju len=%ju\n", (uintmax_t)*offset, 6778 (uintmax_t)*len); 6779 error = nfsvno_getfh(vp, &fh, p); 6780 NFSD_DEBUG(4, "layoutget getfh=%d\n", error); 6781 if (error != 0) 6782 return (error); 6783 6784 /* 6785 * For now, all layouts are for entire files. 6786 * Only issue Read/Write layouts if requested for a non-readonly fs. 6787 */ 6788 if (NFSVNO_EXRDONLY(exp)) { 6789 if (*iomode == NFSLAYOUTIOMODE_RW) 6790 return (NFSERR_LAYOUTTRYLATER); 6791 *iomode = NFSLAYOUTIOMODE_READ; 6792 } 6793 if (*iomode != NFSLAYOUTIOMODE_RW) 6794 *iomode = NFSLAYOUTIOMODE_READ; 6795 6796 /* 6797 * Check to see if a write layout can be issued for this file. 6798 * This is used during mirror recovery to avoid RW layouts being 6799 * issued for a file while it is being copied to the recovered 6800 * mirror. 6801 */ 6802 if (*iomode == NFSLAYOUTIOMODE_RW && nfsrv_dontlayout(&fh) != 0) 6803 return (NFSERR_LAYOUTTRYLATER); 6804 6805 *retonclose = 0; 6806 *offset = 0; 6807 *len = UINT64_MAX; 6808 6809 /* First, see if a layout already exists and return if found. */ 6810 lhyp = NFSLAYOUTHASH(&fh); 6811 NFSLOCKLAYOUT(lhyp); 6812 error = nfsrv_findlayout(&nd->nd_clientid, &fh, layouttype, p, &lyp); 6813 NFSD_DEBUG(4, "layoutget findlay=%d\n", error); 6814 /* 6815 * Not sure if the seqid must be the same, so I won't check it. 6816 */ 6817 if (error == 0 && (stateidp->other[0] != lyp->lay_stateid.other[0] || 6818 stateidp->other[1] != lyp->lay_stateid.other[1] || 6819 stateidp->other[2] != lyp->lay_stateid.other[2])) { 6820 if ((lyp->lay_flags & NFSLAY_CALLB) == 0) { 6821 NFSUNLOCKLAYOUT(lhyp); 6822 NFSD_DEBUG(1, "ret bad stateid\n"); 6823 return (NFSERR_BADSTATEID); 6824 } 6825 /* 6826 * I believe we get here because there is a race between 6827 * the client processing the CBLAYOUTRECALL and the layout 6828 * being deleted here on the server. 6829 * The client has now done a LayoutGet with a non-layout 6830 * stateid, as it would when there is no layout. 6831 * As such, free this layout and set error == NFSERR_BADSTATEID 6832 * so the code below will create a new layout structure as 6833 * would happen if no layout was found. 6834 * "lyp" will be set before being used below, but set it NULL 6835 * as a safety belt. 6836 */ 6837 nfsrv_freelayout(&lhyp->list, lyp); 6838 lyp = NULL; 6839 error = NFSERR_BADSTATEID; 6840 } 6841 if (error == 0) { 6842 if (lyp->lay_layoutlen > maxcnt) { 6843 NFSUNLOCKLAYOUT(lhyp); 6844 NFSD_DEBUG(1, "ret layout too small\n"); 6845 return (NFSERR_TOOSMALL); 6846 } 6847 if (*iomode == NFSLAYOUTIOMODE_RW) { 6848 if ((lyp->lay_flags & NFSLAY_NOSPC) != 0) { 6849 NFSUNLOCKLAYOUT(lhyp); 6850 NFSD_DEBUG(1, "ret layout nospace\n"); 6851 return (NFSERR_NOSPC); 6852 } 6853 lyp->lay_flags |= NFSLAY_RW; 6854 } else 6855 lyp->lay_flags |= NFSLAY_READ; 6856 NFSBCOPY(lyp->lay_xdr, layp, lyp->lay_layoutlen); 6857 *layoutlenp = lyp->lay_layoutlen; 6858 if (++lyp->lay_stateid.seqid == 0) 6859 lyp->lay_stateid.seqid = 1; 6860 stateidp->seqid = lyp->lay_stateid.seqid; 6861 NFSUNLOCKLAYOUT(lhyp); 6862 NFSD_DEBUG(4, "ret fnd layout\n"); 6863 return (0); 6864 } 6865 NFSUNLOCKLAYOUT(lhyp); 6866 6867 /* Find the device id and file handle. */ 6868 dsfhp = malloc(sizeof(fhandle_t) * NFSDEV_MAXMIRRORS, M_TEMP, M_WAITOK); 6869 devid = malloc(NFSX_V4DEVICEID * NFSDEV_MAXMIRRORS, M_TEMP, M_WAITOK); 6870 error = nfsrv_dsgetdevandfh(vp, p, &mirrorcnt, dsfhp, devid); 6871 NFSD_DEBUG(4, "layoutget devandfh=%d\n", error); 6872 if (error == 0) { 6873 if (layouttype == NFSLAYOUT_NFSV4_1_FILES) { 6874 if (NFSX_V4FILELAYOUT > maxcnt) 6875 error = NFSERR_TOOSMALL; 6876 else 6877 lyp = nfsrv_filelayout(nd, *iomode, &fh, dsfhp, 6878 devid, vp->v_mount->mnt_stat.f_fsid); 6879 } else { 6880 if (NFSX_V4FLEXLAYOUT(mirrorcnt) > maxcnt) 6881 error = NFSERR_TOOSMALL; 6882 else 6883 lyp = nfsrv_flexlayout(nd, *iomode, mirrorcnt, 6884 &fh, dsfhp, devid, 6885 vp->v_mount->mnt_stat.f_fsid); 6886 } 6887 } 6888 free(dsfhp, M_TEMP); 6889 free(devid, M_TEMP); 6890 if (error != 0) 6891 return (error); 6892 6893 /* 6894 * Now, add this layout to the list. 6895 */ 6896 error = nfsrv_addlayout(nd, &lyp, stateidp, layp, layoutlenp, p); 6897 NFSD_DEBUG(4, "layoutget addl=%d\n", error); 6898 /* 6899 * The lyp will be set to NULL by nfsrv_addlayout() if it 6900 * linked the new structure into the lists. 6901 */ 6902 free(lyp, M_NFSDSTATE); 6903 return (error); 6904 } 6905 6906 /* 6907 * Generate a File Layout. 6908 */ 6909 static struct nfslayout * 6910 nfsrv_filelayout(struct nfsrv_descript *nd, int iomode, fhandle_t *fhp, 6911 fhandle_t *dsfhp, char *devid, fsid_t fs) 6912 { 6913 uint32_t *tl; 6914 struct nfslayout *lyp; 6915 uint64_t pattern_offset; 6916 6917 lyp = malloc(sizeof(struct nfslayout) + NFSX_V4FILELAYOUT, M_NFSDSTATE, 6918 M_WAITOK | M_ZERO); 6919 lyp->lay_type = NFSLAYOUT_NFSV4_1_FILES; 6920 if (iomode == NFSLAYOUTIOMODE_RW) 6921 lyp->lay_flags = NFSLAY_RW; 6922 else 6923 lyp->lay_flags = NFSLAY_READ; 6924 NFSBCOPY(fhp, &lyp->lay_fh, sizeof(*fhp)); 6925 lyp->lay_clientid.qval = nd->nd_clientid.qval; 6926 lyp->lay_fsid = fs; 6927 NFSBCOPY(devid, lyp->lay_deviceid, NFSX_V4DEVICEID); 6928 6929 /* Fill in the xdr for the files layout. */ 6930 tl = (uint32_t *)lyp->lay_xdr; 6931 NFSBCOPY(devid, tl, NFSX_V4DEVICEID); /* Device ID. */ 6932 tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); 6933 6934 /* Set the stripe size to the maximum I/O size. */ 6935 *tl++ = txdr_unsigned(nfs_srvmaxio & NFSFLAYUTIL_STRIPE_MASK); 6936 *tl++ = 0; /* 1st stripe index. */ 6937 pattern_offset = 0; 6938 txdr_hyper(pattern_offset, tl); tl += 2; /* Pattern offset. */ 6939 *tl++ = txdr_unsigned(1); /* 1 file handle. */ 6940 *tl++ = txdr_unsigned(NFSX_V4PNFSFH); 6941 NFSBCOPY(dsfhp, tl, sizeof(*dsfhp)); 6942 lyp->lay_layoutlen = NFSX_V4FILELAYOUT; 6943 return (lyp); 6944 } 6945 6946 #define FLEX_OWNERID "999" 6947 #define FLEX_UID0 "0" 6948 /* 6949 * Generate a Flex File Layout. 6950 * The FLEX_OWNERID can be any string of 3 decimal digits. Although this 6951 * string goes on the wire, it isn't supposed to be used by the client, 6952 * since this server uses tight coupling. 6953 * Although not recommended by the spec., if vfs.nfsd.flexlinuxhack=1 use 6954 * a string of "0". This works around the Linux Flex File Layout driver bug 6955 * which uses the synthetic uid/gid strings for the "tightly coupled" case. 6956 */ 6957 static struct nfslayout * 6958 nfsrv_flexlayout(struct nfsrv_descript *nd, int iomode, int mirrorcnt, 6959 fhandle_t *fhp, fhandle_t *dsfhp, char *devid, fsid_t fs) 6960 { 6961 uint32_t *tl; 6962 struct nfslayout *lyp; 6963 uint64_t lenval; 6964 int i; 6965 6966 lyp = malloc(sizeof(struct nfslayout) + NFSX_V4FLEXLAYOUT(mirrorcnt), 6967 M_NFSDSTATE, M_WAITOK | M_ZERO); 6968 lyp->lay_type = NFSLAYOUT_FLEXFILE; 6969 if (iomode == NFSLAYOUTIOMODE_RW) 6970 lyp->lay_flags = NFSLAY_RW; 6971 else 6972 lyp->lay_flags = NFSLAY_READ; 6973 NFSBCOPY(fhp, &lyp->lay_fh, sizeof(*fhp)); 6974 lyp->lay_clientid.qval = nd->nd_clientid.qval; 6975 lyp->lay_fsid = fs; 6976 lyp->lay_mirrorcnt = mirrorcnt; 6977 NFSBCOPY(devid, lyp->lay_deviceid, NFSX_V4DEVICEID); 6978 6979 /* Fill in the xdr for the files layout. */ 6980 tl = (uint32_t *)lyp->lay_xdr; 6981 lenval = 0; 6982 txdr_hyper(lenval, tl); tl += 2; /* Stripe unit. */ 6983 *tl++ = txdr_unsigned(mirrorcnt); /* # of mirrors. */ 6984 for (i = 0; i < mirrorcnt; i++) { 6985 *tl++ = txdr_unsigned(1); /* One stripe. */ 6986 NFSBCOPY(devid, tl, NFSX_V4DEVICEID); /* Device ID. */ 6987 tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); 6988 devid += NFSX_V4DEVICEID; 6989 *tl++ = txdr_unsigned(1); /* Efficiency. */ 6990 *tl++ = 0; /* Proxy Stateid. */ 6991 *tl++ = 0x55555555; 6992 *tl++ = 0x55555555; 6993 *tl++ = 0x55555555; 6994 *tl++ = txdr_unsigned(1); /* 1 file handle. */ 6995 *tl++ = txdr_unsigned(NFSX_V4PNFSFH); 6996 NFSBCOPY(dsfhp, tl, sizeof(*dsfhp)); 6997 tl += (NFSM_RNDUP(NFSX_V4PNFSFH) / NFSX_UNSIGNED); 6998 dsfhp++; 6999 if (nfsrv_flexlinuxhack != 0) { 7000 *tl++ = txdr_unsigned(strlen(FLEX_UID0)); 7001 *tl = 0; /* 0 pad string. */ 7002 NFSBCOPY(FLEX_UID0, tl++, strlen(FLEX_UID0)); 7003 *tl++ = txdr_unsigned(strlen(FLEX_UID0)); 7004 *tl = 0; /* 0 pad string. */ 7005 NFSBCOPY(FLEX_UID0, tl++, strlen(FLEX_UID0)); 7006 } else { 7007 *tl++ = txdr_unsigned(strlen(FLEX_OWNERID)); 7008 NFSBCOPY(FLEX_OWNERID, tl++, NFSX_UNSIGNED); 7009 *tl++ = txdr_unsigned(strlen(FLEX_OWNERID)); 7010 NFSBCOPY(FLEX_OWNERID, tl++, NFSX_UNSIGNED); 7011 } 7012 } 7013 *tl++ = txdr_unsigned(0); /* ff_flags. */ 7014 *tl = txdr_unsigned(60); /* Status interval hint. */ 7015 lyp->lay_layoutlen = NFSX_V4FLEXLAYOUT(mirrorcnt); 7016 return (lyp); 7017 } 7018 7019 /* 7020 * Parse and process Flex File errors returned via LayoutReturn. 7021 */ 7022 static void 7023 nfsrv_flexlayouterr(struct nfsrv_descript *nd, uint32_t *layp, int maxcnt, 7024 NFSPROC_T *p) 7025 { 7026 uint32_t *tl; 7027 int cnt, errcnt, i, j, opnum, stat; 7028 char devid[NFSX_V4DEVICEID]; 7029 7030 tl = layp; 7031 maxcnt -= NFSX_UNSIGNED; 7032 if (maxcnt > 0) 7033 cnt = fxdr_unsigned(int, *tl++); 7034 else 7035 cnt = 0; 7036 NFSD_DEBUG(4, "flexlayouterr cnt=%d\n", cnt); 7037 for (i = 0; i < cnt; i++) { 7038 maxcnt -= NFSX_STATEID + 2 * NFSX_HYPER + 7039 NFSX_UNSIGNED; 7040 if (maxcnt <= 0) 7041 break; 7042 /* Skip offset, length and stateid for now. */ 7043 tl += (4 + NFSX_STATEID / NFSX_UNSIGNED); 7044 errcnt = fxdr_unsigned(int, *tl++); 7045 NFSD_DEBUG(4, "flexlayouterr errcnt=%d\n", errcnt); 7046 for (j = 0; j < errcnt; j++) { 7047 maxcnt -= NFSX_V4DEVICEID + 2 * NFSX_UNSIGNED; 7048 if (maxcnt < 0) 7049 break; 7050 NFSBCOPY(tl, devid, NFSX_V4DEVICEID); 7051 tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); 7052 stat = fxdr_unsigned(int, *tl++); 7053 opnum = fxdr_unsigned(int, *tl++); 7054 NFSD_DEBUG(4, "flexlayouterr op=%d stat=%d\n", opnum, 7055 stat); 7056 /* 7057 * Except for NFSERR_ACCES, NFSERR_STALE and 7058 * NFSERR_NOSPC errors, disable the mirror. 7059 */ 7060 if (stat != NFSERR_ACCES && stat != NFSERR_STALE && 7061 stat != NFSERR_NOSPC) 7062 nfsrv_delds(devid, p); 7063 7064 /* For NFSERR_NOSPC, mark all devids and layouts. */ 7065 if (stat == NFSERR_NOSPC) 7066 nfsrv_marknospc(devid, true); 7067 } 7068 } 7069 } 7070 7071 /* 7072 * This function removes all flex file layouts which has a mirror with 7073 * a device id that matches the argument. 7074 * Called when the DS represented by the device id has failed. 7075 */ 7076 void 7077 nfsrv_flexmirrordel(char *devid, NFSPROC_T *p) 7078 { 7079 uint32_t *tl; 7080 struct nfslayout *lyp, *nlyp; 7081 struct nfslayouthash *lhyp; 7082 struct nfslayouthead loclyp; 7083 int i, j; 7084 7085 NFSD_DEBUG(4, "flexmirrordel\n"); 7086 /* Move all layouts found onto a local list. */ 7087 TAILQ_INIT(&loclyp); 7088 for (i = 0; i < nfsrv_layouthashsize; i++) { 7089 lhyp = &nfslayouthash[i]; 7090 NFSLOCKLAYOUT(lhyp); 7091 TAILQ_FOREACH_SAFE(lyp, &lhyp->list, lay_list, nlyp) { 7092 if (lyp->lay_type == NFSLAYOUT_FLEXFILE && 7093 lyp->lay_mirrorcnt > 1) { 7094 NFSD_DEBUG(4, "possible match\n"); 7095 tl = lyp->lay_xdr; 7096 tl += 3; 7097 for (j = 0; j < lyp->lay_mirrorcnt; j++) { 7098 tl++; 7099 if (NFSBCMP(devid, tl, NFSX_V4DEVICEID) 7100 == 0) { 7101 /* Found one. */ 7102 NFSD_DEBUG(4, "fnd one\n"); 7103 TAILQ_REMOVE(&lhyp->list, lyp, 7104 lay_list); 7105 TAILQ_INSERT_HEAD(&loclyp, lyp, 7106 lay_list); 7107 break; 7108 } 7109 tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED + 7110 NFSM_RNDUP(NFSX_V4PNFSFH) / 7111 NFSX_UNSIGNED + 11 * NFSX_UNSIGNED); 7112 } 7113 } 7114 } 7115 NFSUNLOCKLAYOUT(lhyp); 7116 } 7117 7118 /* Now, try to do a Layout recall for each one found. */ 7119 TAILQ_FOREACH_SAFE(lyp, &loclyp, lay_list, nlyp) { 7120 NFSD_DEBUG(4, "do layout recall\n"); 7121 /* 7122 * The layout stateid.seqid needs to be incremented 7123 * before doing a LAYOUT_RECALL callback. 7124 */ 7125 if (++lyp->lay_stateid.seqid == 0) 7126 lyp->lay_stateid.seqid = 1; 7127 nfsrv_recalllayout(lyp->lay_clientid, &lyp->lay_stateid, 7128 &lyp->lay_fh, lyp, 1, lyp->lay_type, p); 7129 nfsrv_freelayout(&loclyp, lyp); 7130 } 7131 } 7132 7133 /* 7134 * Do a recall callback to the client for this layout. 7135 */ 7136 static int 7137 nfsrv_recalllayout(nfsquad_t clid, nfsv4stateid_t *stateidp, fhandle_t *fhp, 7138 struct nfslayout *lyp, int changed, int laytype, NFSPROC_T *p) 7139 { 7140 struct nfsclient *clp; 7141 int error; 7142 7143 NFSD_DEBUG(4, "nfsrv_recalllayout\n"); 7144 error = nfsrv_getclient(clid, 0, &clp, NULL, (nfsquad_t)((u_quad_t)0), 7145 0, NULL, p); 7146 NFSD_DEBUG(4, "aft nfsrv_getclient=%d\n", error); 7147 if (error != 0) { 7148 printf("nfsrv_recalllayout: getclient err=%d\n", error); 7149 return (error); 7150 } 7151 if ((clp->lc_flags & LCL_NFSV41) != 0) { 7152 error = nfsrv_docallback(clp, NFSV4OP_CBLAYOUTRECALL, 7153 stateidp, changed, fhp, NULL, NULL, laytype, p); 7154 /* If lyp != NULL, handle an error return here. */ 7155 if (error != 0 && lyp != NULL) { 7156 NFSDRECALLLOCK(); 7157 /* 7158 * Mark it returned, since no layout recall 7159 * has been done. 7160 * All errors seem to be non-recoverable, although 7161 * NFSERR_NOMATCHLAYOUT is a normal event. 7162 */ 7163 if ((lyp->lay_flags & NFSLAY_RECALL) != 0) { 7164 lyp->lay_flags |= NFSLAY_RETURNED; 7165 wakeup(lyp); 7166 } 7167 NFSDRECALLUNLOCK(); 7168 if (error != NFSERR_NOMATCHLAYOUT) 7169 printf("nfsrv_recalllayout: err=%d\n", error); 7170 } 7171 } else 7172 printf("nfsrv_recalllayout: clp not NFSv4.1\n"); 7173 return (error); 7174 } 7175 7176 /* 7177 * Find a layout to recall when we exceed our high water mark. 7178 */ 7179 void 7180 nfsrv_recalloldlayout(NFSPROC_T *p) 7181 { 7182 struct nfslayouthash *lhyp; 7183 struct nfslayout *lyp; 7184 nfsquad_t clientid; 7185 nfsv4stateid_t stateid; 7186 fhandle_t fh; 7187 int error, laytype = 0, ret; 7188 7189 lhyp = &nfslayouthash[arc4random() % nfsrv_layouthashsize]; 7190 NFSLOCKLAYOUT(lhyp); 7191 TAILQ_FOREACH_REVERSE(lyp, &lhyp->list, nfslayouthead, lay_list) { 7192 if ((lyp->lay_flags & NFSLAY_CALLB) == 0) { 7193 lyp->lay_flags |= NFSLAY_CALLB; 7194 /* 7195 * The layout stateid.seqid needs to be incremented 7196 * before doing a LAYOUT_RECALL callback. 7197 */ 7198 if (++lyp->lay_stateid.seqid == 0) 7199 lyp->lay_stateid.seqid = 1; 7200 clientid = lyp->lay_clientid; 7201 stateid = lyp->lay_stateid; 7202 NFSBCOPY(&lyp->lay_fh, &fh, sizeof(fh)); 7203 laytype = lyp->lay_type; 7204 break; 7205 } 7206 } 7207 NFSUNLOCKLAYOUT(lhyp); 7208 if (lyp != NULL) { 7209 error = nfsrv_recalllayout(clientid, &stateid, &fh, NULL, 0, 7210 laytype, p); 7211 if (error != 0 && error != NFSERR_NOMATCHLAYOUT) 7212 NFSD_DEBUG(4, "recallold=%d\n", error); 7213 if (error != 0) { 7214 NFSLOCKLAYOUT(lhyp); 7215 /* 7216 * Since the hash list was unlocked, we need to 7217 * find it again. 7218 */ 7219 ret = nfsrv_findlayout(&clientid, &fh, laytype, p, 7220 &lyp); 7221 if (ret == 0 && 7222 (lyp->lay_flags & NFSLAY_CALLB) != 0 && 7223 lyp->lay_stateid.other[0] == stateid.other[0] && 7224 lyp->lay_stateid.other[1] == stateid.other[1] && 7225 lyp->lay_stateid.other[2] == stateid.other[2]) { 7226 /* 7227 * The client no longer knows this layout, so 7228 * it can be free'd now. 7229 */ 7230 if (error == NFSERR_NOMATCHLAYOUT) 7231 nfsrv_freelayout(&lhyp->list, lyp); 7232 else { 7233 /* 7234 * Leave it to be tried later by 7235 * clearing NFSLAY_CALLB and moving 7236 * it to the head of the list, so it 7237 * won't be tried again for a while. 7238 */ 7239 lyp->lay_flags &= ~NFSLAY_CALLB; 7240 TAILQ_REMOVE(&lhyp->list, lyp, 7241 lay_list); 7242 TAILQ_INSERT_HEAD(&lhyp->list, lyp, 7243 lay_list); 7244 } 7245 } 7246 NFSUNLOCKLAYOUT(lhyp); 7247 } 7248 } 7249 } 7250 7251 /* 7252 * Try and return layout(s). 7253 */ 7254 int 7255 nfsrv_layoutreturn(struct nfsrv_descript *nd, vnode_t vp, 7256 int layouttype, int iomode, uint64_t offset, uint64_t len, int reclaim, 7257 int kind, nfsv4stateid_t *stateidp, int maxcnt, uint32_t *layp, int *fndp, 7258 struct ucred *cred, NFSPROC_T *p) 7259 { 7260 struct nfsvattr na; 7261 struct nfslayouthash *lhyp; 7262 struct nfslayout *lyp; 7263 fhandle_t fh; 7264 int error = 0; 7265 7266 *fndp = 0; 7267 if (kind == NFSV4LAYOUTRET_FILE) { 7268 error = nfsvno_getfh(vp, &fh, p); 7269 if (error == 0) { 7270 error = nfsrv_updatemdsattr(vp, &na, p); 7271 if (error != 0) 7272 printf("nfsrv_layoutreturn: updatemdsattr" 7273 " failed=%d\n", error); 7274 } 7275 if (error == 0) { 7276 if (reclaim == newnfs_true) { 7277 error = nfsrv_checkgrace(NULL, NULL, 7278 NFSLCK_RECLAIM); 7279 if (error != NFSERR_NOGRACE) 7280 error = 0; 7281 return (error); 7282 } 7283 lhyp = NFSLAYOUTHASH(&fh); 7284 NFSDRECALLLOCK(); 7285 NFSLOCKLAYOUT(lhyp); 7286 error = nfsrv_findlayout(&nd->nd_clientid, &fh, 7287 layouttype, p, &lyp); 7288 NFSD_DEBUG(4, "layoutret findlay=%d\n", error); 7289 if (error == 0 && 7290 stateidp->other[0] == lyp->lay_stateid.other[0] && 7291 stateidp->other[1] == lyp->lay_stateid.other[1] && 7292 stateidp->other[2] == lyp->lay_stateid.other[2]) { 7293 NFSD_DEBUG(4, "nfsrv_layoutreturn: stateid %d" 7294 " %x %x %x laystateid %d %x %x %x" 7295 " off=%ju len=%ju flgs=0x%x\n", 7296 stateidp->seqid, stateidp->other[0], 7297 stateidp->other[1], stateidp->other[2], 7298 lyp->lay_stateid.seqid, 7299 lyp->lay_stateid.other[0], 7300 lyp->lay_stateid.other[1], 7301 lyp->lay_stateid.other[2], 7302 (uintmax_t)offset, (uintmax_t)len, 7303 lyp->lay_flags); 7304 if (++lyp->lay_stateid.seqid == 0) 7305 lyp->lay_stateid.seqid = 1; 7306 stateidp->seqid = lyp->lay_stateid.seqid; 7307 if (offset == 0 && len == UINT64_MAX) { 7308 if ((iomode & NFSLAYOUTIOMODE_READ) != 7309 0) 7310 lyp->lay_flags &= ~NFSLAY_READ; 7311 if ((iomode & NFSLAYOUTIOMODE_RW) != 0) 7312 lyp->lay_flags &= ~NFSLAY_RW; 7313 if ((lyp->lay_flags & (NFSLAY_READ | 7314 NFSLAY_RW)) == 0) 7315 nfsrv_freelayout(&lhyp->list, 7316 lyp); 7317 else 7318 *fndp = 1; 7319 } else 7320 *fndp = 1; 7321 } 7322 NFSUNLOCKLAYOUT(lhyp); 7323 /* Search the nfsrv_recalllist for a match. */ 7324 TAILQ_FOREACH(lyp, &nfsrv_recalllisthead, lay_list) { 7325 if (NFSBCMP(&lyp->lay_fh, &fh, 7326 sizeof(fh)) == 0 && 7327 lyp->lay_clientid.qval == 7328 nd->nd_clientid.qval && 7329 stateidp->other[0] == 7330 lyp->lay_stateid.other[0] && 7331 stateidp->other[1] == 7332 lyp->lay_stateid.other[1] && 7333 stateidp->other[2] == 7334 lyp->lay_stateid.other[2]) { 7335 lyp->lay_flags |= NFSLAY_RETURNED; 7336 wakeup(lyp); 7337 error = 0; 7338 } 7339 } 7340 NFSDRECALLUNLOCK(); 7341 } 7342 if (layouttype == NFSLAYOUT_FLEXFILE && layp != NULL) 7343 nfsrv_flexlayouterr(nd, layp, maxcnt, p); 7344 } else if (kind == NFSV4LAYOUTRET_FSID) 7345 nfsrv_freelayouts(&nd->nd_clientid, 7346 &vp->v_mount->mnt_stat.f_fsid, layouttype, iomode); 7347 else if (kind == NFSV4LAYOUTRET_ALL) 7348 nfsrv_freelayouts(&nd->nd_clientid, NULL, layouttype, iomode); 7349 else 7350 error = NFSERR_INVAL; 7351 if (error == -1) 7352 error = 0; 7353 return (error); 7354 } 7355 7356 /* 7357 * Look for an existing layout. 7358 */ 7359 static int 7360 nfsrv_findlayout(nfsquad_t *clientidp, fhandle_t *fhp, int laytype, 7361 NFSPROC_T *p, struct nfslayout **lypp) 7362 { 7363 struct nfslayouthash *lhyp; 7364 struct nfslayout *lyp; 7365 int ret; 7366 7367 *lypp = NULL; 7368 ret = 0; 7369 lhyp = NFSLAYOUTHASH(fhp); 7370 TAILQ_FOREACH(lyp, &lhyp->list, lay_list) { 7371 if (NFSBCMP(&lyp->lay_fh, fhp, sizeof(*fhp)) == 0 && 7372 lyp->lay_clientid.qval == clientidp->qval && 7373 lyp->lay_type == laytype) 7374 break; 7375 } 7376 if (lyp != NULL) 7377 *lypp = lyp; 7378 else 7379 ret = -1; 7380 return (ret); 7381 } 7382 7383 /* 7384 * Add the new layout, as required. 7385 */ 7386 static int 7387 nfsrv_addlayout(struct nfsrv_descript *nd, struct nfslayout **lypp, 7388 nfsv4stateid_t *stateidp, char *layp, int *layoutlenp, NFSPROC_T *p) 7389 { 7390 struct nfsclient *clp; 7391 struct nfslayouthash *lhyp; 7392 struct nfslayout *lyp, *nlyp; 7393 fhandle_t *fhp; 7394 int error; 7395 7396 KASSERT((nd->nd_flag & ND_IMPLIEDCLID) != 0, 7397 ("nfsrv_layoutget: no nd_clientid\n")); 7398 lyp = *lypp; 7399 fhp = &lyp->lay_fh; 7400 NFSLOCKSTATE(); 7401 error = nfsrv_getclient((nfsquad_t)((u_quad_t)0), CLOPS_RENEW, &clp, 7402 NULL, (nfsquad_t)((u_quad_t)0), 0, nd, p); 7403 if (error != 0) { 7404 NFSUNLOCKSTATE(); 7405 return (error); 7406 } 7407 lyp->lay_stateid.seqid = stateidp->seqid = 1; 7408 lyp->lay_stateid.other[0] = stateidp->other[0] = 7409 clp->lc_clientid.lval[0]; 7410 lyp->lay_stateid.other[1] = stateidp->other[1] = 7411 clp->lc_clientid.lval[1]; 7412 lyp->lay_stateid.other[2] = stateidp->other[2] = 7413 nfsrv_nextstateindex(clp); 7414 NFSUNLOCKSTATE(); 7415 7416 lhyp = NFSLAYOUTHASH(fhp); 7417 NFSLOCKLAYOUT(lhyp); 7418 TAILQ_FOREACH(nlyp, &lhyp->list, lay_list) { 7419 if (NFSBCMP(&nlyp->lay_fh, fhp, sizeof(*fhp)) == 0 && 7420 nlyp->lay_clientid.qval == nd->nd_clientid.qval) 7421 break; 7422 } 7423 if (nlyp != NULL) { 7424 /* A layout already exists, so use it. */ 7425 nlyp->lay_flags |= (lyp->lay_flags & (NFSLAY_READ | NFSLAY_RW)); 7426 NFSBCOPY(nlyp->lay_xdr, layp, nlyp->lay_layoutlen); 7427 *layoutlenp = nlyp->lay_layoutlen; 7428 if (++nlyp->lay_stateid.seqid == 0) 7429 nlyp->lay_stateid.seqid = 1; 7430 stateidp->seqid = nlyp->lay_stateid.seqid; 7431 stateidp->other[0] = nlyp->lay_stateid.other[0]; 7432 stateidp->other[1] = nlyp->lay_stateid.other[1]; 7433 stateidp->other[2] = nlyp->lay_stateid.other[2]; 7434 NFSUNLOCKLAYOUT(lhyp); 7435 return (0); 7436 } 7437 7438 /* Insert the new layout in the lists. */ 7439 *lypp = NULL; 7440 atomic_add_int(&nfsrv_layoutcnt, 1); 7441 nfsstatsv1.srvlayouts++; 7442 NFSBCOPY(lyp->lay_xdr, layp, lyp->lay_layoutlen); 7443 *layoutlenp = lyp->lay_layoutlen; 7444 TAILQ_INSERT_HEAD(&lhyp->list, lyp, lay_list); 7445 NFSUNLOCKLAYOUT(lhyp); 7446 return (0); 7447 } 7448 7449 /* 7450 * Get the devinfo for a deviceid. 7451 */ 7452 int 7453 nfsrv_getdevinfo(char *devid, int layouttype, uint32_t *maxcnt, 7454 uint32_t *notify, int *devaddrlen, char **devaddr) 7455 { 7456 struct nfsdevice *ds; 7457 7458 if ((layouttype != NFSLAYOUT_NFSV4_1_FILES && layouttype != 7459 NFSLAYOUT_FLEXFILE) || 7460 (nfsrv_maxpnfsmirror > 1 && layouttype == NFSLAYOUT_NFSV4_1_FILES)) 7461 return (NFSERR_UNKNLAYOUTTYPE); 7462 7463 /* 7464 * Now, search for the device id. Note that the structures won't go 7465 * away, but the order changes in the list. As such, the lock only 7466 * needs to be held during the search through the list. 7467 */ 7468 NFSDDSLOCK(); 7469 TAILQ_FOREACH(ds, &nfsrv_devidhead, nfsdev_list) { 7470 if (NFSBCMP(devid, ds->nfsdev_deviceid, NFSX_V4DEVICEID) == 0 && 7471 ds->nfsdev_nmp != NULL) 7472 break; 7473 } 7474 NFSDDSUNLOCK(); 7475 if (ds == NULL) 7476 return (NFSERR_NOENT); 7477 7478 /* If the correct nfsdev_XXXXaddrlen is > 0, we have the device info. */ 7479 *devaddrlen = 0; 7480 if (layouttype == NFSLAYOUT_NFSV4_1_FILES) { 7481 *devaddrlen = ds->nfsdev_fileaddrlen; 7482 *devaddr = ds->nfsdev_fileaddr; 7483 } else if (layouttype == NFSLAYOUT_FLEXFILE) { 7484 *devaddrlen = ds->nfsdev_flexaddrlen; 7485 *devaddr = ds->nfsdev_flexaddr; 7486 } 7487 if (*devaddrlen == 0) 7488 return (NFSERR_UNKNLAYOUTTYPE); 7489 7490 /* 7491 * The XDR overhead is 3 unsigned values: layout_type, 7492 * length_of_address and notify bitmap. 7493 * If the notify array is changed to not all zeros, the 7494 * count of unsigned values must be increased. 7495 */ 7496 if (*maxcnt > 0 && *maxcnt < NFSM_RNDUP(*devaddrlen) + 7497 3 * NFSX_UNSIGNED) { 7498 *maxcnt = NFSM_RNDUP(*devaddrlen) + 3 * NFSX_UNSIGNED; 7499 return (NFSERR_TOOSMALL); 7500 } 7501 return (0); 7502 } 7503 7504 /* 7505 * Free a list of layout state structures. 7506 */ 7507 static void 7508 nfsrv_freelayoutlist(nfsquad_t clientid) 7509 { 7510 struct nfslayouthash *lhyp; 7511 struct nfslayout *lyp, *nlyp; 7512 int i; 7513 7514 for (i = 0; i < nfsrv_layouthashsize; i++) { 7515 lhyp = &nfslayouthash[i]; 7516 NFSLOCKLAYOUT(lhyp); 7517 TAILQ_FOREACH_SAFE(lyp, &lhyp->list, lay_list, nlyp) { 7518 if (lyp->lay_clientid.qval == clientid.qval) 7519 nfsrv_freelayout(&lhyp->list, lyp); 7520 } 7521 NFSUNLOCKLAYOUT(lhyp); 7522 } 7523 } 7524 7525 /* 7526 * Free up a layout. 7527 */ 7528 static void 7529 nfsrv_freelayout(struct nfslayouthead *lhp, struct nfslayout *lyp) 7530 { 7531 7532 NFSD_DEBUG(4, "Freelayout=%p\n", lyp); 7533 atomic_add_int(&nfsrv_layoutcnt, -1); 7534 nfsstatsv1.srvlayouts--; 7535 TAILQ_REMOVE(lhp, lyp, lay_list); 7536 free(lyp, M_NFSDSTATE); 7537 } 7538 7539 /* 7540 * Free up a device id. 7541 */ 7542 void 7543 nfsrv_freeonedevid(struct nfsdevice *ds) 7544 { 7545 int i; 7546 7547 atomic_add_int(&nfsrv_devidcnt, -1); 7548 vrele(ds->nfsdev_dvp); 7549 for (i = 0; i < nfsrv_dsdirsize; i++) 7550 if (ds->nfsdev_dsdir[i] != NULL) 7551 vrele(ds->nfsdev_dsdir[i]); 7552 free(ds->nfsdev_fileaddr, M_NFSDSTATE); 7553 free(ds->nfsdev_flexaddr, M_NFSDSTATE); 7554 free(ds->nfsdev_host, M_NFSDSTATE); 7555 free(ds, M_NFSDSTATE); 7556 } 7557 7558 /* 7559 * Free up a device id and its mirrors. 7560 */ 7561 static void 7562 nfsrv_freedevid(struct nfsdevice *ds) 7563 { 7564 7565 TAILQ_REMOVE(&nfsrv_devidhead, ds, nfsdev_list); 7566 nfsrv_freeonedevid(ds); 7567 } 7568 7569 /* 7570 * Free all layouts and device ids. 7571 * Done when the nfsd threads are shut down since there may be a new 7572 * modified device id list created when the nfsd is restarted. 7573 */ 7574 void 7575 nfsrv_freealllayoutsanddevids(void) 7576 { 7577 struct nfsdontlist *mrp, *nmrp; 7578 struct nfslayout *lyp, *nlyp; 7579 7580 /* Get rid of the deviceid structures. */ 7581 nfsrv_freealldevids(); 7582 TAILQ_INIT(&nfsrv_devidhead); 7583 nfsrv_devidcnt = 0; 7584 7585 /* Get rid of all layouts. */ 7586 nfsrv_freealllayouts(); 7587 7588 /* Get rid of any nfsdontlist entries. */ 7589 LIST_FOREACH_SAFE(mrp, &nfsrv_dontlisthead, nfsmr_list, nmrp) 7590 free(mrp, M_NFSDSTATE); 7591 LIST_INIT(&nfsrv_dontlisthead); 7592 nfsrv_dontlistlen = 0; 7593 7594 /* Free layouts in the recall list. */ 7595 TAILQ_FOREACH_SAFE(lyp, &nfsrv_recalllisthead, lay_list, nlyp) 7596 nfsrv_freelayout(&nfsrv_recalllisthead, lyp); 7597 TAILQ_INIT(&nfsrv_recalllisthead); 7598 } 7599 7600 /* 7601 * Free layouts that match the arguments. 7602 */ 7603 static void 7604 nfsrv_freelayouts(nfsquad_t *clid, fsid_t *fs, int laytype, int iomode) 7605 { 7606 struct nfslayouthash *lhyp; 7607 struct nfslayout *lyp, *nlyp; 7608 int i; 7609 7610 for (i = 0; i < nfsrv_layouthashsize; i++) { 7611 lhyp = &nfslayouthash[i]; 7612 NFSLOCKLAYOUT(lhyp); 7613 TAILQ_FOREACH_SAFE(lyp, &lhyp->list, lay_list, nlyp) { 7614 if (clid->qval != lyp->lay_clientid.qval) 7615 continue; 7616 if (fs != NULL && fsidcmp(fs, &lyp->lay_fsid) != 0) 7617 continue; 7618 if (laytype != lyp->lay_type) 7619 continue; 7620 if ((iomode & NFSLAYOUTIOMODE_READ) != 0) 7621 lyp->lay_flags &= ~NFSLAY_READ; 7622 if ((iomode & NFSLAYOUTIOMODE_RW) != 0) 7623 lyp->lay_flags &= ~NFSLAY_RW; 7624 if ((lyp->lay_flags & (NFSLAY_READ | NFSLAY_RW)) == 0) 7625 nfsrv_freelayout(&lhyp->list, lyp); 7626 } 7627 NFSUNLOCKLAYOUT(lhyp); 7628 } 7629 } 7630 7631 /* 7632 * Free all layouts for the argument file. 7633 */ 7634 void 7635 nfsrv_freefilelayouts(fhandle_t *fhp) 7636 { 7637 struct nfslayouthash *lhyp; 7638 struct nfslayout *lyp, *nlyp; 7639 7640 lhyp = NFSLAYOUTHASH(fhp); 7641 NFSLOCKLAYOUT(lhyp); 7642 TAILQ_FOREACH_SAFE(lyp, &lhyp->list, lay_list, nlyp) { 7643 if (NFSBCMP(&lyp->lay_fh, fhp, sizeof(*fhp)) == 0) 7644 nfsrv_freelayout(&lhyp->list, lyp); 7645 } 7646 NFSUNLOCKLAYOUT(lhyp); 7647 } 7648 7649 /* 7650 * Free all layouts. 7651 */ 7652 static void 7653 nfsrv_freealllayouts(void) 7654 { 7655 struct nfslayouthash *lhyp; 7656 struct nfslayout *lyp, *nlyp; 7657 int i; 7658 7659 for (i = 0; i < nfsrv_layouthashsize; i++) { 7660 lhyp = &nfslayouthash[i]; 7661 NFSLOCKLAYOUT(lhyp); 7662 TAILQ_FOREACH_SAFE(lyp, &lhyp->list, lay_list, nlyp) 7663 nfsrv_freelayout(&lhyp->list, lyp); 7664 NFSUNLOCKLAYOUT(lhyp); 7665 } 7666 } 7667 7668 /* 7669 * Look up the mount path for the DS server. 7670 */ 7671 static int 7672 nfsrv_setdsserver(char *dspathp, char *mdspathp, NFSPROC_T *p, 7673 struct nfsdevice **dsp) 7674 { 7675 struct nameidata nd; 7676 struct nfsdevice *ds; 7677 struct mount *mp; 7678 int error, i; 7679 char *dsdirpath; 7680 size_t dsdirsize; 7681 7682 NFSD_DEBUG(4, "setdssrv path=%s\n", dspathp); 7683 *dsp = NULL; 7684 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF, UIO_SYSSPACE, 7685 dspathp); 7686 error = namei(&nd); 7687 NFSD_DEBUG(4, "lookup=%d\n", error); 7688 if (error != 0) 7689 return (error); 7690 if (nd.ni_vp->v_type != VDIR) { 7691 vput(nd.ni_vp); 7692 NFSD_DEBUG(4, "dspath not dir\n"); 7693 return (ENOTDIR); 7694 } 7695 if (strcmp(nd.ni_vp->v_mount->mnt_vfc->vfc_name, "nfs") != 0) { 7696 vput(nd.ni_vp); 7697 NFSD_DEBUG(4, "dspath not an NFS mount\n"); 7698 return (ENXIO); 7699 } 7700 7701 /* 7702 * Allocate a DS server structure with the NFS mounted directory 7703 * vnode reference counted, so that a non-forced dismount will 7704 * fail with EBUSY. 7705 * This structure is always linked into the list, even if an error 7706 * is being returned. The caller will free the entire list upon 7707 * an error return. 7708 */ 7709 *dsp = ds = malloc(sizeof(*ds) + nfsrv_dsdirsize * sizeof(vnode_t), 7710 M_NFSDSTATE, M_WAITOK | M_ZERO); 7711 ds->nfsdev_dvp = nd.ni_vp; 7712 ds->nfsdev_nmp = VFSTONFS(nd.ni_vp->v_mount); 7713 NFSVOPUNLOCK(nd.ni_vp); 7714 7715 dsdirsize = strlen(dspathp) + 16; 7716 dsdirpath = malloc(dsdirsize, M_TEMP, M_WAITOK); 7717 /* Now, create the DS directory structures. */ 7718 for (i = 0; i < nfsrv_dsdirsize; i++) { 7719 snprintf(dsdirpath, dsdirsize, "%s/ds%d", dspathp, i); 7720 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF, 7721 UIO_SYSSPACE, dsdirpath); 7722 error = namei(&nd); 7723 NFSD_DEBUG(4, "dsdirpath=%s lookup=%d\n", dsdirpath, error); 7724 if (error != 0) 7725 break; 7726 if (nd.ni_vp->v_type != VDIR) { 7727 vput(nd.ni_vp); 7728 error = ENOTDIR; 7729 NFSD_DEBUG(4, "dsdirpath not a VDIR\n"); 7730 break; 7731 } 7732 if (strcmp(nd.ni_vp->v_mount->mnt_vfc->vfc_name, "nfs") != 0) { 7733 vput(nd.ni_vp); 7734 error = ENXIO; 7735 NFSD_DEBUG(4, "dsdirpath not an NFS mount\n"); 7736 break; 7737 } 7738 ds->nfsdev_dsdir[i] = nd.ni_vp; 7739 NFSVOPUNLOCK(nd.ni_vp); 7740 } 7741 free(dsdirpath, M_TEMP); 7742 7743 if (strlen(mdspathp) > 0) { 7744 /* 7745 * This DS stores file for a specific MDS exported file 7746 * system. 7747 */ 7748 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF, 7749 UIO_SYSSPACE, mdspathp); 7750 error = namei(&nd); 7751 NFSD_DEBUG(4, "mds lookup=%d\n", error); 7752 if (error != 0) 7753 goto out; 7754 if (nd.ni_vp->v_type != VDIR) { 7755 vput(nd.ni_vp); 7756 error = ENOTDIR; 7757 NFSD_DEBUG(4, "mdspath not dir\n"); 7758 goto out; 7759 } 7760 mp = nd.ni_vp->v_mount; 7761 if ((mp->mnt_flag & MNT_EXPORTED) == 0) { 7762 vput(nd.ni_vp); 7763 error = ENXIO; 7764 NFSD_DEBUG(4, "mdspath not an exported fs\n"); 7765 goto out; 7766 } 7767 ds->nfsdev_mdsfsid = mp->mnt_stat.f_fsid; 7768 ds->nfsdev_mdsisset = 1; 7769 vput(nd.ni_vp); 7770 } 7771 7772 out: 7773 TAILQ_INSERT_TAIL(&nfsrv_devidhead, ds, nfsdev_list); 7774 atomic_add_int(&nfsrv_devidcnt, 1); 7775 return (error); 7776 } 7777 7778 /* 7779 * Look up the mount path for the DS server and delete it. 7780 */ 7781 int 7782 nfsrv_deldsserver(int op, char *dspathp, NFSPROC_T *p) 7783 { 7784 struct mount *mp; 7785 struct nfsmount *nmp; 7786 struct nfsdevice *ds; 7787 int error; 7788 7789 NFSD_DEBUG(4, "deldssrv path=%s\n", dspathp); 7790 /* 7791 * Search for the path in the mount list. Avoid looking the path 7792 * up, since this mount point may be hung, with associated locked 7793 * vnodes, etc. 7794 * Set NFSMNTP_CANCELRPCS so that any forced dismount will be blocked 7795 * until this completes. 7796 * As noted in the man page, this should be done before any forced 7797 * dismount on the mount point, but at least the handshake on 7798 * NFSMNTP_CANCELRPCS should make it safe. 7799 */ 7800 error = 0; 7801 ds = NULL; 7802 nmp = NULL; 7803 mtx_lock(&mountlist_mtx); 7804 TAILQ_FOREACH(mp, &mountlist, mnt_list) { 7805 if (strcmp(mp->mnt_stat.f_mntonname, dspathp) == 0 && 7806 strcmp(mp->mnt_stat.f_fstypename, "nfs") == 0 && 7807 mp->mnt_data != NULL) { 7808 nmp = VFSTONFS(mp); 7809 NFSLOCKMNT(nmp); 7810 if ((nmp->nm_privflag & (NFSMNTP_FORCEDISM | 7811 NFSMNTP_CANCELRPCS)) == 0) { 7812 nmp->nm_privflag |= NFSMNTP_CANCELRPCS; 7813 NFSUNLOCKMNT(nmp); 7814 } else { 7815 NFSUNLOCKMNT(nmp); 7816 nmp = NULL; 7817 } 7818 break; 7819 } 7820 } 7821 mtx_unlock(&mountlist_mtx); 7822 7823 if (nmp != NULL) { 7824 ds = nfsrv_deldsnmp(op, nmp, p); 7825 NFSD_DEBUG(4, "deldsnmp=%p\n", ds); 7826 if (ds != NULL) { 7827 nfsrv_killrpcs(nmp); 7828 NFSD_DEBUG(4, "aft killrpcs\n"); 7829 } else 7830 error = ENXIO; 7831 NFSLOCKMNT(nmp); 7832 nmp->nm_privflag &= ~NFSMNTP_CANCELRPCS; 7833 wakeup(nmp); 7834 NFSUNLOCKMNT(nmp); 7835 } else 7836 error = EINVAL; 7837 return (error); 7838 } 7839 7840 /* 7841 * Search for and remove a DS entry which matches the "nmp" argument. 7842 * The nfsdevice structure pointer is returned so that the caller can 7843 * free it via nfsrv_freeonedevid(). 7844 * For the forced case, do not try to do LayoutRecalls, since the server 7845 * must be shut down now anyhow. 7846 */ 7847 struct nfsdevice * 7848 nfsrv_deldsnmp(int op, struct nfsmount *nmp, NFSPROC_T *p) 7849 { 7850 struct nfsdevice *fndds; 7851 7852 NFSD_DEBUG(4, "deldsdvp\n"); 7853 NFSDDSLOCK(); 7854 if (op == PNFSDOP_FORCEDELDS) 7855 fndds = nfsv4_findmirror(nmp); 7856 else 7857 fndds = nfsrv_findmirroredds(nmp); 7858 if (fndds != NULL) 7859 nfsrv_deleteds(fndds); 7860 NFSDDSUNLOCK(); 7861 if (fndds != NULL) { 7862 if (op != PNFSDOP_FORCEDELDS) 7863 nfsrv_flexmirrordel(fndds->nfsdev_deviceid, p); 7864 printf("pNFS server: mirror %s failed\n", fndds->nfsdev_host); 7865 } 7866 return (fndds); 7867 } 7868 7869 /* 7870 * Similar to nfsrv_deldsnmp(), except that the DS is indicated by deviceid. 7871 * This function also calls nfsrv_killrpcs() to unblock RPCs on the mount 7872 * point. 7873 * Also, returns an error instead of the nfsdevice found. 7874 */ 7875 int 7876 nfsrv_delds(char *devid, NFSPROC_T *p) 7877 { 7878 struct nfsdevice *ds, *fndds; 7879 struct nfsmount *nmp; 7880 int fndmirror; 7881 7882 NFSD_DEBUG(4, "delds\n"); 7883 /* 7884 * Search the DS server list for a match with devid. 7885 * Remove the DS entry if found and there is a mirror. 7886 */ 7887 fndds = NULL; 7888 nmp = NULL; 7889 fndmirror = 0; 7890 NFSDDSLOCK(); 7891 TAILQ_FOREACH(ds, &nfsrv_devidhead, nfsdev_list) { 7892 if (NFSBCMP(ds->nfsdev_deviceid, devid, NFSX_V4DEVICEID) == 0 && 7893 ds->nfsdev_nmp != NULL) { 7894 NFSD_DEBUG(4, "fnd main ds\n"); 7895 fndds = ds; 7896 break; 7897 } 7898 } 7899 if (fndds == NULL) { 7900 NFSDDSUNLOCK(); 7901 return (ENXIO); 7902 } 7903 if (fndds->nfsdev_mdsisset == 0 && nfsrv_faildscnt > 0) 7904 fndmirror = 1; 7905 else if (fndds->nfsdev_mdsisset != 0) { 7906 /* For the fsid is set case, search for a mirror. */ 7907 TAILQ_FOREACH(ds, &nfsrv_devidhead, nfsdev_list) { 7908 if (ds != fndds && ds->nfsdev_nmp != NULL && 7909 ds->nfsdev_mdsisset != 0 && 7910 fsidcmp(&ds->nfsdev_mdsfsid, 7911 &fndds->nfsdev_mdsfsid) == 0) { 7912 fndmirror = 1; 7913 break; 7914 } 7915 } 7916 } 7917 if (fndmirror != 0) { 7918 nmp = fndds->nfsdev_nmp; 7919 NFSLOCKMNT(nmp); 7920 if ((nmp->nm_privflag & (NFSMNTP_FORCEDISM | 7921 NFSMNTP_CANCELRPCS)) == 0) { 7922 nmp->nm_privflag |= NFSMNTP_CANCELRPCS; 7923 NFSUNLOCKMNT(nmp); 7924 nfsrv_deleteds(fndds); 7925 } else { 7926 NFSUNLOCKMNT(nmp); 7927 nmp = NULL; 7928 } 7929 } 7930 NFSDDSUNLOCK(); 7931 if (nmp != NULL) { 7932 nfsrv_flexmirrordel(fndds->nfsdev_deviceid, p); 7933 printf("pNFS server: mirror %s failed\n", fndds->nfsdev_host); 7934 nfsrv_killrpcs(nmp); 7935 NFSLOCKMNT(nmp); 7936 nmp->nm_privflag &= ~NFSMNTP_CANCELRPCS; 7937 wakeup(nmp); 7938 NFSUNLOCKMNT(nmp); 7939 return (0); 7940 } 7941 return (ENXIO); 7942 } 7943 7944 /* 7945 * Mark a DS as disabled by setting nfsdev_nmp = NULL. 7946 */ 7947 static void 7948 nfsrv_deleteds(struct nfsdevice *fndds) 7949 { 7950 7951 NFSD_DEBUG(4, "deleteds: deleting a mirror\n"); 7952 fndds->nfsdev_nmp = NULL; 7953 if (fndds->nfsdev_mdsisset == 0) 7954 nfsrv_faildscnt--; 7955 } 7956 7957 /* 7958 * Fill in the addr structures for the File and Flex File layouts. 7959 */ 7960 static void 7961 nfsrv_allocdevid(struct nfsdevice *ds, char *addr, char *dnshost) 7962 { 7963 uint32_t *tl; 7964 char *netprot; 7965 int addrlen; 7966 static uint64_t new_devid = 0; 7967 7968 if (strchr(addr, ':') != NULL) 7969 netprot = "tcp6"; 7970 else 7971 netprot = "tcp"; 7972 7973 /* Fill in the device id. */ 7974 NFSBCOPY(&nfsdev_time, ds->nfsdev_deviceid, sizeof(nfsdev_time)); 7975 new_devid++; 7976 NFSBCOPY(&new_devid, &ds->nfsdev_deviceid[sizeof(nfsdev_time)], 7977 sizeof(new_devid)); 7978 7979 /* 7980 * Fill in the file addr (actually the nfsv4_file_layout_ds_addr4 7981 * as defined in RFC5661) in XDR. 7982 */ 7983 addrlen = NFSM_RNDUP(strlen(addr)) + NFSM_RNDUP(strlen(netprot)) + 7984 6 * NFSX_UNSIGNED; 7985 NFSD_DEBUG(4, "hn=%s addr=%s netprot=%s\n", dnshost, addr, netprot); 7986 ds->nfsdev_fileaddrlen = addrlen; 7987 tl = malloc(addrlen, M_NFSDSTATE, M_WAITOK | M_ZERO); 7988 ds->nfsdev_fileaddr = (char *)tl; 7989 *tl++ = txdr_unsigned(1); /* One stripe with index 0. */ 7990 *tl++ = 0; 7991 *tl++ = txdr_unsigned(1); /* One multipath list */ 7992 *tl++ = txdr_unsigned(1); /* with one entry in it. */ 7993 /* The netaddr for this one entry. */ 7994 *tl++ = txdr_unsigned(strlen(netprot)); 7995 NFSBCOPY(netprot, tl, strlen(netprot)); 7996 tl += (NFSM_RNDUP(strlen(netprot)) / NFSX_UNSIGNED); 7997 *tl++ = txdr_unsigned(strlen(addr)); 7998 NFSBCOPY(addr, tl, strlen(addr)); 7999 8000 /* 8001 * Fill in the flex file addr (actually the ff_device_addr4 8002 * as defined for Flexible File Layout) in XDR. 8003 */ 8004 addrlen = NFSM_RNDUP(strlen(addr)) + NFSM_RNDUP(strlen(netprot)) + 8005 14 * NFSX_UNSIGNED; 8006 ds->nfsdev_flexaddrlen = addrlen; 8007 tl = malloc(addrlen, M_NFSDSTATE, M_WAITOK | M_ZERO); 8008 ds->nfsdev_flexaddr = (char *)tl; 8009 *tl++ = txdr_unsigned(1); /* One multipath entry. */ 8010 /* The netaddr for this one entry. */ 8011 *tl++ = txdr_unsigned(strlen(netprot)); 8012 NFSBCOPY(netprot, tl, strlen(netprot)); 8013 tl += (NFSM_RNDUP(strlen(netprot)) / NFSX_UNSIGNED); 8014 *tl++ = txdr_unsigned(strlen(addr)); 8015 NFSBCOPY(addr, tl, strlen(addr)); 8016 tl += (NFSM_RNDUP(strlen(addr)) / NFSX_UNSIGNED); 8017 *tl++ = txdr_unsigned(2); /* Two NFS Versions. */ 8018 *tl++ = txdr_unsigned(NFS_VER4); /* NFSv4. */ 8019 *tl++ = txdr_unsigned(NFSV42_MINORVERSION); /* Minor version 2. */ 8020 *tl++ = txdr_unsigned(nfs_srvmaxio); /* DS max rsize. */ 8021 *tl++ = txdr_unsigned(nfs_srvmaxio); /* DS max wsize. */ 8022 *tl++ = newnfs_true; /* Tightly coupled. */ 8023 *tl++ = txdr_unsigned(NFS_VER4); /* NFSv4. */ 8024 *tl++ = txdr_unsigned(NFSV41_MINORVERSION); /* Minor version 1. */ 8025 *tl++ = txdr_unsigned(nfs_srvmaxio); /* DS max rsize. */ 8026 *tl++ = txdr_unsigned(nfs_srvmaxio); /* DS max wsize. */ 8027 *tl = newnfs_true; /* Tightly coupled. */ 8028 8029 ds->nfsdev_hostnamelen = strlen(dnshost); 8030 ds->nfsdev_host = malloc(ds->nfsdev_hostnamelen + 1, M_NFSDSTATE, 8031 M_WAITOK); 8032 NFSBCOPY(dnshost, ds->nfsdev_host, ds->nfsdev_hostnamelen + 1); 8033 } 8034 8035 /* 8036 * Create the device id list. 8037 * Return 0 if the nfsd threads are to run and ENXIO if the "-p" argument 8038 * is misconfigured. 8039 */ 8040 int 8041 nfsrv_createdevids(struct nfsd_nfsd_args *args, NFSPROC_T *p) 8042 { 8043 struct nfsdevice *ds; 8044 char *addrp, *dnshostp, *dspathp, *mdspathp; 8045 int error, i; 8046 8047 addrp = args->addr; 8048 dnshostp = args->dnshost; 8049 dspathp = args->dspath; 8050 mdspathp = args->mdspath; 8051 nfsrv_maxpnfsmirror = args->mirrorcnt; 8052 if (addrp == NULL || dnshostp == NULL || dspathp == NULL || 8053 mdspathp == NULL) 8054 return (0); 8055 8056 /* 8057 * Loop around for each nul-terminated string in args->addr, 8058 * args->dnshost, args->dnspath and args->mdspath. 8059 */ 8060 while (addrp < (args->addr + args->addrlen) && 8061 dnshostp < (args->dnshost + args->dnshostlen) && 8062 dspathp < (args->dspath + args->dspathlen) && 8063 mdspathp < (args->mdspath + args->mdspathlen)) { 8064 error = nfsrv_setdsserver(dspathp, mdspathp, p, &ds); 8065 if (error != 0) { 8066 /* Free all DS servers. */ 8067 nfsrv_freealldevids(); 8068 nfsrv_devidcnt = 0; 8069 return (ENXIO); 8070 } 8071 nfsrv_allocdevid(ds, addrp, dnshostp); 8072 addrp += (strlen(addrp) + 1); 8073 dnshostp += (strlen(dnshostp) + 1); 8074 dspathp += (strlen(dspathp) + 1); 8075 mdspathp += (strlen(mdspathp) + 1); 8076 } 8077 if (nfsrv_devidcnt < nfsrv_maxpnfsmirror) { 8078 /* Free all DS servers. */ 8079 nfsrv_freealldevids(); 8080 nfsrv_devidcnt = 0; 8081 nfsrv_maxpnfsmirror = 1; 8082 return (ENXIO); 8083 } 8084 /* We can fail at most one less DS than the mirror level. */ 8085 nfsrv_faildscnt = nfsrv_maxpnfsmirror - 1; 8086 8087 /* 8088 * Allocate the nfslayout hash table now, since this is a pNFS server. 8089 * Make it 1% of the high water mark and at least 100. 8090 */ 8091 if (nfslayouthash == NULL) { 8092 nfsrv_layouthashsize = nfsrv_layouthighwater / 100; 8093 if (nfsrv_layouthashsize < 100) 8094 nfsrv_layouthashsize = 100; 8095 nfslayouthash = mallocarray(nfsrv_layouthashsize, 8096 sizeof(struct nfslayouthash), M_NFSDSESSION, M_WAITOK | 8097 M_ZERO); 8098 for (i = 0; i < nfsrv_layouthashsize; i++) { 8099 mtx_init(&nfslayouthash[i].mtx, "nfslm", NULL, MTX_DEF); 8100 TAILQ_INIT(&nfslayouthash[i].list); 8101 } 8102 } 8103 return (0); 8104 } 8105 8106 /* 8107 * Free all device ids. 8108 */ 8109 static void 8110 nfsrv_freealldevids(void) 8111 { 8112 struct nfsdevice *ds, *nds; 8113 8114 TAILQ_FOREACH_SAFE(ds, &nfsrv_devidhead, nfsdev_list, nds) 8115 nfsrv_freedevid(ds); 8116 } 8117 8118 /* 8119 * Check to see if there is a Read/Write Layout plus either: 8120 * - A Write Delegation 8121 * or 8122 * - An Open with Write_access. 8123 * Return 1 if this is the case and 0 otherwise. 8124 * This function is used by nfsrv_proxyds() to decide if doing a Proxy 8125 * Getattr RPC to the Data Server (DS) is necessary. 8126 */ 8127 #define NFSCLIDVECSIZE 6 8128 int 8129 nfsrv_checkdsattr(vnode_t vp, NFSPROC_T *p) 8130 { 8131 fhandle_t fh, *tfhp; 8132 struct nfsstate *stp; 8133 struct nfslayout *lyp; 8134 struct nfslayouthash *lhyp; 8135 struct nfslockhashhead *hp; 8136 struct nfslockfile *lfp; 8137 nfsquad_t clid[NFSCLIDVECSIZE]; 8138 int clidcnt, ret; 8139 8140 ret = nfsvno_getfh(vp, &fh, p); 8141 if (ret != 0) 8142 return (0); 8143 8144 /* First check for a Read/Write Layout. */ 8145 clidcnt = 0; 8146 lhyp = NFSLAYOUTHASH(&fh); 8147 NFSLOCKLAYOUT(lhyp); 8148 TAILQ_FOREACH(lyp, &lhyp->list, lay_list) { 8149 if (NFSBCMP(&lyp->lay_fh, &fh, sizeof(fh)) == 0 && 8150 ((lyp->lay_flags & NFSLAY_RW) != 0 || 8151 ((lyp->lay_flags & NFSLAY_READ) != 0 && 8152 nfsrv_pnfsatime != 0))) { 8153 if (clidcnt < NFSCLIDVECSIZE) 8154 clid[clidcnt].qval = lyp->lay_clientid.qval; 8155 clidcnt++; 8156 } 8157 } 8158 NFSUNLOCKLAYOUT(lhyp); 8159 if (clidcnt == 0) { 8160 /* None found, so return 0. */ 8161 return (0); 8162 } 8163 8164 /* Get the nfslockfile for this fh. */ 8165 NFSLOCKSTATE(); 8166 hp = NFSLOCKHASH(&fh); 8167 LIST_FOREACH(lfp, hp, lf_hash) { 8168 tfhp = &lfp->lf_fh; 8169 if (NFSVNO_CMPFH(&fh, tfhp)) 8170 break; 8171 } 8172 if (lfp == NULL) { 8173 /* None found, so return 0. */ 8174 NFSUNLOCKSTATE(); 8175 return (0); 8176 } 8177 8178 /* Now, look for a Write delegation for this clientid. */ 8179 LIST_FOREACH(stp, &lfp->lf_deleg, ls_file) { 8180 if ((stp->ls_flags & NFSLCK_DELEGWRITE) != 0 && 8181 nfsrv_fndclid(clid, stp->ls_clp->lc_clientid, clidcnt) != 0) 8182 break; 8183 } 8184 if (stp != NULL) { 8185 /* Found one, so return 1. */ 8186 NFSUNLOCKSTATE(); 8187 return (1); 8188 } 8189 8190 /* No Write delegation, so look for an Open with Write_access. */ 8191 LIST_FOREACH(stp, &lfp->lf_open, ls_file) { 8192 KASSERT((stp->ls_flags & NFSLCK_OPEN) != 0, 8193 ("nfsrv_checkdsattr: Non-open in Open list\n")); 8194 if ((stp->ls_flags & NFSLCK_WRITEACCESS) != 0 && 8195 nfsrv_fndclid(clid, stp->ls_clp->lc_clientid, clidcnt) != 0) 8196 break; 8197 } 8198 NFSUNLOCKSTATE(); 8199 if (stp != NULL) 8200 return (1); 8201 return (0); 8202 } 8203 8204 /* 8205 * Look for a matching clientid in the vector. Return 1 if one might match. 8206 */ 8207 static int 8208 nfsrv_fndclid(nfsquad_t *clidvec, nfsquad_t clid, int clidcnt) 8209 { 8210 int i; 8211 8212 /* If too many for the vector, return 1 since there might be a match. */ 8213 if (clidcnt > NFSCLIDVECSIZE) 8214 return (1); 8215 8216 for (i = 0; i < clidcnt; i++) 8217 if (clidvec[i].qval == clid.qval) 8218 return (1); 8219 return (0); 8220 } 8221 8222 /* 8223 * Check the don't list for "vp" and see if issuing an rw layout is allowed. 8224 * Return 1 if issuing an rw layout isn't allowed, 0 otherwise. 8225 */ 8226 static int 8227 nfsrv_dontlayout(fhandle_t *fhp) 8228 { 8229 struct nfsdontlist *mrp; 8230 int ret; 8231 8232 if (nfsrv_dontlistlen == 0) 8233 return (0); 8234 ret = 0; 8235 NFSDDONTLISTLOCK(); 8236 LIST_FOREACH(mrp, &nfsrv_dontlisthead, nfsmr_list) { 8237 if (NFSBCMP(fhp, &mrp->nfsmr_fh, sizeof(*fhp)) == 0 && 8238 (mrp->nfsmr_flags & NFSMR_DONTLAYOUT) != 0) { 8239 ret = 1; 8240 break; 8241 } 8242 } 8243 NFSDDONTLISTUNLOCK(); 8244 return (ret); 8245 } 8246 8247 #define PNFSDS_COPYSIZ 65536 8248 /* 8249 * Create a new file on a DS and copy the contents of an extant DS file to it. 8250 * This can be used for recovery of a DS file onto a recovered DS. 8251 * The steps are: 8252 * - When called, the MDS file's vnode is locked, blocking LayoutGet operations. 8253 * - Disable issuing of read/write layouts for the file via the nfsdontlist, 8254 * so that they will be disabled after the MDS file's vnode is unlocked. 8255 * - Set up the nfsrv_recalllist so that recall of read/write layouts can 8256 * be done. 8257 * - Unlock the MDS file's vnode, so that the client(s) can perform proxied 8258 * writes, LayoutCommits and LayoutReturns for the file when completing the 8259 * LayoutReturn requested by the LayoutRecall callback. 8260 * - Issue a LayoutRecall callback for all read/write layouts and wait for 8261 * them to be returned. (If the LayoutRecall callback replies 8262 * NFSERR_NOMATCHLAYOUT, they are gone and no LayoutReturn is needed.) 8263 * - Exclusively lock the MDS file's vnode. This ensures that no proxied 8264 * writes are in progress or can occur during the DS file copy. 8265 * It also blocks Setattr operations. 8266 * - Create the file on the recovered mirror. 8267 * - Copy the file from the operational DS. 8268 * - Copy any ACL from the MDS file to the new DS file. 8269 * - Set the modify time of the new DS file to that of the MDS file. 8270 * - Update the extended attribute for the MDS file. 8271 * - Enable issuing of rw layouts by deleting the nfsdontlist entry. 8272 * - The caller will unlock the MDS file's vnode allowing operations 8273 * to continue normally, since it is now on the mirror again. 8274 */ 8275 int 8276 nfsrv_copymr(vnode_t vp, vnode_t fvp, vnode_t dvp, struct nfsdevice *ds, 8277 struct pnfsdsfile *pf, struct pnfsdsfile *wpf, int mirrorcnt, 8278 struct ucred *cred, NFSPROC_T *p) 8279 { 8280 struct nfsdontlist *mrp, *nmrp; 8281 struct nfslayouthash *lhyp; 8282 struct nfslayout *lyp, *nlyp; 8283 struct nfslayouthead thl; 8284 struct mount *mp, *tvmp; 8285 struct acl *aclp; 8286 struct vattr va; 8287 struct timespec mtime; 8288 fhandle_t fh; 8289 vnode_t tvp; 8290 off_t rdpos, wrpos; 8291 ssize_t aresid; 8292 char *dat; 8293 int didprintf, ret, retacl, xfer; 8294 8295 ASSERT_VOP_LOCKED(fvp, "nfsrv_copymr fvp"); 8296 ASSERT_VOP_LOCKED(vp, "nfsrv_copymr vp"); 8297 /* 8298 * Allocate a nfsdontlist entry and set the NFSMR_DONTLAYOUT flag 8299 * so that no more RW layouts will get issued. 8300 */ 8301 ret = nfsvno_getfh(vp, &fh, p); 8302 if (ret != 0) { 8303 NFSD_DEBUG(4, "nfsrv_copymr: getfh=%d\n", ret); 8304 return (ret); 8305 } 8306 nmrp = malloc(sizeof(*nmrp), M_NFSDSTATE, M_WAITOK); 8307 nmrp->nfsmr_flags = NFSMR_DONTLAYOUT; 8308 NFSBCOPY(&fh, &nmrp->nfsmr_fh, sizeof(fh)); 8309 NFSDDONTLISTLOCK(); 8310 LIST_FOREACH(mrp, &nfsrv_dontlisthead, nfsmr_list) { 8311 if (NFSBCMP(&fh, &mrp->nfsmr_fh, sizeof(fh)) == 0) 8312 break; 8313 } 8314 if (mrp == NULL) { 8315 LIST_INSERT_HEAD(&nfsrv_dontlisthead, nmrp, nfsmr_list); 8316 mrp = nmrp; 8317 nmrp = NULL; 8318 nfsrv_dontlistlen++; 8319 NFSD_DEBUG(4, "nfsrv_copymr: in dontlist\n"); 8320 } else { 8321 NFSDDONTLISTUNLOCK(); 8322 free(nmrp, M_NFSDSTATE); 8323 NFSD_DEBUG(4, "nfsrv_copymr: dup dontlist\n"); 8324 return (ENXIO); 8325 } 8326 NFSDDONTLISTUNLOCK(); 8327 8328 /* 8329 * Search for all RW layouts for this file. Move them to the 8330 * recall list, so they can be recalled and their return noted. 8331 */ 8332 lhyp = NFSLAYOUTHASH(&fh); 8333 NFSDRECALLLOCK(); 8334 NFSLOCKLAYOUT(lhyp); 8335 TAILQ_FOREACH_SAFE(lyp, &lhyp->list, lay_list, nlyp) { 8336 if (NFSBCMP(&lyp->lay_fh, &fh, sizeof(fh)) == 0 && 8337 (lyp->lay_flags & NFSLAY_RW) != 0) { 8338 TAILQ_REMOVE(&lhyp->list, lyp, lay_list); 8339 TAILQ_INSERT_HEAD(&nfsrv_recalllisthead, lyp, lay_list); 8340 lyp->lay_trycnt = 0; 8341 } 8342 } 8343 NFSUNLOCKLAYOUT(lhyp); 8344 NFSDRECALLUNLOCK(); 8345 8346 ret = 0; 8347 mp = tvmp = NULL; 8348 didprintf = 0; 8349 TAILQ_INIT(&thl); 8350 /* Unlock the MDS vp, so that a LayoutReturn can be done on it. */ 8351 NFSVOPUNLOCK(vp); 8352 /* Now, do a recall for all layouts not yet recalled. */ 8353 tryagain: 8354 NFSDRECALLLOCK(); 8355 TAILQ_FOREACH(lyp, &nfsrv_recalllisthead, lay_list) { 8356 if (NFSBCMP(&lyp->lay_fh, &fh, sizeof(fh)) == 0 && 8357 (lyp->lay_flags & NFSLAY_RECALL) == 0) { 8358 lyp->lay_flags |= NFSLAY_RECALL; 8359 /* 8360 * The layout stateid.seqid needs to be incremented 8361 * before doing a LAYOUT_RECALL callback. 8362 */ 8363 if (++lyp->lay_stateid.seqid == 0) 8364 lyp->lay_stateid.seqid = 1; 8365 NFSDRECALLUNLOCK(); 8366 nfsrv_recalllayout(lyp->lay_clientid, &lyp->lay_stateid, 8367 &lyp->lay_fh, lyp, 0, lyp->lay_type, p); 8368 NFSD_DEBUG(4, "nfsrv_copymr: recalled layout\n"); 8369 goto tryagain; 8370 } 8371 } 8372 8373 /* Now wait for them to be returned. */ 8374 tryagain2: 8375 TAILQ_FOREACH(lyp, &nfsrv_recalllisthead, lay_list) { 8376 if (NFSBCMP(&lyp->lay_fh, &fh, sizeof(fh)) == 0) { 8377 if ((lyp->lay_flags & NFSLAY_RETURNED) != 0) { 8378 TAILQ_REMOVE(&nfsrv_recalllisthead, lyp, 8379 lay_list); 8380 TAILQ_INSERT_HEAD(&thl, lyp, lay_list); 8381 NFSD_DEBUG(4, 8382 "nfsrv_copymr: layout returned\n"); 8383 } else { 8384 lyp->lay_trycnt++; 8385 ret = mtx_sleep(lyp, NFSDRECALLMUTEXPTR, 8386 PVFS | PCATCH, "nfsmrl", hz); 8387 NFSD_DEBUG(4, "nfsrv_copymr: aft sleep=%d\n", 8388 ret); 8389 if (ret == EINTR || ret == ERESTART) 8390 break; 8391 if ((lyp->lay_flags & NFSLAY_RETURNED) == 0) { 8392 /* 8393 * Give up after 60sec and return 8394 * ENXIO, failing the copymr. 8395 * This layout will remain on the 8396 * recalllist. It can only be cleared 8397 * by restarting the nfsd. 8398 * This seems the safe way to handle 8399 * it, since it cannot be safely copied 8400 * with an outstanding RW layout. 8401 */ 8402 if (lyp->lay_trycnt >= 60) { 8403 ret = ENXIO; 8404 break; 8405 } 8406 if (didprintf == 0) { 8407 printf("nfsrv_copymr: layout " 8408 "not returned\n"); 8409 didprintf = 1; 8410 } 8411 } 8412 } 8413 goto tryagain2; 8414 } 8415 } 8416 NFSDRECALLUNLOCK(); 8417 /* We can now get rid of the layouts that have been returned. */ 8418 TAILQ_FOREACH_SAFE(lyp, &thl, lay_list, nlyp) 8419 nfsrv_freelayout(&thl, lyp); 8420 8421 /* 8422 * Do the vn_start_write() calls here, before the MDS vnode is 8423 * locked and the tvp is created (locked) in the NFS file system 8424 * that dvp is in. 8425 * For tvmp, this probably isn't necessary, since it will be an 8426 * NFS mount and they are not suspendable at this time. 8427 */ 8428 if (ret == 0) 8429 ret = vn_start_write(vp, &mp, V_WAIT | PCATCH); 8430 if (ret == 0) { 8431 tvmp = dvp->v_mount; 8432 ret = vn_start_write(NULL, &tvmp, V_WAIT | PCATCH); 8433 } 8434 8435 /* 8436 * LK_EXCLUSIVE lock the MDS vnode, so that any 8437 * proxied writes through the MDS will be blocked until we have 8438 * completed the copy and update of the extended attributes. 8439 * This will also ensure that any attributes and ACL will not be 8440 * changed until the copy is complete. 8441 */ 8442 NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); 8443 if (ret == 0 && VN_IS_DOOMED(vp)) { 8444 NFSD_DEBUG(4, "nfsrv_copymr: lk_exclusive doomed\n"); 8445 ret = ESTALE; 8446 } 8447 8448 /* Create the data file on the recovered DS. */ 8449 if (ret == 0) 8450 ret = nfsrv_createdsfile(vp, &fh, pf, dvp, ds, cred, p, &tvp); 8451 8452 /* Copy the DS file, if created successfully. */ 8453 if (ret == 0) { 8454 /* 8455 * Get any NFSv4 ACL on the MDS file, so that it can be set 8456 * on the new DS file. 8457 */ 8458 aclp = acl_alloc(M_WAITOK | M_ZERO); 8459 retacl = VOP_GETACL(vp, ACL_TYPE_NFS4, aclp, cred, p); 8460 if (retacl != 0 && retacl != ENOATTR) 8461 NFSD_DEBUG(1, "nfsrv_copymr: vop_getacl=%d\n", retacl); 8462 dat = malloc(PNFSDS_COPYSIZ, M_TEMP, M_WAITOK); 8463 /* Malloc a block of 0s used to check for holes. */ 8464 if (nfsrv_zeropnfsdat == NULL) 8465 nfsrv_zeropnfsdat = malloc(PNFSDS_COPYSIZ, M_TEMP, 8466 M_WAITOK | M_ZERO); 8467 rdpos = wrpos = 0; 8468 ret = VOP_GETATTR(fvp, &va, cred); 8469 aresid = 0; 8470 while (ret == 0 && aresid == 0) { 8471 ret = vn_rdwr(UIO_READ, fvp, dat, PNFSDS_COPYSIZ, 8472 rdpos, UIO_SYSSPACE, IO_NODELOCKED, cred, NULL, 8473 &aresid, p); 8474 xfer = PNFSDS_COPYSIZ - aresid; 8475 if (ret == 0 && xfer > 0) { 8476 rdpos += xfer; 8477 /* 8478 * Skip the write for holes, except for the 8479 * last block. 8480 */ 8481 if (xfer < PNFSDS_COPYSIZ || rdpos == 8482 va.va_size || NFSBCMP(dat, 8483 nfsrv_zeropnfsdat, PNFSDS_COPYSIZ) != 0) 8484 ret = vn_rdwr(UIO_WRITE, tvp, dat, xfer, 8485 wrpos, UIO_SYSSPACE, IO_NODELOCKED, 8486 cred, NULL, NULL, p); 8487 if (ret == 0) 8488 wrpos += xfer; 8489 } 8490 } 8491 8492 /* If there is an ACL and the copy succeeded, set the ACL. */ 8493 if (ret == 0 && retacl == 0) { 8494 ret = VOP_SETACL(tvp, ACL_TYPE_NFS4, aclp, cred, p); 8495 /* 8496 * Don't consider these as errors, since VOP_GETACL() 8497 * can return an ACL when they are not actually 8498 * supported. For example, for UFS, VOP_GETACL() 8499 * will return a trivial ACL based on the uid/gid/mode 8500 * when there is no ACL on the file. 8501 * This case should be recognized as a trivial ACL 8502 * by UFS's VOP_SETACL() and succeed, but... 8503 */ 8504 if (ret == ENOATTR || ret == EOPNOTSUPP || ret == EPERM) 8505 ret = 0; 8506 } 8507 8508 if (ret == 0) 8509 ret = VOP_FSYNC(tvp, MNT_WAIT, p); 8510 8511 /* Set the DS data file's modify time that of the MDS file. */ 8512 if (ret == 0) 8513 ret = VOP_GETATTR(vp, &va, cred); 8514 if (ret == 0) { 8515 mtime = va.va_mtime; 8516 VATTR_NULL(&va); 8517 va.va_mtime = mtime; 8518 ret = VOP_SETATTR(tvp, &va, cred); 8519 } 8520 8521 vput(tvp); 8522 acl_free(aclp); 8523 free(dat, M_TEMP); 8524 } 8525 if (tvmp != NULL) 8526 vn_finished_write(tvmp); 8527 8528 /* Update the extended attributes for the newly created DS file. */ 8529 if (ret == 0) 8530 ret = vn_extattr_set(vp, IO_NODELOCKED, 8531 EXTATTR_NAMESPACE_SYSTEM, "pnfsd.dsfile", 8532 sizeof(*wpf) * mirrorcnt, (char *)wpf, p); 8533 if (mp != NULL) 8534 vn_finished_write(mp); 8535 8536 /* Get rid of the dontlist entry, so that Layouts can be issued. */ 8537 NFSDDONTLISTLOCK(); 8538 LIST_REMOVE(mrp, nfsmr_list); 8539 NFSDDONTLISTUNLOCK(); 8540 free(mrp, M_NFSDSTATE); 8541 return (ret); 8542 } 8543 8544 /* 8545 * Create a data storage file on the recovered DS. 8546 */ 8547 static int 8548 nfsrv_createdsfile(vnode_t vp, fhandle_t *fhp, struct pnfsdsfile *pf, 8549 vnode_t dvp, struct nfsdevice *ds, struct ucred *cred, NFSPROC_T *p, 8550 vnode_t *tvpp) 8551 { 8552 struct vattr va, nva; 8553 int error; 8554 8555 /* Make data file name based on FH. */ 8556 error = VOP_GETATTR(vp, &va, cred); 8557 if (error == 0) { 8558 /* Set the attributes for "vp" to Setattr the DS vp. */ 8559 VATTR_NULL(&nva); 8560 nva.va_uid = va.va_uid; 8561 nva.va_gid = va.va_gid; 8562 nva.va_mode = va.va_mode; 8563 nva.va_size = 0; 8564 VATTR_NULL(&va); 8565 va.va_type = VREG; 8566 va.va_mode = nva.va_mode; 8567 NFSD_DEBUG(4, "nfsrv_dscreatefile: dvp=%p pf=%p\n", dvp, pf); 8568 error = nfsrv_dscreate(dvp, &va, &nva, fhp, pf, NULL, 8569 pf->dsf_filename, cred, p, tvpp); 8570 } 8571 return (error); 8572 } 8573 8574 /* 8575 * Look up the MDS file shared locked, and then get the extended attribute 8576 * to find the extant DS file to be copied to the new mirror. 8577 * If successful, *vpp is set to the MDS file's vp and *nvpp is 8578 * set to a DS data file for the MDS file, both exclusively locked. 8579 * The "buf" argument has the pnfsdsfile structure from the MDS file 8580 * in it and buflen is set to its length. 8581 */ 8582 int 8583 nfsrv_mdscopymr(char *mdspathp, char *dspathp, char *curdspathp, char *buf, 8584 int *buflenp, char *fname, NFSPROC_T *p, struct vnode **vpp, 8585 struct vnode **nvpp, struct pnfsdsfile **pfp, struct nfsdevice **dsp, 8586 struct nfsdevice **fdsp) 8587 { 8588 struct nameidata nd; 8589 struct vnode *vp, *curvp; 8590 struct pnfsdsfile *pf; 8591 struct nfsmount *nmp, *curnmp; 8592 int dsdir, error, mirrorcnt, ippos; 8593 8594 vp = NULL; 8595 curvp = NULL; 8596 curnmp = NULL; 8597 *dsp = NULL; 8598 *fdsp = NULL; 8599 if (dspathp == NULL && curdspathp != NULL) 8600 return (EPERM); 8601 8602 /* 8603 * Look up the MDS file shared locked. The lock will be upgraded 8604 * to an exclusive lock after any rw layouts have been returned. 8605 */ 8606 NFSD_DEBUG(4, "mdsopen path=%s\n", mdspathp); 8607 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF, UIO_SYSSPACE, 8608 mdspathp); 8609 error = namei(&nd); 8610 NFSD_DEBUG(4, "lookup=%d\n", error); 8611 if (error != 0) 8612 return (error); 8613 if (nd.ni_vp->v_type != VREG) { 8614 vput(nd.ni_vp); 8615 NFSD_DEBUG(4, "mdspath not reg\n"); 8616 return (EISDIR); 8617 } 8618 vp = nd.ni_vp; 8619 8620 if (curdspathp != NULL) { 8621 /* 8622 * Look up the current DS path and find the nfsdev structure for 8623 * it. 8624 */ 8625 NFSD_DEBUG(4, "curmdsdev path=%s\n", curdspathp); 8626 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF, 8627 UIO_SYSSPACE, curdspathp); 8628 error = namei(&nd); 8629 NFSD_DEBUG(4, "ds lookup=%d\n", error); 8630 if (error != 0) { 8631 vput(vp); 8632 return (error); 8633 } 8634 if (nd.ni_vp->v_type != VDIR) { 8635 vput(nd.ni_vp); 8636 vput(vp); 8637 NFSD_DEBUG(4, "curdspath not dir\n"); 8638 return (ENOTDIR); 8639 } 8640 if (strcmp(nd.ni_vp->v_mount->mnt_vfc->vfc_name, "nfs") != 0) { 8641 vput(nd.ni_vp); 8642 vput(vp); 8643 NFSD_DEBUG(4, "curdspath not an NFS mount\n"); 8644 return (ENXIO); 8645 } 8646 curnmp = VFSTONFS(nd.ni_vp->v_mount); 8647 8648 /* Search the nfsdev list for a match. */ 8649 NFSDDSLOCK(); 8650 *fdsp = nfsv4_findmirror(curnmp); 8651 NFSDDSUNLOCK(); 8652 if (*fdsp == NULL) 8653 curnmp = NULL; 8654 if (curnmp == NULL) { 8655 vput(nd.ni_vp); 8656 vput(vp); 8657 NFSD_DEBUG(4, "mdscopymr: no current ds\n"); 8658 return (ENXIO); 8659 } 8660 curvp = nd.ni_vp; 8661 } 8662 8663 if (dspathp != NULL) { 8664 /* Look up the nfsdev path and find the nfsdev structure. */ 8665 NFSD_DEBUG(4, "mdsdev path=%s\n", dspathp); 8666 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF, 8667 UIO_SYSSPACE, dspathp); 8668 error = namei(&nd); 8669 NFSD_DEBUG(4, "ds lookup=%d\n", error); 8670 if (error != 0) { 8671 vput(vp); 8672 if (curvp != NULL) 8673 vput(curvp); 8674 return (error); 8675 } 8676 if (nd.ni_vp->v_type != VDIR || nd.ni_vp == curvp) { 8677 vput(nd.ni_vp); 8678 vput(vp); 8679 if (curvp != NULL) 8680 vput(curvp); 8681 NFSD_DEBUG(4, "dspath not dir\n"); 8682 if (nd.ni_vp == curvp) 8683 return (EPERM); 8684 return (ENOTDIR); 8685 } 8686 if (strcmp(nd.ni_vp->v_mount->mnt_vfc->vfc_name, "nfs") != 0) { 8687 vput(nd.ni_vp); 8688 vput(vp); 8689 if (curvp != NULL) 8690 vput(curvp); 8691 NFSD_DEBUG(4, "dspath not an NFS mount\n"); 8692 return (ENXIO); 8693 } 8694 nmp = VFSTONFS(nd.ni_vp->v_mount); 8695 8696 /* 8697 * Search the nfsdevice list for a match. If curnmp == NULL, 8698 * this is a recovery and there must be a mirror. 8699 */ 8700 NFSDDSLOCK(); 8701 if (curnmp == NULL) 8702 *dsp = nfsrv_findmirroredds(nmp); 8703 else 8704 *dsp = nfsv4_findmirror(nmp); 8705 NFSDDSUNLOCK(); 8706 if (*dsp == NULL) { 8707 vput(nd.ni_vp); 8708 vput(vp); 8709 if (curvp != NULL) 8710 vput(curvp); 8711 NFSD_DEBUG(4, "mdscopymr: no ds\n"); 8712 return (ENXIO); 8713 } 8714 } else { 8715 nd.ni_vp = NULL; 8716 nmp = NULL; 8717 } 8718 8719 /* 8720 * Get a vp for an available DS data file using the extended 8721 * attribute on the MDS file. 8722 * If there is a valid entry for the new DS in the extended attribute 8723 * on the MDS file (as checked via the nmp argument), 8724 * nfsrv_dsgetsockmnt() returns EEXIST, so no copying will occur. 8725 */ 8726 error = nfsrv_dsgetsockmnt(vp, 0, buf, buflenp, &mirrorcnt, p, 8727 NULL, NULL, NULL, fname, nvpp, &nmp, curnmp, &ippos, &dsdir); 8728 if (curvp != NULL) 8729 vput(curvp); 8730 if (nd.ni_vp == NULL) { 8731 if (error == 0 && nmp != NULL) { 8732 /* Search the nfsdev list for a match. */ 8733 NFSDDSLOCK(); 8734 *dsp = nfsrv_findmirroredds(nmp); 8735 NFSDDSUNLOCK(); 8736 } 8737 if (error == 0 && (nmp == NULL || *dsp == NULL)) { 8738 if (nvpp != NULL && *nvpp != NULL) { 8739 vput(*nvpp); 8740 *nvpp = NULL; 8741 } 8742 error = ENXIO; 8743 } 8744 } else 8745 vput(nd.ni_vp); 8746 8747 /* 8748 * When dspathp != NULL and curdspathp == NULL, this is a recovery 8749 * and is only allowed if there is a 0.0.0.0 IP address entry. 8750 * When curdspathp != NULL, the ippos will be set to that entry. 8751 */ 8752 if (error == 0 && dspathp != NULL && ippos == -1) { 8753 if (nvpp != NULL && *nvpp != NULL) { 8754 vput(*nvpp); 8755 *nvpp = NULL; 8756 } 8757 error = ENXIO; 8758 } 8759 if (error == 0) { 8760 *vpp = vp; 8761 8762 pf = (struct pnfsdsfile *)buf; 8763 if (ippos == -1) { 8764 /* If no zeroip pnfsdsfile, add one. */ 8765 ippos = *buflenp / sizeof(*pf); 8766 *buflenp += sizeof(*pf); 8767 pf += ippos; 8768 pf->dsf_dir = dsdir; 8769 strlcpy(pf->dsf_filename, fname, 8770 sizeof(pf->dsf_filename)); 8771 } else 8772 pf += ippos; 8773 *pfp = pf; 8774 } else 8775 vput(vp); 8776 return (error); 8777 } 8778 8779 /* 8780 * Search for a matching pnfsd mirror device structure, base on the nmp arg. 8781 * Return one if found, NULL otherwise. 8782 */ 8783 static struct nfsdevice * 8784 nfsrv_findmirroredds(struct nfsmount *nmp) 8785 { 8786 struct nfsdevice *ds, *fndds; 8787 int fndmirror; 8788 8789 mtx_assert(NFSDDSMUTEXPTR, MA_OWNED); 8790 /* 8791 * Search the DS server list for a match with nmp. 8792 * Remove the DS entry if found and there is a mirror. 8793 */ 8794 fndds = NULL; 8795 fndmirror = 0; 8796 if (nfsrv_devidcnt == 0) 8797 return (fndds); 8798 TAILQ_FOREACH(ds, &nfsrv_devidhead, nfsdev_list) { 8799 if (ds->nfsdev_nmp == nmp) { 8800 NFSD_DEBUG(4, "nfsrv_findmirroredds: fnd main ds\n"); 8801 fndds = ds; 8802 break; 8803 } 8804 } 8805 if (fndds == NULL) 8806 return (fndds); 8807 if (fndds->nfsdev_mdsisset == 0 && nfsrv_faildscnt > 0) 8808 fndmirror = 1; 8809 else if (fndds->nfsdev_mdsisset != 0) { 8810 /* For the fsid is set case, search for a mirror. */ 8811 TAILQ_FOREACH(ds, &nfsrv_devidhead, nfsdev_list) { 8812 if (ds != fndds && ds->nfsdev_nmp != NULL && 8813 ds->nfsdev_mdsisset != 0 && 8814 fsidcmp(&ds->nfsdev_mdsfsid, 8815 &fndds->nfsdev_mdsfsid) == 0) { 8816 fndmirror = 1; 8817 break; 8818 } 8819 } 8820 } 8821 if (fndmirror == 0) { 8822 NFSD_DEBUG(4, "nfsrv_findmirroredds: no mirror for DS\n"); 8823 return (NULL); 8824 } 8825 return (fndds); 8826 } 8827 8828 /* 8829 * Mark the appropriate devid and all associated layout as "out of space". 8830 */ 8831 void 8832 nfsrv_marknospc(char *devid, bool setit) 8833 { 8834 struct nfsdevice *ds; 8835 struct nfslayout *lyp; 8836 struct nfslayouthash *lhyp; 8837 int i; 8838 8839 NFSDDSLOCK(); 8840 TAILQ_FOREACH(ds, &nfsrv_devidhead, nfsdev_list) { 8841 if (NFSBCMP(ds->nfsdev_deviceid, devid, NFSX_V4DEVICEID) == 0) { 8842 NFSD_DEBUG(1, "nfsrv_marknospc: devid %d\n", setit); 8843 ds->nfsdev_nospc = setit; 8844 } 8845 } 8846 NFSDDSUNLOCK(); 8847 8848 for (i = 0; i < nfsrv_layouthashsize; i++) { 8849 lhyp = &nfslayouthash[i]; 8850 NFSLOCKLAYOUT(lhyp); 8851 TAILQ_FOREACH(lyp, &lhyp->list, lay_list) { 8852 if (NFSBCMP(lyp->lay_deviceid, devid, 8853 NFSX_V4DEVICEID) == 0) { 8854 NFSD_DEBUG(1, "nfsrv_marknospc: layout %d\n", 8855 setit); 8856 if (setit) 8857 lyp->lay_flags |= NFSLAY_NOSPC; 8858 else 8859 lyp->lay_flags &= ~NFSLAY_NOSPC; 8860 } 8861 } 8862 NFSUNLOCKLAYOUT(lhyp); 8863 } 8864 } 8865