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