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