xref: /illumos-gate/usr/src/uts/common/fs/nfs/nfs_subr.c (revision f5654033)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
28  */
29 
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/systm.h>
33 #include <sys/cred.h>
34 #include <sys/proc.h>
35 #include <sys/user.h>
36 #include <sys/time.h>
37 #include <sys/buf.h>
38 #include <sys/vfs.h>
39 #include <sys/vnode.h>
40 #include <sys/socket.h>
41 #include <sys/uio.h>
42 #include <sys/tiuser.h>
43 #include <sys/swap.h>
44 #include <sys/errno.h>
45 #include <sys/debug.h>
46 #include <sys/kmem.h>
47 #include <sys/kstat.h>
48 #include <sys/cmn_err.h>
49 #include <sys/vtrace.h>
50 #include <sys/session.h>
51 #include <sys/dnlc.h>
52 #include <sys/bitmap.h>
53 #include <sys/acl.h>
54 #include <sys/ddi.h>
55 #include <sys/pathname.h>
56 #include <sys/flock.h>
57 #include <sys/dirent.h>
58 #include <sys/flock.h>
59 #include <sys/callb.h>
60 #include <sys/atomic.h>
61 #include <sys/list.h>
62 #include <sys/tsol/tnet.h>
63 #include <sys/priv.h>
64 #include <sys/sdt.h>
65 #include <sys/attr.h>
66 
67 #include <inet/ip6.h>
68 
69 #include <rpc/types.h>
70 #include <rpc/xdr.h>
71 #include <rpc/auth.h>
72 #include <rpc/clnt.h>
73 
74 #include <nfs/nfs.h>
75 #include <nfs/nfs4.h>
76 #include <nfs/nfs_clnt.h>
77 #include <nfs/rnode.h>
78 #include <nfs/nfs_acl.h>
79 
80 #include <sys/tsol/label.h>
81 
82 /*
83  * The hash queues for the access to active and cached rnodes
84  * are organized as doubly linked lists.  A reader/writer lock
85  * for each hash bucket is used to control access and to synchronize
86  * lookups, additions, and deletions from the hash queue.
87  *
88  * The rnode freelist is organized as a doubly linked list with
89  * a head pointer.  Additions and deletions are synchronized via
90  * a single mutex.
91  *
92  * In order to add an rnode to the free list, it must be hashed into
93  * a hash queue and the exclusive lock to the hash queue be held.
94  * If an rnode is not hashed into a hash queue, then it is destroyed
95  * because it represents no valuable information that can be reused
96  * about the file.  The exclusive lock to the hash queue must be
97  * held in order to prevent a lookup in the hash queue from finding
98  * the rnode and using it and assuming that the rnode is not on the
99  * freelist.  The lookup in the hash queue will have the hash queue
100  * locked, either exclusive or shared.
101  *
102  * The vnode reference count for each rnode is not allowed to drop
103  * below 1.  This prevents external entities, such as the VM
104  * subsystem, from acquiring references to vnodes already on the
105  * freelist and then trying to place them back on the freelist
106  * when their reference is released.  This means that the when an
107  * rnode is looked up in the hash queues, then either the rnode
108  * is removed from the freelist and that reference is transferred to
109  * the new reference or the vnode reference count must be incremented
110  * accordingly.  The mutex for the freelist must be held in order to
111  * accurately test to see if the rnode is on the freelist or not.
112  * The hash queue lock might be held shared and it is possible that
113  * two different threads may race to remove the rnode from the
114  * freelist.  This race can be resolved by holding the mutex for the
115  * freelist.  Please note that the mutex for the freelist does not
116  * need to held if the rnode is not on the freelist.  It can not be
117  * placed on the freelist due to the requirement that the thread
118  * putting the rnode on the freelist must hold the exclusive lock
119  * to the hash queue and the thread doing the lookup in the hash
120  * queue is holding either a shared or exclusive lock to the hash
121  * queue.
122  *
123  * The lock ordering is:
124  *
125  *	hash bucket lock -> vnode lock
126  *	hash bucket lock -> freelist lock
127  */
128 static rhashq_t *rtable;
129 
130 static kmutex_t rpfreelist_lock;
131 static rnode_t *rpfreelist = NULL;
132 static long rnew = 0;
133 long nrnode = 0;
134 
135 static int rtablesize;
136 static int rtablemask;
137 
138 static int hashlen = 4;
139 
140 static struct kmem_cache *rnode_cache;
141 
142 /*
143  * Mutex to protect the following variables:
144  *	nfs_major
145  *	nfs_minor
146  */
147 kmutex_t nfs_minor_lock;
148 int nfs_major;
149 int nfs_minor;
150 
151 /* Do we allow preepoch (negative) time values otw? */
152 bool_t nfs_allow_preepoch_time = FALSE;	/* default: do not allow preepoch */
153 
154 /*
155  * Access cache
156  */
157 static acache_hash_t *acache;
158 static long nacache;	/* used strictly to size the number of hash queues */
159 
160 static int acachesize;
161 static int acachemask;
162 static struct kmem_cache *acache_cache;
163 
164 /*
165  * Client side utilities
166  */
167 
168 /*
169  * client side statistics
170  */
171 static const struct clstat clstat_tmpl = {
172 	{ "calls",	KSTAT_DATA_UINT64 },
173 	{ "badcalls",	KSTAT_DATA_UINT64 },
174 	{ "clgets",	KSTAT_DATA_UINT64 },
175 	{ "cltoomany",	KSTAT_DATA_UINT64 },
176 #ifdef DEBUG
177 	{ "clalloc",	KSTAT_DATA_UINT64 },
178 	{ "noresponse",	KSTAT_DATA_UINT64 },
179 	{ "failover",	KSTAT_DATA_UINT64 },
180 	{ "remap",	KSTAT_DATA_UINT64 },
181 #endif
182 };
183 
184 /*
185  * The following are statistics that describe behavior of the system as a whole
186  * and doesn't correspond to any one particular zone.
187  */
188 #ifdef DEBUG
189 static struct clstat_debug {
190 	kstat_named_t	nrnode;			/* number of allocated rnodes */
191 	kstat_named_t	access;			/* size of access cache */
192 	kstat_named_t	dirent;			/* size of readdir cache */
193 	kstat_named_t	dirents;		/* size of readdir buf cache */
194 	kstat_named_t	reclaim;		/* number of reclaims */
195 	kstat_named_t	clreclaim;		/* number of cl reclaims */
196 	kstat_named_t	f_reclaim;		/* number of free reclaims */
197 	kstat_named_t	a_reclaim;		/* number of active reclaims */
198 	kstat_named_t	r_reclaim;		/* number of rnode reclaims */
199 	kstat_named_t	rpath;			/* bytes used to store rpaths */
200 } clstat_debug = {
201 	{ "nrnode",	KSTAT_DATA_UINT64 },
202 	{ "access",	KSTAT_DATA_UINT64 },
203 	{ "dirent",	KSTAT_DATA_UINT64 },
204 	{ "dirents",	KSTAT_DATA_UINT64 },
205 	{ "reclaim",	KSTAT_DATA_UINT64 },
206 	{ "clreclaim",	KSTAT_DATA_UINT64 },
207 	{ "f_reclaim",	KSTAT_DATA_UINT64 },
208 	{ "a_reclaim",	KSTAT_DATA_UINT64 },
209 	{ "r_reclaim",	KSTAT_DATA_UINT64 },
210 	{ "r_path",	KSTAT_DATA_UINT64 },
211 };
212 #endif	/* DEBUG */
213 
214 /*
215  * We keep a global list of per-zone client data, so we can clean up all zones
216  * if we get low on memory.
217  */
218 static list_t nfs_clnt_list;
219 static kmutex_t nfs_clnt_list_lock;
220 static zone_key_t nfsclnt_zone_key;
221 
222 static struct kmem_cache *chtab_cache;
223 
224 /*
225  * Some servers do not properly update the attributes of the
226  * directory when changes are made.  To allow interoperability
227  * with these broken servers, the nfs_disable_rddir_cache
228  * parameter must be set in /etc/system
229  */
230 int nfs_disable_rddir_cache = 0;
231 
232 int		clget(clinfo_t *, servinfo_t *, cred_t *, CLIENT **,
233 		    struct chtab **);
234 void		clfree(CLIENT *, struct chtab *);
235 static int	acl_clget(mntinfo_t *, servinfo_t *, cred_t *, CLIENT **,
236 		    struct chtab **, struct nfs_clnt *);
237 static int	nfs_clget(mntinfo_t *, servinfo_t *, cred_t *, CLIENT **,
238 		    struct chtab **, struct nfs_clnt *);
239 static void	clreclaim(void *);
240 static int	nfs_feedback(int, int, mntinfo_t *);
241 static int	rfscall(mntinfo_t *, rpcproc_t, xdrproc_t, caddr_t, xdrproc_t,
242 		    caddr_t, cred_t *, int *, enum clnt_stat *, int,
243 		    failinfo_t *);
244 static int	aclcall(mntinfo_t *, rpcproc_t, xdrproc_t, caddr_t, xdrproc_t,
245 		    caddr_t, cred_t *, int *, int, failinfo_t *);
246 static void	rinactive(rnode_t *, cred_t *);
247 static int	rtablehash(nfs_fhandle *);
248 static vnode_t	*make_rnode(nfs_fhandle *, rhashq_t *, struct vfs *,
249 		    struct vnodeops *,
250 		    int (*)(vnode_t *, page_t *, u_offset_t *, size_t *, int,
251 			cred_t *),
252 		    int (*)(const void *, const void *), int *, cred_t *,
253 		    char *, char *);
254 static void	rp_rmfree(rnode_t *);
255 static void	rp_addhash(rnode_t *);
256 static void	rp_rmhash_locked(rnode_t *);
257 static rnode_t	*rfind(rhashq_t *, nfs_fhandle *, struct vfs *);
258 static void	destroy_rnode(rnode_t *);
259 static void	rddir_cache_free(rddir_cache *);
260 static int	nfs_free_data_reclaim(rnode_t *);
261 static int	nfs_active_data_reclaim(rnode_t *);
262 static int	nfs_free_reclaim(void);
263 static int	nfs_active_reclaim(void);
264 static int	nfs_rnode_reclaim(void);
265 static void	nfs_reclaim(void *);
266 static int	failover_safe(failinfo_t *);
267 static void	failover_newserver(mntinfo_t *mi);
268 static void	failover_thread(mntinfo_t *mi);
269 static int	failover_wait(mntinfo_t *);
270 static int	failover_remap(failinfo_t *);
271 static int	failover_lookup(char *, vnode_t *,
272 		    int (*)(vnode_t *, char *, vnode_t **,
273 			struct pathname *, int, vnode_t *, cred_t *, int),
274 		    int (*)(vnode_t *, vnode_t **, bool_t, cred_t *, int),
275 		    vnode_t **);
276 static void	nfs_free_r_path(rnode_t *);
277 static void	nfs_set_vroot(vnode_t *);
278 static char	*nfs_getsrvnames(mntinfo_t *, size_t *);
279 
280 /*
281  * from rpcsec module (common/rpcsec)
282  */
283 extern int sec_clnt_geth(CLIENT *, struct sec_data *, cred_t *, AUTH **);
284 extern void sec_clnt_freeh(AUTH *);
285 extern void sec_clnt_freeinfo(struct sec_data *);
286 
287 /*
288  * used in mount policy
289  */
290 extern ts_label_t *getflabel_cipso(vfs_t *);
291 
292 /*
293  * EIO or EINTR are not recoverable errors.
294  */
295 #define	IS_RECOVERABLE_ERROR(error)	!((error == EINTR) || (error == EIO))
296 
297 #ifdef DEBUG
298 #define	SRV_QFULL_MSG	"send queue to NFS%d server %s is full; still trying\n"
299 #define	SRV_NOTRESP_MSG	"NFS%d server %s not responding still trying\n"
300 #else
301 #define	SRV_QFULL_MSG	"send queue to NFS server %s is full still trying\n"
302 #define	SRV_NOTRESP_MSG	"NFS server %s not responding still trying\n"
303 #endif
304 /*
305  * Common handle get program for NFS, NFS ACL, and NFS AUTH client.
306  */
307 static int
308 clget_impl(clinfo_t *ci, servinfo_t *svp, cred_t *cr, CLIENT **newcl,
309     struct chtab **chp, struct nfs_clnt *nfscl)
310 {
311 	struct chhead *ch, *newch;
312 	struct chhead **plistp;
313 	struct chtab *cp;
314 	int error;
315 	k_sigset_t smask;
316 
317 	if (newcl == NULL || chp == NULL || ci == NULL)
318 		return (EINVAL);
319 
320 	*newcl = NULL;
321 	*chp = NULL;
322 
323 	/*
324 	 * Find an unused handle or create one
325 	 */
326 	newch = NULL;
327 	nfscl->nfscl_stat.clgets.value.ui64++;
328 top:
329 	/*
330 	 * Find the correct entry in the cache to check for free
331 	 * client handles.  The search is based on the RPC program
332 	 * number, program version number, dev_t for the transport
333 	 * device, and the protocol family.
334 	 */
335 	mutex_enter(&nfscl->nfscl_chtable_lock);
336 	plistp = &nfscl->nfscl_chtable;
337 	for (ch = nfscl->nfscl_chtable; ch != NULL; ch = ch->ch_next) {
338 		if (ch->ch_prog == ci->cl_prog &&
339 		    ch->ch_vers == ci->cl_vers &&
340 		    ch->ch_dev == svp->sv_knconf->knc_rdev &&
341 		    (strcmp(ch->ch_protofmly,
342 		    svp->sv_knconf->knc_protofmly) == 0))
343 			break;
344 		plistp = &ch->ch_next;
345 	}
346 
347 	/*
348 	 * If we didn't find a cache entry for this quadruple, then
349 	 * create one.  If we don't have one already preallocated,
350 	 * then drop the cache lock, create one, and then start over.
351 	 * If we did have a preallocated entry, then just add it to
352 	 * the front of the list.
353 	 */
354 	if (ch == NULL) {
355 		if (newch == NULL) {
356 			mutex_exit(&nfscl->nfscl_chtable_lock);
357 			newch = kmem_alloc(sizeof (*newch), KM_SLEEP);
358 			newch->ch_timesused = 0;
359 			newch->ch_prog = ci->cl_prog;
360 			newch->ch_vers = ci->cl_vers;
361 			newch->ch_dev = svp->sv_knconf->knc_rdev;
362 			newch->ch_protofmly = kmem_alloc(
363 			    strlen(svp->sv_knconf->knc_protofmly) + 1,
364 			    KM_SLEEP);
365 			(void) strcpy(newch->ch_protofmly,
366 			    svp->sv_knconf->knc_protofmly);
367 			newch->ch_list = NULL;
368 			goto top;
369 		}
370 		ch = newch;
371 		newch = NULL;
372 		ch->ch_next = nfscl->nfscl_chtable;
373 		nfscl->nfscl_chtable = ch;
374 	/*
375 	 * We found a cache entry, but if it isn't on the front of the
376 	 * list, then move it to the front of the list to try to take
377 	 * advantage of locality of operations.
378 	 */
379 	} else if (ch != nfscl->nfscl_chtable) {
380 		*plistp = ch->ch_next;
381 		ch->ch_next = nfscl->nfscl_chtable;
382 		nfscl->nfscl_chtable = ch;
383 	}
384 
385 	/*
386 	 * If there was a free client handle cached, then remove it
387 	 * from the list, init it, and use it.
388 	 */
389 	if (ch->ch_list != NULL) {
390 		cp = ch->ch_list;
391 		ch->ch_list = cp->ch_list;
392 		mutex_exit(&nfscl->nfscl_chtable_lock);
393 		if (newch != NULL) {
394 			kmem_free(newch->ch_protofmly,
395 			    strlen(newch->ch_protofmly) + 1);
396 			kmem_free(newch, sizeof (*newch));
397 		}
398 		(void) clnt_tli_kinit(cp->ch_client, svp->sv_knconf,
399 		    &svp->sv_addr, ci->cl_readsize, ci->cl_retrans, cr);
400 		error = sec_clnt_geth(cp->ch_client, svp->sv_secdata, cr,
401 		    &cp->ch_client->cl_auth);
402 		if (error || cp->ch_client->cl_auth == NULL) {
403 			CLNT_DESTROY(cp->ch_client);
404 			kmem_cache_free(chtab_cache, cp);
405 			return ((error != 0) ? error : EINTR);
406 		}
407 		ch->ch_timesused++;
408 		*newcl = cp->ch_client;
409 		*chp = cp;
410 		return (0);
411 	}
412 
413 	/*
414 	 * There weren't any free client handles which fit, so allocate
415 	 * a new one and use that.
416 	 */
417 #ifdef DEBUG
418 	atomic_add_64(&nfscl->nfscl_stat.clalloc.value.ui64, 1);
419 #endif
420 	mutex_exit(&nfscl->nfscl_chtable_lock);
421 
422 	nfscl->nfscl_stat.cltoomany.value.ui64++;
423 	if (newch != NULL) {
424 		kmem_free(newch->ch_protofmly, strlen(newch->ch_protofmly) + 1);
425 		kmem_free(newch, sizeof (*newch));
426 	}
427 
428 	cp = kmem_cache_alloc(chtab_cache, KM_SLEEP);
429 	cp->ch_head = ch;
430 
431 	sigintr(&smask, (int)ci->cl_flags & MI_INT);
432 	error = clnt_tli_kcreate(svp->sv_knconf, &svp->sv_addr, ci->cl_prog,
433 	    ci->cl_vers, ci->cl_readsize, ci->cl_retrans, cr, &cp->ch_client);
434 	sigunintr(&smask);
435 
436 	if (error != 0) {
437 		kmem_cache_free(chtab_cache, cp);
438 #ifdef DEBUG
439 		atomic_add_64(&nfscl->nfscl_stat.clalloc.value.ui64, -1);
440 #endif
441 		/*
442 		 * Warning is unnecessary if error is EINTR.
443 		 */
444 		if (error != EINTR) {
445 			nfs_cmn_err(error, CE_WARN,
446 			    "clget: couldn't create handle: %m\n");
447 		}
448 		return (error);
449 	}
450 	(void) CLNT_CONTROL(cp->ch_client, CLSET_PROGRESS, NULL);
451 	auth_destroy(cp->ch_client->cl_auth);
452 	error = sec_clnt_geth(cp->ch_client, svp->sv_secdata, cr,
453 	    &cp->ch_client->cl_auth);
454 	if (error || cp->ch_client->cl_auth == NULL) {
455 		CLNT_DESTROY(cp->ch_client);
456 		kmem_cache_free(chtab_cache, cp);
457 #ifdef DEBUG
458 		atomic_add_64(&nfscl->nfscl_stat.clalloc.value.ui64, -1);
459 #endif
460 		return ((error != 0) ? error : EINTR);
461 	}
462 	ch->ch_timesused++;
463 	*newcl = cp->ch_client;
464 	ASSERT(cp->ch_client->cl_nosignal == FALSE);
465 	*chp = cp;
466 	return (0);
467 }
468 
469 int
470 clget(clinfo_t *ci, servinfo_t *svp, cred_t *cr, CLIENT **newcl,
471     struct chtab **chp)
472 {
473 	struct nfs_clnt *nfscl;
474 
475 	nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
476 	ASSERT(nfscl != NULL);
477 
478 	return (clget_impl(ci, svp, cr, newcl, chp, nfscl));
479 }
480 
481 static int
482 acl_clget(mntinfo_t *mi, servinfo_t *svp, cred_t *cr, CLIENT **newcl,
483     struct chtab **chp, struct nfs_clnt *nfscl)
484 {
485 	clinfo_t ci;
486 	int error;
487 
488 	/*
489 	 * Set read buffer size to rsize
490 	 * and add room for RPC headers.
491 	 */
492 	ci.cl_readsize = mi->mi_tsize;
493 	if (ci.cl_readsize != 0)
494 		ci.cl_readsize += (RPC_MAXDATASIZE - NFS_MAXDATA);
495 
496 	/*
497 	 * If soft mount and server is down just try once.
498 	 * meaning: do not retransmit.
499 	 */
500 	if (!(mi->mi_flags & MI_HARD) && (mi->mi_flags & MI_DOWN))
501 		ci.cl_retrans = 0;
502 	else
503 		ci.cl_retrans = mi->mi_retrans;
504 
505 	ci.cl_prog = NFS_ACL_PROGRAM;
506 	ci.cl_vers = mi->mi_vers;
507 	ci.cl_flags = mi->mi_flags;
508 
509 	/*
510 	 * clget calls sec_clnt_geth() to get an auth handle. For RPCSEC_GSS
511 	 * security flavor, the client tries to establish a security context
512 	 * by contacting the server. If the connection is timed out or reset,
513 	 * e.g. server reboot, we will try again.
514 	 */
515 	do {
516 		error = clget_impl(&ci, svp, cr, newcl, chp, nfscl);
517 
518 		if (error == 0)
519 			break;
520 
521 		/*
522 		 * For forced unmount or zone shutdown, bail out, no retry.
523 		 */
524 		if (FS_OR_ZONE_GONE(mi->mi_vfsp)) {
525 			error = EIO;
526 			break;
527 		}
528 
529 		/* do not retry for softmount */
530 		if (!(mi->mi_flags & MI_HARD))
531 			break;
532 
533 		/* let the caller deal with the failover case */
534 		if (FAILOVER_MOUNT(mi))
535 			break;
536 
537 	} while (error == ETIMEDOUT || error == ECONNRESET);
538 
539 	return (error);
540 }
541 
542 static int
543 nfs_clget(mntinfo_t *mi, servinfo_t *svp, cred_t *cr, CLIENT **newcl,
544     struct chtab **chp, struct nfs_clnt *nfscl)
545 {
546 	clinfo_t ci;
547 	int error;
548 
549 	/*
550 	 * Set read buffer size to rsize
551 	 * and add room for RPC headers.
552 	 */
553 	ci.cl_readsize = mi->mi_tsize;
554 	if (ci.cl_readsize != 0)
555 		ci.cl_readsize += (RPC_MAXDATASIZE - NFS_MAXDATA);
556 
557 	/*
558 	 * If soft mount and server is down just try once.
559 	 * meaning: do not retransmit.
560 	 */
561 	if (!(mi->mi_flags & MI_HARD) && (mi->mi_flags & MI_DOWN))
562 		ci.cl_retrans = 0;
563 	else
564 		ci.cl_retrans = mi->mi_retrans;
565 
566 	ci.cl_prog = mi->mi_prog;
567 	ci.cl_vers = mi->mi_vers;
568 	ci.cl_flags = mi->mi_flags;
569 
570 	/*
571 	 * clget calls sec_clnt_geth() to get an auth handle. For RPCSEC_GSS
572 	 * security flavor, the client tries to establish a security context
573 	 * by contacting the server. If the connection is timed out or reset,
574 	 * e.g. server reboot, we will try again.
575 	 */
576 	do {
577 		error = clget_impl(&ci, svp, cr, newcl, chp, nfscl);
578 
579 		if (error == 0)
580 			break;
581 
582 		/*
583 		 * For forced unmount or zone shutdown, bail out, no retry.
584 		 */
585 		if (FS_OR_ZONE_GONE(mi->mi_vfsp)) {
586 			error = EIO;
587 			break;
588 		}
589 
590 		/* do not retry for softmount */
591 		if (!(mi->mi_flags & MI_HARD))
592 			break;
593 
594 		/* let the caller deal with the failover case */
595 		if (FAILOVER_MOUNT(mi))
596 			break;
597 
598 	} while (error == ETIMEDOUT || error == ECONNRESET);
599 
600 	return (error);
601 }
602 
603 static void
604 clfree_impl(CLIENT *cl, struct chtab *cp, struct nfs_clnt *nfscl)
605 {
606 	if (cl->cl_auth != NULL) {
607 		sec_clnt_freeh(cl->cl_auth);
608 		cl->cl_auth = NULL;
609 	}
610 
611 	/*
612 	 * Timestamp this cache entry so that we know when it was last
613 	 * used.
614 	 */
615 	cp->ch_freed = gethrestime_sec();
616 
617 	/*
618 	 * Add the free client handle to the front of the list.
619 	 * This way, the list will be sorted in youngest to oldest
620 	 * order.
621 	 */
622 	mutex_enter(&nfscl->nfscl_chtable_lock);
623 	cp->ch_list = cp->ch_head->ch_list;
624 	cp->ch_head->ch_list = cp;
625 	mutex_exit(&nfscl->nfscl_chtable_lock);
626 }
627 
628 void
629 clfree(CLIENT *cl, struct chtab *cp)
630 {
631 	struct nfs_clnt *nfscl;
632 
633 	nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
634 	ASSERT(nfscl != NULL);
635 
636 	clfree_impl(cl, cp, nfscl);
637 }
638 
639 #define	CL_HOLDTIME	60	/* time to hold client handles */
640 
641 static void
642 clreclaim_zone(struct nfs_clnt *nfscl, uint_t cl_holdtime)
643 {
644 	struct chhead *ch;
645 	struct chtab *cp;	/* list of objects that can be reclaimed */
646 	struct chtab *cpe;
647 	struct chtab *cpl;
648 	struct chtab **cpp;
649 #ifdef DEBUG
650 	int n = 0;
651 #endif
652 
653 	/*
654 	 * Need to reclaim some memory, so step through the cache
655 	 * looking through the lists for entries which can be freed.
656 	 */
657 	cp = NULL;
658 
659 	mutex_enter(&nfscl->nfscl_chtable_lock);
660 
661 	/*
662 	 * Here we step through each non-NULL quadruple and start to
663 	 * construct the reclaim list pointed to by cp.  Note that
664 	 * cp will contain all eligible chtab entries.  When this traversal
665 	 * completes, chtab entries from the last quadruple will be at the
666 	 * front of cp and entries from previously inspected quadruples have
667 	 * been appended to the rear of cp.
668 	 */
669 	for (ch = nfscl->nfscl_chtable; ch != NULL; ch = ch->ch_next) {
670 		if (ch->ch_list == NULL)
671 			continue;
672 		/*
673 		 * Search each list for entries older then
674 		 * cl_holdtime seconds.  The lists are maintained
675 		 * in youngest to oldest order so that when the
676 		 * first entry is found which is old enough, then
677 		 * all of the rest of the entries on the list will
678 		 * be old enough as well.
679 		 */
680 		cpl = ch->ch_list;
681 		cpp = &ch->ch_list;
682 		while (cpl != NULL &&
683 		    cpl->ch_freed + cl_holdtime > gethrestime_sec()) {
684 			cpp = &cpl->ch_list;
685 			cpl = cpl->ch_list;
686 		}
687 		if (cpl != NULL) {
688 			*cpp = NULL;
689 			if (cp != NULL) {
690 				cpe = cpl;
691 				while (cpe->ch_list != NULL)
692 					cpe = cpe->ch_list;
693 				cpe->ch_list = cp;
694 			}
695 			cp = cpl;
696 		}
697 	}
698 
699 	mutex_exit(&nfscl->nfscl_chtable_lock);
700 
701 	/*
702 	 * If cp is empty, then there is nothing to reclaim here.
703 	 */
704 	if (cp == NULL)
705 		return;
706 
707 	/*
708 	 * Step through the list of entries to free, destroying each client
709 	 * handle and kmem_free'ing the memory for each entry.
710 	 */
711 	while (cp != NULL) {
712 #ifdef DEBUG
713 		n++;
714 #endif
715 		CLNT_DESTROY(cp->ch_client);
716 		cpl = cp->ch_list;
717 		kmem_cache_free(chtab_cache, cp);
718 		cp = cpl;
719 	}
720 
721 #ifdef DEBUG
722 	/*
723 	 * Update clalloc so that nfsstat shows the current number
724 	 * of allocated client handles.
725 	 */
726 	atomic_add_64(&nfscl->nfscl_stat.clalloc.value.ui64, -n);
727 #endif
728 }
729 
730 /* ARGSUSED */
731 static void
732 clreclaim(void *all)
733 {
734 	struct nfs_clnt *nfscl;
735 
736 #ifdef DEBUG
737 	clstat_debug.clreclaim.value.ui64++;
738 #endif
739 	/*
740 	 * The system is low on memory; go through and try to reclaim some from
741 	 * every zone on the system.
742 	 */
743 	mutex_enter(&nfs_clnt_list_lock);
744 	nfscl = list_head(&nfs_clnt_list);
745 	for (; nfscl != NULL; nfscl = list_next(&nfs_clnt_list, nfscl))
746 		clreclaim_zone(nfscl, CL_HOLDTIME);
747 	mutex_exit(&nfs_clnt_list_lock);
748 }
749 
750 /*
751  * Minimum time-out values indexed by call type
752  * These units are in "eights" of a second to avoid multiplies
753  */
754 static unsigned int minimum_timeo[] = {
755 	6, 7, 10
756 };
757 
758 /*
759  * Back off for retransmission timeout, MAXTIMO is in hz of a sec
760  */
761 #define	MAXTIMO	(20*hz)
762 #define	backoff(tim)	(((tim) < MAXTIMO) ? dobackoff(tim) : (tim))
763 #define	dobackoff(tim)	((((tim) << 1) > MAXTIMO) ? MAXTIMO : ((tim) << 1))
764 
765 #define	MIN_NFS_TSIZE 512	/* minimum "chunk" of NFS IO */
766 #define	REDUCE_NFS_TIME (hz/2)	/* rtxcur we try to keep under */
767 #define	INCREASE_NFS_TIME (hz/3*8) /* srtt we try to keep under (scaled*8) */
768 
769 /*
770  * Function called when rfscall notices that we have been
771  * re-transmitting, or when we get a response without retransmissions.
772  * Return 1 if the transfer size was adjusted down - 0 if no change.
773  */
774 static int
775 nfs_feedback(int flag, int which, mntinfo_t *mi)
776 {
777 	int kind;
778 	int r = 0;
779 
780 	mutex_enter(&mi->mi_lock);
781 	if (flag == FEEDBACK_REXMIT1) {
782 		if (mi->mi_timers[NFS_CALLTYPES].rt_rtxcur != 0 &&
783 		    mi->mi_timers[NFS_CALLTYPES].rt_rtxcur < REDUCE_NFS_TIME)
784 			goto done;
785 		if (mi->mi_curread > MIN_NFS_TSIZE) {
786 			mi->mi_curread /= 2;
787 			if (mi->mi_curread < MIN_NFS_TSIZE)
788 				mi->mi_curread = MIN_NFS_TSIZE;
789 			r = 1;
790 		}
791 
792 		if (mi->mi_curwrite > MIN_NFS_TSIZE) {
793 			mi->mi_curwrite /= 2;
794 			if (mi->mi_curwrite < MIN_NFS_TSIZE)
795 				mi->mi_curwrite = MIN_NFS_TSIZE;
796 			r = 1;
797 		}
798 	} else if (flag == FEEDBACK_OK) {
799 		kind = mi->mi_timer_type[which];
800 		if (kind == 0 ||
801 		    mi->mi_timers[kind].rt_srtt >= INCREASE_NFS_TIME)
802 			goto done;
803 		if (kind == 1) {
804 			if (mi->mi_curread >= mi->mi_tsize)
805 				goto done;
806 			mi->mi_curread +=  MIN_NFS_TSIZE;
807 			if (mi->mi_curread > mi->mi_tsize/2)
808 				mi->mi_curread = mi->mi_tsize;
809 		} else if (kind == 2) {
810 			if (mi->mi_curwrite >= mi->mi_stsize)
811 				goto done;
812 			mi->mi_curwrite += MIN_NFS_TSIZE;
813 			if (mi->mi_curwrite > mi->mi_stsize/2)
814 				mi->mi_curwrite = mi->mi_stsize;
815 		}
816 	}
817 done:
818 	mutex_exit(&mi->mi_lock);
819 	return (r);
820 }
821 
822 #ifdef DEBUG
823 static int rfs2call_hits = 0;
824 static int rfs2call_misses = 0;
825 #endif
826 
827 int
828 rfs2call(mntinfo_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
829     xdrproc_t xdrres, caddr_t resp, cred_t *cr, int *douprintf,
830     enum nfsstat *statusp, int flags, failinfo_t *fi)
831 {
832 	int rpcerror;
833 	enum clnt_stat rpc_status;
834 
835 	ASSERT(statusp != NULL);
836 
837 	rpcerror = rfscall(mi, which, xdrargs, argsp, xdrres, resp,
838 	    cr, douprintf, &rpc_status, flags, fi);
839 	if (!rpcerror) {
840 		/*
841 		 * See crnetadjust() for comments.
842 		 */
843 		if (*statusp == NFSERR_ACCES &&
844 		    (cr = crnetadjust(cr)) != NULL) {
845 #ifdef DEBUG
846 			rfs2call_hits++;
847 #endif
848 			rpcerror = rfscall(mi, which, xdrargs, argsp, xdrres,
849 			    resp, cr, douprintf, NULL, flags, fi);
850 			crfree(cr);
851 #ifdef DEBUG
852 			if (*statusp == NFSERR_ACCES)
853 				rfs2call_misses++;
854 #endif
855 		}
856 	} else if (rpc_status == RPC_PROCUNAVAIL) {
857 		*statusp = NFSERR_OPNOTSUPP;
858 		rpcerror = 0;
859 	}
860 
861 	return (rpcerror);
862 }
863 
864 #define	NFS3_JUKEBOX_DELAY	10 * hz
865 
866 static clock_t nfs3_jukebox_delay = 0;
867 
868 #ifdef DEBUG
869 static int rfs3call_hits = 0;
870 static int rfs3call_misses = 0;
871 #endif
872 
873 int
874 rfs3call(mntinfo_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
875     xdrproc_t xdrres, caddr_t resp, cred_t *cr, int *douprintf,
876     nfsstat3 *statusp, int flags, failinfo_t *fi)
877 {
878 	int rpcerror;
879 	int user_informed;
880 
881 	user_informed = 0;
882 	do {
883 		rpcerror = rfscall(mi, which, xdrargs, argsp, xdrres, resp,
884 		    cr, douprintf, NULL, flags, fi);
885 		if (!rpcerror) {
886 			cred_t *crr;
887 			if (*statusp == NFS3ERR_JUKEBOX) {
888 				if (ttoproc(curthread) == &p0) {
889 					rpcerror = EAGAIN;
890 					break;
891 				}
892 				if (!user_informed) {
893 					user_informed = 1;
894 					uprintf(
895 		"file temporarily unavailable on the server, retrying...\n");
896 				}
897 				delay(nfs3_jukebox_delay);
898 			}
899 			/*
900 			 * See crnetadjust() for comments.
901 			 */
902 			else if (*statusp == NFS3ERR_ACCES &&
903 			    (crr = crnetadjust(cr)) != NULL) {
904 #ifdef DEBUG
905 				rfs3call_hits++;
906 #endif
907 				rpcerror = rfscall(mi, which, xdrargs, argsp,
908 				    xdrres, resp, crr, douprintf,
909 				    NULL, flags, fi);
910 
911 				crfree(crr);
912 #ifdef DEBUG
913 				if (*statusp == NFS3ERR_ACCES)
914 					rfs3call_misses++;
915 #endif
916 			}
917 		}
918 	} while (!rpcerror && *statusp == NFS3ERR_JUKEBOX);
919 
920 	return (rpcerror);
921 }
922 
923 #define	VALID_FH(fi)	(VTOR(fi->vp)->r_server == VTOMI(fi->vp)->mi_curr_serv)
924 #define	INC_READERS(mi)		{ \
925 	mi->mi_readers++; \
926 }
927 #define	DEC_READERS(mi)		{ \
928 	mi->mi_readers--; \
929 	if (mi->mi_readers == 0) \
930 		cv_broadcast(&mi->mi_failover_cv); \
931 }
932 
933 static int
934 rfscall(mntinfo_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
935     xdrproc_t xdrres, caddr_t resp, cred_t *icr, int *douprintf,
936     enum clnt_stat *rpc_status, int flags, failinfo_t *fi)
937 {
938 	CLIENT *client;
939 	struct chtab *ch;
940 	cred_t *cr = icr;
941 	enum clnt_stat status;
942 	struct rpc_err rpcerr, rpcerr_tmp;
943 	struct timeval wait;
944 	int timeo;		/* in units of hz */
945 	int my_rsize, my_wsize;
946 	bool_t tryagain;
947 	bool_t cred_cloned = FALSE;
948 	k_sigset_t smask;
949 	servinfo_t *svp;
950 	struct nfs_clnt *nfscl;
951 	zoneid_t zoneid = getzoneid();
952 	char *msg;
953 #ifdef DEBUG
954 	char *bufp;
955 #endif
956 
957 
958 	TRACE_2(TR_FAC_NFS, TR_RFSCALL_START,
959 	    "rfscall_start:which %d mi %p", which, mi);
960 
961 	nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
962 	ASSERT(nfscl != NULL);
963 
964 	nfscl->nfscl_stat.calls.value.ui64++;
965 	mi->mi_reqs[which].value.ui64++;
966 
967 	rpcerr.re_status = RPC_SUCCESS;
968 
969 	/*
970 	 * In case of forced unmount or zone shutdown, return EIO.
971 	 */
972 
973 	if (FS_OR_ZONE_GONE(mi->mi_vfsp)) {
974 		rpcerr.re_status = RPC_FAILED;
975 		rpcerr.re_errno = EIO;
976 		return (rpcerr.re_errno);
977 	}
978 
979 	/*
980 	 * Remember the transfer sizes in case
981 	 * nfs_feedback changes them underneath us.
982 	 */
983 	my_rsize = mi->mi_curread;
984 	my_wsize = mi->mi_curwrite;
985 
986 	/*
987 	 * NFS client failover support
988 	 *
989 	 * If this rnode is not in sync with the current server (VALID_FH),
990 	 * we'd like to do a remap to get in sync.  We can be interrupted
991 	 * in failover_remap(), and if so we'll bail.  Otherwise, we'll
992 	 * use the best info we have to try the RPC.  Part of that is
993 	 * unconditionally updating the filehandle copy kept for V3.
994 	 *
995 	 * Locking: INC_READERS/DEC_READERS is a poor man's interrruptible
996 	 * rw_enter(); we're trying to keep the current server from being
997 	 * changed on us until we're done with the remapping and have a
998 	 * matching client handle.  We don't want to sending a filehandle
999 	 * to the wrong host.
1000 	 */
1001 failoverretry:
1002 	if (FAILOVER_MOUNT(mi)) {
1003 		mutex_enter(&mi->mi_lock);
1004 		if (!(flags & RFSCALL_SOFT) && failover_safe(fi)) {
1005 			if (failover_wait(mi)) {
1006 				mutex_exit(&mi->mi_lock);
1007 				return (EINTR);
1008 			}
1009 		}
1010 		INC_READERS(mi);
1011 		mutex_exit(&mi->mi_lock);
1012 		if (fi) {
1013 			if (!VALID_FH(fi) &&
1014 			    !(flags & RFSCALL_SOFT) && failover_safe(fi)) {
1015 				int remaperr;
1016 
1017 				svp = mi->mi_curr_serv;
1018 				remaperr = failover_remap(fi);
1019 				if (remaperr != 0) {
1020 #ifdef DEBUG
1021 					if (remaperr != EINTR)
1022 						nfs_cmn_err(remaperr, CE_WARN,
1023 					    "rfscall couldn't failover: %m");
1024 #endif
1025 					mutex_enter(&mi->mi_lock);
1026 					DEC_READERS(mi);
1027 					mutex_exit(&mi->mi_lock);
1028 					/*
1029 					 * If failover_remap returns ETIMEDOUT
1030 					 * and the filesystem is hard mounted
1031 					 * we have to retry the call with a new
1032 					 * server.
1033 					 */
1034 					if ((mi->mi_flags & MI_HARD) &&
1035 					    IS_RECOVERABLE_ERROR(remaperr)) {
1036 						if (svp == mi->mi_curr_serv)
1037 							failover_newserver(mi);
1038 						rpcerr.re_status = RPC_SUCCESS;
1039 						goto failoverretry;
1040 					}
1041 					rpcerr.re_errno = remaperr;
1042 					return (remaperr);
1043 				}
1044 			}
1045 			if (fi->fhp && fi->copyproc)
1046 				(*fi->copyproc)(fi->fhp, fi->vp);
1047 		}
1048 	}
1049 
1050 	/* For TSOL, use a new cred which has net_mac_aware flag */
1051 	if (!cred_cloned && is_system_labeled()) {
1052 		cred_cloned = TRUE;
1053 		cr = crdup(icr);
1054 		(void) setpflags(NET_MAC_AWARE, 1, cr);
1055 	}
1056 
1057 	/*
1058 	 * clget() calls clnt_tli_kinit() which clears the xid, so we
1059 	 * are guaranteed to reprocess the retry as a new request.
1060 	 */
1061 	svp = mi->mi_curr_serv;
1062 	rpcerr.re_errno = nfs_clget(mi, svp, cr, &client, &ch, nfscl);
1063 
1064 	if (FAILOVER_MOUNT(mi)) {
1065 		mutex_enter(&mi->mi_lock);
1066 		DEC_READERS(mi);
1067 		mutex_exit(&mi->mi_lock);
1068 
1069 		if ((rpcerr.re_errno == ETIMEDOUT ||
1070 		    rpcerr.re_errno == ECONNRESET) &&
1071 		    failover_safe(fi)) {
1072 			if (svp == mi->mi_curr_serv)
1073 				failover_newserver(mi);
1074 			goto failoverretry;
1075 		}
1076 	}
1077 	if (rpcerr.re_errno != 0)
1078 		return (rpcerr.re_errno);
1079 
1080 	if (svp->sv_knconf->knc_semantics == NC_TPI_COTS_ORD ||
1081 	    svp->sv_knconf->knc_semantics == NC_TPI_COTS) {
1082 		timeo = (mi->mi_timeo * hz) / 10;
1083 	} else {
1084 		mutex_enter(&mi->mi_lock);
1085 		timeo = CLNT_SETTIMERS(client,
1086 		    &(mi->mi_timers[mi->mi_timer_type[which]]),
1087 		    &(mi->mi_timers[NFS_CALLTYPES]),
1088 		    (minimum_timeo[mi->mi_call_type[which]]*hz)>>3,
1089 		    (void (*)())NULL, (caddr_t)mi, 0);
1090 		mutex_exit(&mi->mi_lock);
1091 	}
1092 
1093 	/*
1094 	 * If hard mounted fs, retry call forever unless hard error occurs.
1095 	 */
1096 	do {
1097 		tryagain = FALSE;
1098 
1099 		if (FS_OR_ZONE_GONE(mi->mi_vfsp)) {
1100 			status = RPC_FAILED;
1101 			rpcerr.re_status = RPC_FAILED;
1102 			rpcerr.re_errno = EIO;
1103 			break;
1104 		}
1105 
1106 		TICK_TO_TIMEVAL(timeo, &wait);
1107 
1108 		/*
1109 		 * Mask out all signals except SIGHUP, SIGINT, SIGQUIT
1110 		 * and SIGTERM. (Preserving the existing masks).
1111 		 * Mask out SIGINT if mount option nointr is specified.
1112 		 */
1113 		sigintr(&smask, (int)mi->mi_flags & MI_INT);
1114 		if (!(mi->mi_flags & MI_INT))
1115 			client->cl_nosignal = TRUE;
1116 
1117 		/*
1118 		 * If there is a current signal, then don't bother
1119 		 * even trying to send out the request because we
1120 		 * won't be able to block waiting for the response.
1121 		 * Simply assume RPC_INTR and get on with it.
1122 		 */
1123 		if (ttolwp(curthread) != NULL && ISSIG(curthread, JUSTLOOKING))
1124 			status = RPC_INTR;
1125 		else {
1126 			status = CLNT_CALL(client, which, xdrargs, argsp,
1127 			    xdrres, resp, wait);
1128 		}
1129 
1130 		if (!(mi->mi_flags & MI_INT))
1131 			client->cl_nosignal = FALSE;
1132 		/*
1133 		 * restore original signal mask
1134 		 */
1135 		sigunintr(&smask);
1136 
1137 		switch (status) {
1138 		case RPC_SUCCESS:
1139 			if ((mi->mi_flags & MI_DYNAMIC) &&
1140 			    mi->mi_timer_type[which] != 0 &&
1141 			    (mi->mi_curread != my_rsize ||
1142 			    mi->mi_curwrite != my_wsize))
1143 				(void) nfs_feedback(FEEDBACK_OK, which, mi);
1144 			break;
1145 
1146 		case RPC_INTR:
1147 			/*
1148 			 * There is no way to recover from this error,
1149 			 * even if mount option nointr is specified.
1150 			 * SIGKILL, for example, cannot be blocked.
1151 			 */
1152 			rpcerr.re_status = RPC_INTR;
1153 			rpcerr.re_errno = EINTR;
1154 			break;
1155 
1156 		case RPC_UDERROR:
1157 			/*
1158 			 * If the NFS server is local (vold) and
1159 			 * it goes away then we get RPC_UDERROR.
1160 			 * This is a retryable error, so we would
1161 			 * loop, so check to see if the specific
1162 			 * error was ECONNRESET, indicating that
1163 			 * target did not exist at all.  If so,
1164 			 * return with RPC_PROGUNAVAIL and
1165 			 * ECONNRESET to indicate why.
1166 			 */
1167 			CLNT_GETERR(client, &rpcerr);
1168 			if (rpcerr.re_errno == ECONNRESET) {
1169 				rpcerr.re_status = RPC_PROGUNAVAIL;
1170 				rpcerr.re_errno = ECONNRESET;
1171 				break;
1172 			}
1173 			/*FALLTHROUGH*/
1174 
1175 		default:		/* probably RPC_TIMEDOUT */
1176 			if (IS_UNRECOVERABLE_RPC(status))
1177 				break;
1178 
1179 			/*
1180 			 * increment server not responding count
1181 			 */
1182 			mutex_enter(&mi->mi_lock);
1183 			mi->mi_noresponse++;
1184 			mutex_exit(&mi->mi_lock);
1185 #ifdef DEBUG
1186 			nfscl->nfscl_stat.noresponse.value.ui64++;
1187 #endif
1188 
1189 			if (!(mi->mi_flags & MI_HARD)) {
1190 				if (!(mi->mi_flags & MI_SEMISOFT) ||
1191 				    (mi->mi_ss_call_type[which] == 0))
1192 					break;
1193 			}
1194 
1195 			/*
1196 			 * The call is in progress (over COTS).
1197 			 * Try the CLNT_CALL again, but don't
1198 			 * print a noisy error message.
1199 			 */
1200 			if (status == RPC_INPROGRESS) {
1201 				tryagain = TRUE;
1202 				break;
1203 			}
1204 
1205 			if (flags & RFSCALL_SOFT)
1206 				break;
1207 
1208 			/*
1209 			 * On zone shutdown, just move on.
1210 			 */
1211 			if (zone_status_get(curproc->p_zone) >=
1212 			    ZONE_IS_SHUTTING_DOWN) {
1213 				rpcerr.re_status = RPC_FAILED;
1214 				rpcerr.re_errno = EIO;
1215 				break;
1216 			}
1217 
1218 			/*
1219 			 * NFS client failover support
1220 			 *
1221 			 * If the current server just failed us, we'll
1222 			 * start the process of finding a new server.
1223 			 * After that, we can just retry.
1224 			 */
1225 			if (FAILOVER_MOUNT(mi) && failover_safe(fi)) {
1226 				if (svp == mi->mi_curr_serv)
1227 					failover_newserver(mi);
1228 				clfree_impl(client, ch, nfscl);
1229 				goto failoverretry;
1230 			}
1231 
1232 			tryagain = TRUE;
1233 			timeo = backoff(timeo);
1234 
1235 			CLNT_GETERR(client, &rpcerr_tmp);
1236 			if ((status == RPC_CANTSEND) &&
1237 			    (rpcerr_tmp.re_errno == ENOBUFS))
1238 				msg = SRV_QFULL_MSG;
1239 			else
1240 				msg = SRV_NOTRESP_MSG;
1241 
1242 			mutex_enter(&mi->mi_lock);
1243 			if (!(mi->mi_flags & MI_PRINTED)) {
1244 				mi->mi_flags |= MI_PRINTED;
1245 				mutex_exit(&mi->mi_lock);
1246 #ifdef DEBUG
1247 				zprintf(zoneid, msg, mi->mi_vers,
1248 				    svp->sv_hostname);
1249 #else
1250 				zprintf(zoneid, msg, svp->sv_hostname);
1251 #endif
1252 			} else
1253 				mutex_exit(&mi->mi_lock);
1254 			if (*douprintf && nfs_has_ctty()) {
1255 				*douprintf = 0;
1256 				if (!(mi->mi_flags & MI_NOPRINT))
1257 #ifdef DEBUG
1258 					uprintf(msg, mi->mi_vers,
1259 					    svp->sv_hostname);
1260 #else
1261 					uprintf(msg, svp->sv_hostname);
1262 #endif
1263 			}
1264 
1265 			/*
1266 			 * If doing dynamic adjustment of transfer
1267 			 * size and if it's a read or write call
1268 			 * and if the transfer size changed while
1269 			 * retransmitting or if the feedback routine
1270 			 * changed the transfer size,
1271 			 * then exit rfscall so that the transfer
1272 			 * size can be adjusted at the vnops level.
1273 			 */
1274 			if ((mi->mi_flags & MI_DYNAMIC) &&
1275 			    mi->mi_timer_type[which] != 0 &&
1276 			    (mi->mi_curread != my_rsize ||
1277 			    mi->mi_curwrite != my_wsize ||
1278 			    nfs_feedback(FEEDBACK_REXMIT1, which, mi))) {
1279 				/*
1280 				 * On read or write calls, return
1281 				 * back to the vnode ops level if
1282 				 * the transfer size changed.
1283 				 */
1284 				clfree_impl(client, ch, nfscl);
1285 				if (cred_cloned)
1286 					crfree(cr);
1287 				return (ENFS_TRYAGAIN);
1288 			}
1289 		}
1290 	} while (tryagain);
1291 
1292 	if (status != RPC_SUCCESS) {
1293 		/*
1294 		 * Let soft mounts use the timed out message.
1295 		 */
1296 		if (status == RPC_INPROGRESS)
1297 			status = RPC_TIMEDOUT;
1298 		nfscl->nfscl_stat.badcalls.value.ui64++;
1299 		if (status != RPC_INTR) {
1300 			mutex_enter(&mi->mi_lock);
1301 			mi->mi_flags |= MI_DOWN;
1302 			mutex_exit(&mi->mi_lock);
1303 			CLNT_GETERR(client, &rpcerr);
1304 #ifdef DEBUG
1305 			bufp = clnt_sperror(client, svp->sv_hostname);
1306 			zprintf(zoneid, "NFS%d %s failed for %s\n",
1307 			    mi->mi_vers, mi->mi_rfsnames[which], bufp);
1308 			if (nfs_has_ctty()) {
1309 				if (!(mi->mi_flags & MI_NOPRINT)) {
1310 					uprintf("NFS%d %s failed for %s\n",
1311 					    mi->mi_vers, mi->mi_rfsnames[which],
1312 					    bufp);
1313 				}
1314 			}
1315 			kmem_free(bufp, MAXPATHLEN);
1316 #else
1317 			zprintf(zoneid,
1318 			    "NFS %s failed for server %s: error %d (%s)\n",
1319 			    mi->mi_rfsnames[which], svp->sv_hostname,
1320 			    status, clnt_sperrno(status));
1321 			if (nfs_has_ctty()) {
1322 				if (!(mi->mi_flags & MI_NOPRINT)) {
1323 					uprintf(
1324 				"NFS %s failed for server %s: error %d (%s)\n",
1325 					    mi->mi_rfsnames[which],
1326 					    svp->sv_hostname, status,
1327 					    clnt_sperrno(status));
1328 				}
1329 			}
1330 #endif
1331 			/*
1332 			 * when CLNT_CALL() fails with RPC_AUTHERROR,
1333 			 * re_errno is set appropriately depending on
1334 			 * the authentication error
1335 			 */
1336 			if (status == RPC_VERSMISMATCH ||
1337 			    status == RPC_PROGVERSMISMATCH)
1338 				rpcerr.re_errno = EIO;
1339 		}
1340 	} else {
1341 		/*
1342 		 * Test the value of mi_down and mi_printed without
1343 		 * holding the mi_lock mutex.  If they are both zero,
1344 		 * then it is okay to skip the down and printed
1345 		 * processing.  This saves on a mutex_enter and
1346 		 * mutex_exit pair for a normal, successful RPC.
1347 		 * This was just complete overhead.
1348 		 */
1349 		if (mi->mi_flags & (MI_DOWN | MI_PRINTED)) {
1350 			mutex_enter(&mi->mi_lock);
1351 			mi->mi_flags &= ~MI_DOWN;
1352 			if (mi->mi_flags & MI_PRINTED) {
1353 				mi->mi_flags &= ~MI_PRINTED;
1354 				mutex_exit(&mi->mi_lock);
1355 #ifdef DEBUG
1356 			if (!(mi->mi_vfsp->vfs_flag & VFS_UNMOUNTED))
1357 				zprintf(zoneid, "NFS%d server %s ok\n",
1358 				    mi->mi_vers, svp->sv_hostname);
1359 #else
1360 			if (!(mi->mi_vfsp->vfs_flag & VFS_UNMOUNTED))
1361 				zprintf(zoneid, "NFS server %s ok\n",
1362 				    svp->sv_hostname);
1363 #endif
1364 			} else
1365 				mutex_exit(&mi->mi_lock);
1366 		}
1367 
1368 		if (*douprintf == 0) {
1369 			if (!(mi->mi_flags & MI_NOPRINT))
1370 #ifdef DEBUG
1371 				if (!(mi->mi_vfsp->vfs_flag & VFS_UNMOUNTED))
1372 					uprintf("NFS%d server %s ok\n",
1373 					    mi->mi_vers, svp->sv_hostname);
1374 #else
1375 			if (!(mi->mi_vfsp->vfs_flag & VFS_UNMOUNTED))
1376 				uprintf("NFS server %s ok\n", svp->sv_hostname);
1377 #endif
1378 			*douprintf = 1;
1379 		}
1380 	}
1381 
1382 	clfree_impl(client, ch, nfscl);
1383 	if (cred_cloned)
1384 		crfree(cr);
1385 
1386 	ASSERT(rpcerr.re_status == RPC_SUCCESS || rpcerr.re_errno != 0);
1387 
1388 	if (rpc_status != NULL)
1389 		*rpc_status = rpcerr.re_status;
1390 
1391 	TRACE_1(TR_FAC_NFS, TR_RFSCALL_END, "rfscall_end:errno %d",
1392 	    rpcerr.re_errno);
1393 
1394 	return (rpcerr.re_errno);
1395 }
1396 
1397 #ifdef DEBUG
1398 static int acl2call_hits = 0;
1399 static int acl2call_misses = 0;
1400 #endif
1401 
1402 int
1403 acl2call(mntinfo_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
1404     xdrproc_t xdrres, caddr_t resp, cred_t *cr, int *douprintf,
1405     enum nfsstat *statusp, int flags, failinfo_t *fi)
1406 {
1407 	int rpcerror;
1408 
1409 	rpcerror = aclcall(mi, which, xdrargs, argsp, xdrres, resp,
1410 	    cr, douprintf, flags, fi);
1411 	if (!rpcerror) {
1412 		/*
1413 		 * See comments with crnetadjust().
1414 		 */
1415 		if (*statusp == NFSERR_ACCES &&
1416 		    (cr = crnetadjust(cr)) != NULL) {
1417 #ifdef DEBUG
1418 			acl2call_hits++;
1419 #endif
1420 			rpcerror = aclcall(mi, which, xdrargs, argsp, xdrres,
1421 			    resp, cr, douprintf, flags, fi);
1422 			crfree(cr);
1423 #ifdef DEBUG
1424 			if (*statusp == NFSERR_ACCES)
1425 				acl2call_misses++;
1426 #endif
1427 		}
1428 	}
1429 
1430 	return (rpcerror);
1431 }
1432 
1433 #ifdef DEBUG
1434 static int acl3call_hits = 0;
1435 static int acl3call_misses = 0;
1436 #endif
1437 
1438 int
1439 acl3call(mntinfo_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
1440     xdrproc_t xdrres, caddr_t resp, cred_t *cr, int *douprintf,
1441     nfsstat3 *statusp, int flags, failinfo_t *fi)
1442 {
1443 	int rpcerror;
1444 	int user_informed;
1445 
1446 	user_informed = 0;
1447 
1448 	do {
1449 		rpcerror = aclcall(mi, which, xdrargs, argsp, xdrres, resp,
1450 		    cr, douprintf, flags, fi);
1451 		if (!rpcerror) {
1452 			cred_t *crr;
1453 			if (*statusp == NFS3ERR_JUKEBOX) {
1454 				if (!user_informed) {
1455 					user_informed = 1;
1456 					uprintf(
1457 		"file temporarily unavailable on the server, retrying...\n");
1458 				}
1459 				delay(nfs3_jukebox_delay);
1460 			}
1461 			/*
1462 			 * See crnetadjust() for comments.
1463 			 */
1464 			else if (*statusp == NFS3ERR_ACCES &&
1465 			    (crr = crnetadjust(cr)) != NULL) {
1466 #ifdef DEBUG
1467 				acl3call_hits++;
1468 #endif
1469 				rpcerror = aclcall(mi, which, xdrargs, argsp,
1470 				    xdrres, resp, crr, douprintf, flags, fi);
1471 
1472 				crfree(crr);
1473 #ifdef DEBUG
1474 				if (*statusp == NFS3ERR_ACCES)
1475 					acl3call_misses++;
1476 #endif
1477 			}
1478 		}
1479 	} while (!rpcerror && *statusp == NFS3ERR_JUKEBOX);
1480 
1481 	return (rpcerror);
1482 }
1483 
1484 static int
1485 aclcall(mntinfo_t *mi, rpcproc_t which, xdrproc_t xdrargs, caddr_t argsp,
1486     xdrproc_t xdrres, caddr_t resp, cred_t *icr, int *douprintf,
1487     int flags, failinfo_t *fi)
1488 {
1489 	CLIENT *client;
1490 	struct chtab *ch;
1491 	cred_t *cr = icr;
1492 	bool_t cred_cloned = FALSE;
1493 	enum clnt_stat status;
1494 	struct rpc_err rpcerr;
1495 	struct timeval wait;
1496 	int timeo;		/* in units of hz */
1497 #if 0 /* notyet */
1498 	int my_rsize, my_wsize;
1499 #endif
1500 	bool_t tryagain;
1501 	k_sigset_t smask;
1502 	servinfo_t *svp;
1503 	struct nfs_clnt *nfscl;
1504 	zoneid_t zoneid = getzoneid();
1505 #ifdef DEBUG
1506 	char *bufp;
1507 #endif
1508 
1509 #if 0 /* notyet */
1510 	TRACE_2(TR_FAC_NFS, TR_RFSCALL_START,
1511 	    "rfscall_start:which %d mi %p", which, mi);
1512 #endif
1513 
1514 	nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
1515 	ASSERT(nfscl != NULL);
1516 
1517 	nfscl->nfscl_stat.calls.value.ui64++;
1518 	mi->mi_aclreqs[which].value.ui64++;
1519 
1520 	rpcerr.re_status = RPC_SUCCESS;
1521 
1522 	if (FS_OR_ZONE_GONE(mi->mi_vfsp)) {
1523 		rpcerr.re_status = RPC_FAILED;
1524 		rpcerr.re_errno = EIO;
1525 		return (rpcerr.re_errno);
1526 	}
1527 
1528 #if 0 /* notyet */
1529 	/*
1530 	 * Remember the transfer sizes in case
1531 	 * nfs_feedback changes them underneath us.
1532 	 */
1533 	my_rsize = mi->mi_curread;
1534 	my_wsize = mi->mi_curwrite;
1535 #endif
1536 
1537 	/*
1538 	 * NFS client failover support
1539 	 *
1540 	 * If this rnode is not in sync with the current server (VALID_FH),
1541 	 * we'd like to do a remap to get in sync.  We can be interrupted
1542 	 * in failover_remap(), and if so we'll bail.  Otherwise, we'll
1543 	 * use the best info we have to try the RPC.  Part of that is
1544 	 * unconditionally updating the filehandle copy kept for V3.
1545 	 *
1546 	 * Locking: INC_READERS/DEC_READERS is a poor man's interrruptible
1547 	 * rw_enter(); we're trying to keep the current server from being
1548 	 * changed on us until we're done with the remapping and have a
1549 	 * matching client handle.  We don't want to sending a filehandle
1550 	 * to the wrong host.
1551 	 */
1552 failoverretry:
1553 	if (FAILOVER_MOUNT(mi)) {
1554 		mutex_enter(&mi->mi_lock);
1555 		if (!(flags & RFSCALL_SOFT) && failover_safe(fi)) {
1556 			if (failover_wait(mi)) {
1557 				mutex_exit(&mi->mi_lock);
1558 				return (EINTR);
1559 			}
1560 		}
1561 		INC_READERS(mi);
1562 		mutex_exit(&mi->mi_lock);
1563 		if (fi) {
1564 			if (!VALID_FH(fi) &&
1565 			    !(flags & RFSCALL_SOFT) && failover_safe(fi)) {
1566 				int remaperr;
1567 
1568 				svp = mi->mi_curr_serv;
1569 				remaperr = failover_remap(fi);
1570 				if (remaperr != 0) {
1571 #ifdef DEBUG
1572 					if (remaperr != EINTR)
1573 						nfs_cmn_err(remaperr, CE_WARN,
1574 					    "aclcall couldn't failover: %m");
1575 #endif
1576 					mutex_enter(&mi->mi_lock);
1577 					DEC_READERS(mi);
1578 					mutex_exit(&mi->mi_lock);
1579 
1580 					/*
1581 					 * If failover_remap returns ETIMEDOUT
1582 					 * and the filesystem is hard mounted
1583 					 * we have to retry the call with a new
1584 					 * server.
1585 					 */
1586 					if ((mi->mi_flags & MI_HARD) &&
1587 					    IS_RECOVERABLE_ERROR(remaperr)) {
1588 						if (svp == mi->mi_curr_serv)
1589 							failover_newserver(mi);
1590 						rpcerr.re_status = RPC_SUCCESS;
1591 						goto failoverretry;
1592 					}
1593 					return (remaperr);
1594 				}
1595 			}
1596 			if (fi->fhp && fi->copyproc)
1597 				(*fi->copyproc)(fi->fhp, fi->vp);
1598 		}
1599 	}
1600 
1601 	/* For TSOL, use a new cred which has net_mac_aware flag */
1602 	if (!cred_cloned && is_system_labeled()) {
1603 		cred_cloned = TRUE;
1604 		cr = crdup(icr);
1605 		(void) setpflags(NET_MAC_AWARE, 1, cr);
1606 	}
1607 
1608 	/*
1609 	 * acl_clget() calls clnt_tli_kinit() which clears the xid, so we
1610 	 * are guaranteed to reprocess the retry as a new request.
1611 	 */
1612 	svp = mi->mi_curr_serv;
1613 	rpcerr.re_errno = acl_clget(mi, svp, cr, &client, &ch, nfscl);
1614 	if (FAILOVER_MOUNT(mi)) {
1615 		mutex_enter(&mi->mi_lock);
1616 		DEC_READERS(mi);
1617 		mutex_exit(&mi->mi_lock);
1618 
1619 		if ((rpcerr.re_errno == ETIMEDOUT ||
1620 		    rpcerr.re_errno == ECONNRESET) &&
1621 		    failover_safe(fi)) {
1622 			if (svp == mi->mi_curr_serv)
1623 				failover_newserver(mi);
1624 			goto failoverretry;
1625 		}
1626 	}
1627 	if (rpcerr.re_errno != 0) {
1628 		if (cred_cloned)
1629 			crfree(cr);
1630 		return (rpcerr.re_errno);
1631 	}
1632 
1633 	if (svp->sv_knconf->knc_semantics == NC_TPI_COTS_ORD ||
1634 	    svp->sv_knconf->knc_semantics == NC_TPI_COTS) {
1635 		timeo = (mi->mi_timeo * hz) / 10;
1636 	} else {
1637 		mutex_enter(&mi->mi_lock);
1638 		timeo = CLNT_SETTIMERS(client,
1639 		    &(mi->mi_timers[mi->mi_acl_timer_type[which]]),
1640 		    &(mi->mi_timers[NFS_CALLTYPES]),
1641 		    (minimum_timeo[mi->mi_acl_call_type[which]]*hz)>>3,
1642 		    (void (*)()) 0, (caddr_t)mi, 0);
1643 		mutex_exit(&mi->mi_lock);
1644 	}
1645 
1646 	/*
1647 	 * If hard mounted fs, retry call forever unless hard error occurs.
1648 	 */
1649 	do {
1650 		tryagain = FALSE;
1651 
1652 		if (FS_OR_ZONE_GONE(mi->mi_vfsp)) {
1653 			status = RPC_FAILED;
1654 			rpcerr.re_status = RPC_FAILED;
1655 			rpcerr.re_errno = EIO;
1656 			break;
1657 		}
1658 
1659 		TICK_TO_TIMEVAL(timeo, &wait);
1660 
1661 		/*
1662 		 * Mask out all signals except SIGHUP, SIGINT, SIGQUIT
1663 		 * and SIGTERM. (Preserving the existing masks).
1664 		 * Mask out SIGINT if mount option nointr is specified.
1665 		 */
1666 		sigintr(&smask, (int)mi->mi_flags & MI_INT);
1667 		if (!(mi->mi_flags & MI_INT))
1668 			client->cl_nosignal = TRUE;
1669 
1670 		/*
1671 		 * If there is a current signal, then don't bother
1672 		 * even trying to send out the request because we
1673 		 * won't be able to block waiting for the response.
1674 		 * Simply assume RPC_INTR and get on with it.
1675 		 */
1676 		if (ttolwp(curthread) != NULL && ISSIG(curthread, JUSTLOOKING))
1677 			status = RPC_INTR;
1678 		else {
1679 			status = CLNT_CALL(client, which, xdrargs, argsp,
1680 			    xdrres, resp, wait);
1681 		}
1682 
1683 		if (!(mi->mi_flags & MI_INT))
1684 			client->cl_nosignal = FALSE;
1685 		/*
1686 		 * restore original signal mask
1687 		 */
1688 		sigunintr(&smask);
1689 
1690 		switch (status) {
1691 		case RPC_SUCCESS:
1692 #if 0 /* notyet */
1693 			if ((mi->mi_flags & MI_DYNAMIC) &&
1694 			    mi->mi_timer_type[which] != 0 &&
1695 			    (mi->mi_curread != my_rsize ||
1696 			    mi->mi_curwrite != my_wsize))
1697 				(void) nfs_feedback(FEEDBACK_OK, which, mi);
1698 #endif
1699 			break;
1700 
1701 		/*
1702 		 * Unfortunately, there are servers in the world which
1703 		 * are not coded correctly.  They are not prepared to
1704 		 * handle RPC requests to the NFS port which are not
1705 		 * NFS requests.  Thus, they may try to process the
1706 		 * NFS_ACL request as if it were an NFS request.  This
1707 		 * does not work.  Generally, an error will be generated
1708 		 * on the client because it will not be able to decode
1709 		 * the response from the server.  However, it seems
1710 		 * possible that the server may not be able to decode
1711 		 * the arguments.  Thus, the criteria for deciding
1712 		 * whether the server supports NFS_ACL or not is whether
1713 		 * the following RPC errors are returned from CLNT_CALL.
1714 		 */
1715 		case RPC_CANTDECODERES:
1716 		case RPC_PROGUNAVAIL:
1717 		case RPC_CANTDECODEARGS:
1718 		case RPC_PROGVERSMISMATCH:
1719 			mutex_enter(&mi->mi_lock);
1720 			mi->mi_flags &= ~(MI_ACL | MI_EXTATTR);
1721 			mutex_exit(&mi->mi_lock);
1722 			break;
1723 
1724 		/*
1725 		 * If the server supports NFS_ACL but not the new ops
1726 		 * for extended attributes, make sure we don't retry.
1727 		 */
1728 		case RPC_PROCUNAVAIL:
1729 			mutex_enter(&mi->mi_lock);
1730 			mi->mi_flags &= ~MI_EXTATTR;
1731 			mutex_exit(&mi->mi_lock);
1732 			break;
1733 
1734 		case RPC_INTR:
1735 			/*
1736 			 * There is no way to recover from this error,
1737 			 * even if mount option nointr is specified.
1738 			 * SIGKILL, for example, cannot be blocked.
1739 			 */
1740 			rpcerr.re_status = RPC_INTR;
1741 			rpcerr.re_errno = EINTR;
1742 			break;
1743 
1744 		case RPC_UDERROR:
1745 			/*
1746 			 * If the NFS server is local (vold) and
1747 			 * it goes away then we get RPC_UDERROR.
1748 			 * This is a retryable error, so we would
1749 			 * loop, so check to see if the specific
1750 			 * error was ECONNRESET, indicating that
1751 			 * target did not exist at all.  If so,
1752 			 * return with RPC_PROGUNAVAIL and
1753 			 * ECONNRESET to indicate why.
1754 			 */
1755 			CLNT_GETERR(client, &rpcerr);
1756 			if (rpcerr.re_errno == ECONNRESET) {
1757 				rpcerr.re_status = RPC_PROGUNAVAIL;
1758 				rpcerr.re_errno = ECONNRESET;
1759 				break;
1760 			}
1761 			/*FALLTHROUGH*/
1762 
1763 		default:		/* probably RPC_TIMEDOUT */
1764 			if (IS_UNRECOVERABLE_RPC(status))
1765 				break;
1766 
1767 			/*
1768 			 * increment server not responding count
1769 			 */
1770 			mutex_enter(&mi->mi_lock);
1771 			mi->mi_noresponse++;
1772 			mutex_exit(&mi->mi_lock);
1773 #ifdef DEBUG
1774 			nfscl->nfscl_stat.noresponse.value.ui64++;
1775 #endif
1776 
1777 			if (!(mi->mi_flags & MI_HARD)) {
1778 				if (!(mi->mi_flags & MI_SEMISOFT) ||
1779 				    (mi->mi_acl_ss_call_type[which] == 0))
1780 					break;
1781 			}
1782 
1783 			/*
1784 			 * The call is in progress (over COTS).
1785 			 * Try the CLNT_CALL again, but don't
1786 			 * print a noisy error message.
1787 			 */
1788 			if (status == RPC_INPROGRESS) {
1789 				tryagain = TRUE;
1790 				break;
1791 			}
1792 
1793 			if (flags & RFSCALL_SOFT)
1794 				break;
1795 
1796 			/*
1797 			 * On zone shutdown, just move on.
1798 			 */
1799 			if (zone_status_get(curproc->p_zone) >=
1800 			    ZONE_IS_SHUTTING_DOWN) {
1801 				rpcerr.re_status = RPC_FAILED;
1802 				rpcerr.re_errno = EIO;
1803 				break;
1804 			}
1805 
1806 			/*
1807 			 * NFS client failover support
1808 			 *
1809 			 * If the current server just failed us, we'll
1810 			 * start the process of finding a new server.
1811 			 * After that, we can just retry.
1812 			 */
1813 			if (FAILOVER_MOUNT(mi) && failover_safe(fi)) {
1814 				if (svp == mi->mi_curr_serv)
1815 					failover_newserver(mi);
1816 				clfree_impl(client, ch, nfscl);
1817 				goto failoverretry;
1818 			}
1819 
1820 			tryagain = TRUE;
1821 			timeo = backoff(timeo);
1822 			mutex_enter(&mi->mi_lock);
1823 			if (!(mi->mi_flags & MI_PRINTED)) {
1824 				mi->mi_flags |= MI_PRINTED;
1825 				mutex_exit(&mi->mi_lock);
1826 #ifdef DEBUG
1827 				zprintf(zoneid,
1828 			"NFS_ACL%d server %s not responding still trying\n",
1829 				    mi->mi_vers, svp->sv_hostname);
1830 #else
1831 				zprintf(zoneid,
1832 			    "NFS server %s not responding still trying\n",
1833 				    svp->sv_hostname);
1834 #endif
1835 			} else
1836 				mutex_exit(&mi->mi_lock);
1837 			if (*douprintf && nfs_has_ctty()) {
1838 				*douprintf = 0;
1839 				if (!(mi->mi_flags & MI_NOPRINT))
1840 #ifdef DEBUG
1841 					uprintf(
1842 			"NFS_ACL%d server %s not responding still trying\n",
1843 					    mi->mi_vers, svp->sv_hostname);
1844 #else
1845 					uprintf(
1846 			    "NFS server %s not responding still trying\n",
1847 					    svp->sv_hostname);
1848 #endif
1849 			}
1850 
1851 #if 0 /* notyet */
1852 			/*
1853 			 * If doing dynamic adjustment of transfer
1854 			 * size and if it's a read or write call
1855 			 * and if the transfer size changed while
1856 			 * retransmitting or if the feedback routine
1857 			 * changed the transfer size,
1858 			 * then exit rfscall so that the transfer
1859 			 * size can be adjusted at the vnops level.
1860 			 */
1861 			if ((mi->mi_flags & MI_DYNAMIC) &&
1862 			    mi->mi_acl_timer_type[which] != 0 &&
1863 			    (mi->mi_curread != my_rsize ||
1864 			    mi->mi_curwrite != my_wsize ||
1865 			    nfs_feedback(FEEDBACK_REXMIT1, which, mi))) {
1866 				/*
1867 				 * On read or write calls, return
1868 				 * back to the vnode ops level if
1869 				 * the transfer size changed.
1870 				 */
1871 				clfree_impl(client, ch, nfscl);
1872 				if (cred_cloned)
1873 					crfree(cr);
1874 				return (ENFS_TRYAGAIN);
1875 			}
1876 #endif
1877 		}
1878 	} while (tryagain);
1879 
1880 	if (status != RPC_SUCCESS) {
1881 		/*
1882 		 * Let soft mounts use the timed out message.
1883 		 */
1884 		if (status == RPC_INPROGRESS)
1885 			status = RPC_TIMEDOUT;
1886 		nfscl->nfscl_stat.badcalls.value.ui64++;
1887 		if (status == RPC_CANTDECODERES ||
1888 		    status == RPC_PROGUNAVAIL ||
1889 		    status == RPC_PROCUNAVAIL ||
1890 		    status == RPC_CANTDECODEARGS ||
1891 		    status == RPC_PROGVERSMISMATCH)
1892 			CLNT_GETERR(client, &rpcerr);
1893 		else if (status != RPC_INTR) {
1894 			mutex_enter(&mi->mi_lock);
1895 			mi->mi_flags |= MI_DOWN;
1896 			mutex_exit(&mi->mi_lock);
1897 			CLNT_GETERR(client, &rpcerr);
1898 #ifdef DEBUG
1899 			bufp = clnt_sperror(client, svp->sv_hostname);
1900 			zprintf(zoneid, "NFS_ACL%d %s failed for %s\n",
1901 			    mi->mi_vers, mi->mi_aclnames[which], bufp);
1902 			if (nfs_has_ctty()) {
1903 				if (!(mi->mi_flags & MI_NOPRINT)) {
1904 					uprintf("NFS_ACL%d %s failed for %s\n",
1905 					    mi->mi_vers, mi->mi_aclnames[which],
1906 					    bufp);
1907 				}
1908 			}
1909 			kmem_free(bufp, MAXPATHLEN);
1910 #else
1911 			zprintf(zoneid,
1912 			    "NFS %s failed for server %s: error %d (%s)\n",
1913 			    mi->mi_aclnames[which], svp->sv_hostname,
1914 			    status, clnt_sperrno(status));
1915 			if (nfs_has_ctty()) {
1916 				if (!(mi->mi_flags & MI_NOPRINT))
1917 					uprintf(
1918 				"NFS %s failed for server %s: error %d (%s)\n",
1919 					    mi->mi_aclnames[which],
1920 					    svp->sv_hostname, status,
1921 					    clnt_sperrno(status));
1922 			}
1923 #endif
1924 			/*
1925 			 * when CLNT_CALL() fails with RPC_AUTHERROR,
1926 			 * re_errno is set appropriately depending on
1927 			 * the authentication error
1928 			 */
1929 			if (status == RPC_VERSMISMATCH ||
1930 			    status == RPC_PROGVERSMISMATCH)
1931 				rpcerr.re_errno = EIO;
1932 		}
1933 	} else {
1934 		/*
1935 		 * Test the value of mi_down and mi_printed without
1936 		 * holding the mi_lock mutex.  If they are both zero,
1937 		 * then it is okay to skip the down and printed
1938 		 * processing.  This saves on a mutex_enter and
1939 		 * mutex_exit pair for a normal, successful RPC.
1940 		 * This was just complete overhead.
1941 		 */
1942 		if (mi->mi_flags & (MI_DOWN | MI_PRINTED)) {
1943 			mutex_enter(&mi->mi_lock);
1944 			mi->mi_flags &= ~MI_DOWN;
1945 			if (mi->mi_flags & MI_PRINTED) {
1946 				mi->mi_flags &= ~MI_PRINTED;
1947 				mutex_exit(&mi->mi_lock);
1948 #ifdef DEBUG
1949 				zprintf(zoneid, "NFS_ACL%d server %s ok\n",
1950 				    mi->mi_vers, svp->sv_hostname);
1951 #else
1952 				zprintf(zoneid, "NFS server %s ok\n",
1953 				    svp->sv_hostname);
1954 #endif
1955 			} else
1956 				mutex_exit(&mi->mi_lock);
1957 		}
1958 
1959 		if (*douprintf == 0) {
1960 			if (!(mi->mi_flags & MI_NOPRINT))
1961 #ifdef DEBUG
1962 				uprintf("NFS_ACL%d server %s ok\n",
1963 				    mi->mi_vers, svp->sv_hostname);
1964 #else
1965 				uprintf("NFS server %s ok\n", svp->sv_hostname);
1966 #endif
1967 			*douprintf = 1;
1968 		}
1969 	}
1970 
1971 	clfree_impl(client, ch, nfscl);
1972 	if (cred_cloned)
1973 		crfree(cr);
1974 
1975 	ASSERT(rpcerr.re_status == RPC_SUCCESS || rpcerr.re_errno != 0);
1976 
1977 #if 0 /* notyet */
1978 	TRACE_1(TR_FAC_NFS, TR_RFSCALL_END, "rfscall_end:errno %d",
1979 	    rpcerr.re_errno);
1980 #endif
1981 
1982 	return (rpcerr.re_errno);
1983 }
1984 
1985 int
1986 vattr_to_sattr(struct vattr *vap, struct nfssattr *sa)
1987 {
1988 	uint_t mask = vap->va_mask;
1989 
1990 	if (!(mask & AT_MODE))
1991 		sa->sa_mode = (uint32_t)-1;
1992 	else
1993 		sa->sa_mode = vap->va_mode;
1994 	if (!(mask & AT_UID))
1995 		sa->sa_uid = (uint32_t)-1;
1996 	else
1997 		sa->sa_uid = (uint32_t)vap->va_uid;
1998 	if (!(mask & AT_GID))
1999 		sa->sa_gid = (uint32_t)-1;
2000 	else
2001 		sa->sa_gid = (uint32_t)vap->va_gid;
2002 	if (!(mask & AT_SIZE))
2003 		sa->sa_size = (uint32_t)-1;
2004 	else
2005 		sa->sa_size = (uint32_t)vap->va_size;
2006 	if (!(mask & AT_ATIME))
2007 		sa->sa_atime.tv_sec = sa->sa_atime.tv_usec = (int32_t)-1;
2008 	else {
2009 		/* check time validity */
2010 		if (! NFS_TIME_T_OK(vap->va_atime.tv_sec)) {
2011 			return (EOVERFLOW);
2012 		}
2013 		sa->sa_atime.tv_sec = vap->va_atime.tv_sec;
2014 		sa->sa_atime.tv_usec = vap->va_atime.tv_nsec / 1000;
2015 	}
2016 	if (!(mask & AT_MTIME))
2017 		sa->sa_mtime.tv_sec = sa->sa_mtime.tv_usec = (int32_t)-1;
2018 	else {
2019 		/* check time validity */
2020 		if (! NFS_TIME_T_OK(vap->va_mtime.tv_sec)) {
2021 			return (EOVERFLOW);
2022 		}
2023 		sa->sa_mtime.tv_sec = vap->va_mtime.tv_sec;
2024 		sa->sa_mtime.tv_usec = vap->va_mtime.tv_nsec / 1000;
2025 	}
2026 	return (0);
2027 }
2028 
2029 int
2030 vattr_to_sattr3(struct vattr *vap, sattr3 *sa)
2031 {
2032 	uint_t mask = vap->va_mask;
2033 
2034 	if (!(mask & AT_MODE))
2035 		sa->mode.set_it = FALSE;
2036 	else {
2037 		sa->mode.set_it = TRUE;
2038 		sa->mode.mode = (mode3)vap->va_mode;
2039 	}
2040 	if (!(mask & AT_UID))
2041 		sa->uid.set_it = FALSE;
2042 	else {
2043 		sa->uid.set_it = TRUE;
2044 		sa->uid.uid = (uid3)vap->va_uid;
2045 	}
2046 	if (!(mask & AT_GID))
2047 		sa->gid.set_it = FALSE;
2048 	else {
2049 		sa->gid.set_it = TRUE;
2050 		sa->gid.gid = (gid3)vap->va_gid;
2051 	}
2052 	if (!(mask & AT_SIZE))
2053 		sa->size.set_it = FALSE;
2054 	else {
2055 		sa->size.set_it = TRUE;
2056 		sa->size.size = (size3)vap->va_size;
2057 	}
2058 	if (!(mask & AT_ATIME))
2059 		sa->atime.set_it = DONT_CHANGE;
2060 	else {
2061 		/* check time validity */
2062 		if (! NFS_TIME_T_OK(vap->va_atime.tv_sec)) {
2063 			return (EOVERFLOW);
2064 		}
2065 		sa->atime.set_it = SET_TO_CLIENT_TIME;
2066 		sa->atime.atime.seconds = (uint32)vap->va_atime.tv_sec;
2067 		sa->atime.atime.nseconds = (uint32)vap->va_atime.tv_nsec;
2068 	}
2069 	if (!(mask & AT_MTIME))
2070 		sa->mtime.set_it = DONT_CHANGE;
2071 	else {
2072 		/* check time validity */
2073 		if (! NFS_TIME_T_OK(vap->va_mtime.tv_sec)) {
2074 			return (EOVERFLOW);
2075 		}
2076 		sa->mtime.set_it = SET_TO_CLIENT_TIME;
2077 		sa->mtime.mtime.seconds = (uint32)vap->va_mtime.tv_sec;
2078 		sa->mtime.mtime.nseconds = (uint32)vap->va_mtime.tv_nsec;
2079 	}
2080 	return (0);
2081 }
2082 
2083 void
2084 setdiropargs(struct nfsdiropargs *da, char *nm, vnode_t *dvp)
2085 {
2086 
2087 	da->da_fhandle = VTOFH(dvp);
2088 	da->da_name = nm;
2089 	da->da_flags = 0;
2090 }
2091 
2092 void
2093 setdiropargs3(diropargs3 *da, char *nm, vnode_t *dvp)
2094 {
2095 
2096 	da->dirp = VTOFH3(dvp);
2097 	da->name = nm;
2098 }
2099 
2100 int
2101 setdirgid(vnode_t *dvp, gid_t *gidp, cred_t *cr)
2102 {
2103 	int error;
2104 	rnode_t *rp;
2105 	struct vattr va;
2106 
2107 	va.va_mask = AT_MODE | AT_GID;
2108 	error = VOP_GETATTR(dvp, &va, 0, cr, NULL);
2109 	if (error)
2110 		return (error);
2111 
2112 	/*
2113 	 * To determine the expected group-id of the created file:
2114 	 *  1)	If the filesystem was not mounted with the Old-BSD-compatible
2115 	 *	GRPID option, and the directory's set-gid bit is clear,
2116 	 *	then use the process's gid.
2117 	 *  2)	Otherwise, set the group-id to the gid of the parent directory.
2118 	 */
2119 	rp = VTOR(dvp);
2120 	mutex_enter(&rp->r_statelock);
2121 	if (!(VTOMI(dvp)->mi_flags & MI_GRPID) && !(va.va_mode & VSGID))
2122 		*gidp = crgetgid(cr);
2123 	else
2124 		*gidp = va.va_gid;
2125 	mutex_exit(&rp->r_statelock);
2126 	return (0);
2127 }
2128 
2129 int
2130 setdirmode(vnode_t *dvp, mode_t *omp, cred_t *cr)
2131 {
2132 	int error;
2133 	struct vattr va;
2134 
2135 	va.va_mask = AT_MODE;
2136 	error = VOP_GETATTR(dvp, &va, 0, cr, NULL);
2137 	if (error)
2138 		return (error);
2139 
2140 	/*
2141 	 * Modify the expected mode (om) so that the set-gid bit matches
2142 	 * that of the parent directory (dvp).
2143 	 */
2144 	if (va.va_mode & VSGID)
2145 		*omp |= VSGID;
2146 	else
2147 		*omp &= ~VSGID;
2148 	return (0);
2149 }
2150 
2151 void
2152 nfs_setswaplike(vnode_t *vp, vattr_t *vap)
2153 {
2154 
2155 	if (vp->v_type == VREG && (vap->va_mode & (VEXEC | VSVTX)) == VSVTX) {
2156 		if (!(vp->v_flag & VSWAPLIKE)) {
2157 			mutex_enter(&vp->v_lock);
2158 			vp->v_flag |= VSWAPLIKE;
2159 			mutex_exit(&vp->v_lock);
2160 		}
2161 	} else {
2162 		if (vp->v_flag & VSWAPLIKE) {
2163 			mutex_enter(&vp->v_lock);
2164 			vp->v_flag &= ~VSWAPLIKE;
2165 			mutex_exit(&vp->v_lock);
2166 		}
2167 	}
2168 }
2169 
2170 /*
2171  * Free the resources associated with an rnode.
2172  */
2173 static void
2174 rinactive(rnode_t *rp, cred_t *cr)
2175 {
2176 	vnode_t *vp;
2177 	cred_t *cred;
2178 	char *contents;
2179 	int size;
2180 	vsecattr_t *vsp;
2181 	int error;
2182 	nfs3_pathconf_info *info;
2183 
2184 	/*
2185 	 * Before freeing anything, wait until all asynchronous
2186 	 * activity is done on this rnode.  This will allow all
2187 	 * asynchronous read ahead and write behind i/o's to
2188 	 * finish.
2189 	 */
2190 	mutex_enter(&rp->r_statelock);
2191 	while (rp->r_count > 0)
2192 		cv_wait(&rp->r_cv, &rp->r_statelock);
2193 	mutex_exit(&rp->r_statelock);
2194 
2195 	/*
2196 	 * Flush and invalidate all pages associated with the vnode.
2197 	 */
2198 	vp = RTOV(rp);
2199 	if (vn_has_cached_data(vp)) {
2200 		ASSERT(vp->v_type != VCHR);
2201 		if ((rp->r_flags & RDIRTY) && !rp->r_error) {
2202 			error = VOP_PUTPAGE(vp, (u_offset_t)0, 0, 0, cr, NULL);
2203 			if (error && (error == ENOSPC || error == EDQUOT)) {
2204 				mutex_enter(&rp->r_statelock);
2205 				if (!rp->r_error)
2206 					rp->r_error = error;
2207 				mutex_exit(&rp->r_statelock);
2208 			}
2209 		}
2210 		nfs_invalidate_pages(vp, (u_offset_t)0, cr);
2211 	}
2212 
2213 	/*
2214 	 * Free any held credentials and caches which may be associated
2215 	 * with this rnode.
2216 	 */
2217 	mutex_enter(&rp->r_statelock);
2218 	cred = rp->r_cred;
2219 	rp->r_cred = NULL;
2220 	contents = rp->r_symlink.contents;
2221 	size = rp->r_symlink.size;
2222 	rp->r_symlink.contents = NULL;
2223 	vsp = rp->r_secattr;
2224 	rp->r_secattr = NULL;
2225 	info = rp->r_pathconf;
2226 	rp->r_pathconf = NULL;
2227 	mutex_exit(&rp->r_statelock);
2228 
2229 	/*
2230 	 * Free the held credential.
2231 	 */
2232 	if (cred != NULL)
2233 		crfree(cred);
2234 
2235 	/*
2236 	 * Free the access cache entries.
2237 	 */
2238 	(void) nfs_access_purge_rp(rp);
2239 
2240 	/*
2241 	 * Free the readdir cache entries.
2242 	 */
2243 	if (HAVE_RDDIR_CACHE(rp))
2244 		nfs_purge_rddir_cache(vp);
2245 
2246 	/*
2247 	 * Free the symbolic link cache.
2248 	 */
2249 	if (contents != NULL) {
2250 
2251 		kmem_free((void *)contents, size);
2252 	}
2253 
2254 	/*
2255 	 * Free any cached ACL.
2256 	 */
2257 	if (vsp != NULL)
2258 		nfs_acl_free(vsp);
2259 
2260 	/*
2261 	 * Free any cached pathconf information.
2262 	 */
2263 	if (info != NULL)
2264 		kmem_free(info, sizeof (*info));
2265 }
2266 
2267 /*
2268  * Return a vnode for the given NFS Version 2 file handle.
2269  * If no rnode exists for this fhandle, create one and put it
2270  * into the hash queues.  If the rnode for this fhandle
2271  * already exists, return it.
2272  *
2273  * Note: make_rnode() may upgrade the hash bucket lock to exclusive.
2274  */
2275 vnode_t *
2276 makenfsnode(fhandle_t *fh, struct nfsfattr *attr, struct vfs *vfsp,
2277     hrtime_t t, cred_t *cr, char *dnm, char *nm)
2278 {
2279 	int newnode;
2280 	int index;
2281 	vnode_t *vp;
2282 	nfs_fhandle nfh;
2283 	vattr_t va;
2284 
2285 	nfh.fh_len = NFS_FHSIZE;
2286 	bcopy(fh, nfh.fh_buf, NFS_FHSIZE);
2287 
2288 	index = rtablehash(&nfh);
2289 	rw_enter(&rtable[index].r_lock, RW_READER);
2290 
2291 	vp = make_rnode(&nfh, &rtable[index], vfsp, nfs_vnodeops,
2292 	    nfs_putapage, nfs_rddir_compar, &newnode, cr, dnm, nm);
2293 
2294 	if (attr != NULL) {
2295 		if (!newnode) {
2296 			rw_exit(&rtable[index].r_lock);
2297 			(void) nfs_cache_fattr(vp, attr, &va, t, cr);
2298 		} else {
2299 			if (attr->na_type < NFNON || attr->na_type > NFSOC)
2300 				vp->v_type = VBAD;
2301 			else
2302 				vp->v_type = n2v_type(attr);
2303 			/*
2304 			 * A translation here seems to be necessary
2305 			 * because this function can be called
2306 			 * with `attr' that has come from the wire,
2307 			 * and been operated on by vattr_to_nattr().
2308 			 * See nfsrootvp()->VOP_GETTATTR()->nfsgetattr()
2309 			 * ->nfs_getattr_otw()->rfscall()->vattr_to_nattr()
2310 			 * ->makenfsnode().
2311 			 */
2312 			if ((attr->na_rdev & 0xffff0000) == 0)
2313 				vp->v_rdev = nfsv2_expdev(attr->na_rdev);
2314 			else
2315 				vp->v_rdev = expldev(n2v_rdev(attr));
2316 			nfs_attrcache(vp, attr, t);
2317 			rw_exit(&rtable[index].r_lock);
2318 		}
2319 	} else {
2320 		if (newnode) {
2321 			PURGE_ATTRCACHE(vp);
2322 		}
2323 		rw_exit(&rtable[index].r_lock);
2324 	}
2325 
2326 	return (vp);
2327 }
2328 
2329 /*
2330  * Return a vnode for the given NFS Version 3 file handle.
2331  * If no rnode exists for this fhandle, create one and put it
2332  * into the hash queues.  If the rnode for this fhandle
2333  * already exists, return it.
2334  *
2335  * Note: make_rnode() may upgrade the hash bucket lock to exclusive.
2336  */
2337 vnode_t *
2338 makenfs3node_va(nfs_fh3 *fh, vattr_t *vap, struct vfs *vfsp, hrtime_t t,
2339     cred_t *cr, char *dnm, char *nm)
2340 {
2341 	int newnode;
2342 	int index;
2343 	vnode_t *vp;
2344 
2345 	index = rtablehash((nfs_fhandle *)fh);
2346 	rw_enter(&rtable[index].r_lock, RW_READER);
2347 
2348 	vp = make_rnode((nfs_fhandle *)fh, &rtable[index], vfsp,
2349 	    nfs3_vnodeops, nfs3_putapage, nfs3_rddir_compar, &newnode, cr,
2350 	    dnm, nm);
2351 
2352 	if (vap == NULL) {
2353 		if (newnode) {
2354 			PURGE_ATTRCACHE(vp);
2355 		}
2356 		rw_exit(&rtable[index].r_lock);
2357 		return (vp);
2358 	}
2359 
2360 	if (!newnode) {
2361 		rw_exit(&rtable[index].r_lock);
2362 		nfs_attr_cache(vp, vap, t, cr);
2363 	} else {
2364 		rnode_t *rp = VTOR(vp);
2365 
2366 		vp->v_type = vap->va_type;
2367 		vp->v_rdev = vap->va_rdev;
2368 
2369 		mutex_enter(&rp->r_statelock);
2370 		if (rp->r_mtime <= t)
2371 			nfs_attrcache_va(vp, vap);
2372 		mutex_exit(&rp->r_statelock);
2373 		rw_exit(&rtable[index].r_lock);
2374 	}
2375 
2376 	return (vp);
2377 }
2378 
2379 vnode_t *
2380 makenfs3node(nfs_fh3 *fh, fattr3 *attr, struct vfs *vfsp, hrtime_t t,
2381     cred_t *cr, char *dnm, char *nm)
2382 {
2383 	int newnode;
2384 	int index;
2385 	vnode_t *vp;
2386 	vattr_t va;
2387 
2388 	index = rtablehash((nfs_fhandle *)fh);
2389 	rw_enter(&rtable[index].r_lock, RW_READER);
2390 
2391 	vp = make_rnode((nfs_fhandle *)fh, &rtable[index], vfsp,
2392 	    nfs3_vnodeops, nfs3_putapage, nfs3_rddir_compar, &newnode, cr,
2393 	    dnm, nm);
2394 
2395 	if (attr == NULL) {
2396 		if (newnode) {
2397 			PURGE_ATTRCACHE(vp);
2398 		}
2399 		rw_exit(&rtable[index].r_lock);
2400 		return (vp);
2401 	}
2402 
2403 	if (!newnode) {
2404 		rw_exit(&rtable[index].r_lock);
2405 		(void) nfs3_cache_fattr3(vp, attr, &va, t, cr);
2406 	} else {
2407 		if (attr->type < NF3REG || attr->type > NF3FIFO)
2408 			vp->v_type = VBAD;
2409 		else
2410 			vp->v_type = nf3_to_vt[attr->type];
2411 		vp->v_rdev = makedevice(attr->rdev.specdata1,
2412 		    attr->rdev.specdata2);
2413 		nfs3_attrcache(vp, attr, t);
2414 		rw_exit(&rtable[index].r_lock);
2415 	}
2416 
2417 	return (vp);
2418 }
2419 
2420 /*
2421  * Read this comment before making changes to rtablehash()!
2422  * This is a hash function in which seemingly obvious and harmless
2423  * changes can cause escalations costing million dollars!
2424  * Know what you are doing.
2425  *
2426  * rtablehash() implements Jenkins' one-at-a-time hash algorithm.  The
2427  * algorithm is currently detailed here:
2428  *
2429  *   http://burtleburtle.net/bob/hash/doobs.html
2430  *
2431  * Of course, the above link may not be valid by the time you are reading
2432  * this, but suffice it to say that the one-at-a-time algorithm works well in
2433  * almost all cases.  If you are changing the algorithm be sure to verify that
2434  * the hash algorithm still provides even distribution in all cases and with
2435  * any server returning filehandles in whatever order (sequential or random).
2436  */
2437 static int
2438 rtablehash(nfs_fhandle *fh)
2439 {
2440 	ulong_t hash, len, i;
2441 	char *key;
2442 
2443 	key = fh->fh_buf;
2444 	len = (ulong_t)fh->fh_len;
2445 	for (hash = 0, i = 0; i < len; i++) {
2446 		hash += key[i];
2447 		hash += (hash << 10);
2448 		hash ^= (hash >> 6);
2449 	}
2450 	hash += (hash << 3);
2451 	hash ^= (hash >> 11);
2452 	hash += (hash << 15);
2453 	return (hash & rtablemask);
2454 }
2455 
2456 static vnode_t *
2457 make_rnode(nfs_fhandle *fh, rhashq_t *rhtp, struct vfs *vfsp,
2458     struct vnodeops *vops,
2459     int (*putapage)(vnode_t *, page_t *, u_offset_t *, size_t *, int, cred_t *),
2460     int (*compar)(const void *, const void *),
2461     int *newnode, cred_t *cr, char *dnm, char *nm)
2462 {
2463 	rnode_t *rp;
2464 	rnode_t *trp;
2465 	vnode_t *vp;
2466 	mntinfo_t *mi;
2467 
2468 	ASSERT(RW_READ_HELD(&rhtp->r_lock));
2469 
2470 	mi = VFTOMI(vfsp);
2471 start:
2472 	if ((rp = rfind(rhtp, fh, vfsp)) != NULL) {
2473 		vp = RTOV(rp);
2474 		nfs_set_vroot(vp);
2475 		*newnode = 0;
2476 		return (vp);
2477 	}
2478 	rw_exit(&rhtp->r_lock);
2479 
2480 	mutex_enter(&rpfreelist_lock);
2481 	if (rpfreelist != NULL && rnew >= nrnode) {
2482 		rp = rpfreelist;
2483 		rp_rmfree(rp);
2484 		mutex_exit(&rpfreelist_lock);
2485 
2486 		vp = RTOV(rp);
2487 
2488 		if (rp->r_flags & RHASHED) {
2489 			rw_enter(&rp->r_hashq->r_lock, RW_WRITER);
2490 			mutex_enter(&vp->v_lock);
2491 			if (vp->v_count > 1) {
2492 				vp->v_count--;
2493 				mutex_exit(&vp->v_lock);
2494 				rw_exit(&rp->r_hashq->r_lock);
2495 				rw_enter(&rhtp->r_lock, RW_READER);
2496 				goto start;
2497 			}
2498 			mutex_exit(&vp->v_lock);
2499 			rp_rmhash_locked(rp);
2500 			rw_exit(&rp->r_hashq->r_lock);
2501 		}
2502 
2503 		rinactive(rp, cr);
2504 
2505 		mutex_enter(&vp->v_lock);
2506 		if (vp->v_count > 1) {
2507 			vp->v_count--;
2508 			mutex_exit(&vp->v_lock);
2509 			rw_enter(&rhtp->r_lock, RW_READER);
2510 			goto start;
2511 		}
2512 		mutex_exit(&vp->v_lock);
2513 		vn_invalid(vp);
2514 		/*
2515 		 * destroy old locks before bzero'ing and
2516 		 * recreating the locks below.
2517 		 */
2518 		nfs_rw_destroy(&rp->r_rwlock);
2519 		nfs_rw_destroy(&rp->r_lkserlock);
2520 		mutex_destroy(&rp->r_statelock);
2521 		cv_destroy(&rp->r_cv);
2522 		cv_destroy(&rp->r_commit.c_cv);
2523 		nfs_free_r_path(rp);
2524 		avl_destroy(&rp->r_dir);
2525 		/*
2526 		 * Make sure that if rnode is recycled then
2527 		 * VFS count is decremented properly before
2528 		 * reuse.
2529 		 */
2530 		VFS_RELE(vp->v_vfsp);
2531 		vn_reinit(vp);
2532 	} else {
2533 		vnode_t *new_vp;
2534 
2535 		mutex_exit(&rpfreelist_lock);
2536 
2537 		rp = kmem_cache_alloc(rnode_cache, KM_SLEEP);
2538 		new_vp = vn_alloc(KM_SLEEP);
2539 
2540 		atomic_add_long((ulong_t *)&rnew, 1);
2541 #ifdef DEBUG
2542 		clstat_debug.nrnode.value.ui64++;
2543 #endif
2544 		vp = new_vp;
2545 	}
2546 
2547 	bzero(rp, sizeof (*rp));
2548 	rp->r_vnode = vp;
2549 	nfs_rw_init(&rp->r_rwlock, NULL, RW_DEFAULT, NULL);
2550 	nfs_rw_init(&rp->r_lkserlock, NULL, RW_DEFAULT, NULL);
2551 	mutex_init(&rp->r_statelock, NULL, MUTEX_DEFAULT, NULL);
2552 	cv_init(&rp->r_cv, NULL, CV_DEFAULT, NULL);
2553 	cv_init(&rp->r_commit.c_cv, NULL, CV_DEFAULT, NULL);
2554 	rp->r_fh.fh_len = fh->fh_len;
2555 	bcopy(fh->fh_buf, rp->r_fh.fh_buf, fh->fh_len);
2556 	rp->r_server = mi->mi_curr_serv;
2557 	if (FAILOVER_MOUNT(mi)) {
2558 		/*
2559 		 * If replicated servers, stash pathnames
2560 		 */
2561 		if (dnm != NULL && nm != NULL) {
2562 			char *s, *p;
2563 			uint_t len;
2564 
2565 			len = (uint_t)(strlen(dnm) + strlen(nm) + 2);
2566 			rp->r_path = kmem_alloc(len, KM_SLEEP);
2567 #ifdef DEBUG
2568 			clstat_debug.rpath.value.ui64 += len;
2569 #endif
2570 			s = rp->r_path;
2571 			for (p = dnm; *p; p++)
2572 				*s++ = *p;
2573 			*s++ = '/';
2574 			for (p = nm; *p; p++)
2575 				*s++ = *p;
2576 			*s = '\0';
2577 		} else {
2578 			/* special case for root */
2579 			rp->r_path = kmem_alloc(2, KM_SLEEP);
2580 #ifdef DEBUG
2581 			clstat_debug.rpath.value.ui64 += 2;
2582 #endif
2583 			*rp->r_path = '.';
2584 			*(rp->r_path + 1) = '\0';
2585 		}
2586 	}
2587 	VFS_HOLD(vfsp);
2588 	rp->r_putapage = putapage;
2589 	rp->r_hashq = rhtp;
2590 	rp->r_flags = RREADDIRPLUS;
2591 	avl_create(&rp->r_dir, compar, sizeof (rddir_cache),
2592 	    offsetof(rddir_cache, tree));
2593 	vn_setops(vp, vops);
2594 	vp->v_data = (caddr_t)rp;
2595 	vp->v_vfsp = vfsp;
2596 	vp->v_type = VNON;
2597 	vp->v_flag |= VMODSORT;
2598 	nfs_set_vroot(vp);
2599 
2600 	/*
2601 	 * There is a race condition if someone else
2602 	 * alloc's the rnode while no locks are held, so we
2603 	 * check again and recover if found.
2604 	 */
2605 	rw_enter(&rhtp->r_lock, RW_WRITER);
2606 	if ((trp = rfind(rhtp, fh, vfsp)) != NULL) {
2607 		vp = RTOV(trp);
2608 		nfs_set_vroot(vp);
2609 		*newnode = 0;
2610 		rw_exit(&rhtp->r_lock);
2611 		rp_addfree(rp, cr);
2612 		rw_enter(&rhtp->r_lock, RW_READER);
2613 		return (vp);
2614 	}
2615 	rp_addhash(rp);
2616 	*newnode = 1;
2617 	return (vp);
2618 }
2619 
2620 /*
2621  * Callback function to check if the page should be marked as
2622  * modified. In the positive case, p_fsdata is set to C_NOCOMMIT.
2623  */
2624 int
2625 nfs_setmod_check(page_t *pp)
2626 {
2627 	if (pp->p_fsdata != C_NOCOMMIT) {
2628 		pp->p_fsdata = C_NOCOMMIT;
2629 		return (1);
2630 	}
2631 	return (0);
2632 }
2633 
2634 static void
2635 nfs_set_vroot(vnode_t *vp)
2636 {
2637 	rnode_t *rp;
2638 	nfs_fhandle *rootfh;
2639 
2640 	rp = VTOR(vp);
2641 	rootfh = &rp->r_server->sv_fhandle;
2642 	if (rootfh->fh_len == rp->r_fh.fh_len &&
2643 	    bcmp(rootfh->fh_buf, rp->r_fh.fh_buf, rp->r_fh.fh_len) == 0) {
2644 		if (!(vp->v_flag & VROOT)) {
2645 			mutex_enter(&vp->v_lock);
2646 			vp->v_flag |= VROOT;
2647 			mutex_exit(&vp->v_lock);
2648 		}
2649 	}
2650 }
2651 
2652 static void
2653 nfs_free_r_path(rnode_t *rp)
2654 {
2655 	char *path;
2656 	size_t len;
2657 
2658 	path = rp->r_path;
2659 	if (path) {
2660 		rp->r_path = NULL;
2661 		len = strlen(path) + 1;
2662 		kmem_free(path, len);
2663 #ifdef DEBUG
2664 		clstat_debug.rpath.value.ui64 -= len;
2665 #endif
2666 	}
2667 }
2668 
2669 /*
2670  * Put an rnode on the free list.
2671  *
2672  * Rnodes which were allocated above and beyond the normal limit
2673  * are immediately freed.
2674  */
2675 void
2676 rp_addfree(rnode_t *rp, cred_t *cr)
2677 {
2678 	vnode_t *vp;
2679 	struct vfs *vfsp;
2680 
2681 	vp = RTOV(rp);
2682 	ASSERT(vp->v_count >= 1);
2683 	ASSERT(rp->r_freef == NULL && rp->r_freeb == NULL);
2684 
2685 	/*
2686 	 * If we have too many rnodes allocated and there are no
2687 	 * references to this rnode, or if the rnode is no longer
2688 	 * accessible by it does not reside in the hash queues,
2689 	 * or if an i/o error occurred while writing to the file,
2690 	 * then just free it instead of putting it on the rnode
2691 	 * freelist.
2692 	 */
2693 	vfsp = vp->v_vfsp;
2694 	if (((rnew > nrnode || !(rp->r_flags & RHASHED) || rp->r_error ||
2695 	    (vfsp->vfs_flag & VFS_UNMOUNTED)) && rp->r_count == 0)) {
2696 		if (rp->r_flags & RHASHED) {
2697 			rw_enter(&rp->r_hashq->r_lock, RW_WRITER);
2698 			mutex_enter(&vp->v_lock);
2699 			if (vp->v_count > 1) {
2700 				vp->v_count--;
2701 				mutex_exit(&vp->v_lock);
2702 				rw_exit(&rp->r_hashq->r_lock);
2703 				return;
2704 			}
2705 			mutex_exit(&vp->v_lock);
2706 			rp_rmhash_locked(rp);
2707 			rw_exit(&rp->r_hashq->r_lock);
2708 		}
2709 
2710 		rinactive(rp, cr);
2711 
2712 		/*
2713 		 * Recheck the vnode reference count.  We need to
2714 		 * make sure that another reference has not been
2715 		 * acquired while we were not holding v_lock.  The
2716 		 * rnode is not in the rnode hash queues, so the
2717 		 * only way for a reference to have been acquired
2718 		 * is for a VOP_PUTPAGE because the rnode was marked
2719 		 * with RDIRTY or for a modified page.  This
2720 		 * reference may have been acquired before our call
2721 		 * to rinactive.  The i/o may have been completed,
2722 		 * thus allowing rinactive to complete, but the
2723 		 * reference to the vnode may not have been released
2724 		 * yet.  In any case, the rnode can not be destroyed
2725 		 * until the other references to this vnode have been
2726 		 * released.  The other references will take care of
2727 		 * either destroying the rnode or placing it on the
2728 		 * rnode freelist.  If there are no other references,
2729 		 * then the rnode may be safely destroyed.
2730 		 */
2731 		mutex_enter(&vp->v_lock);
2732 		if (vp->v_count > 1) {
2733 			vp->v_count--;
2734 			mutex_exit(&vp->v_lock);
2735 			return;
2736 		}
2737 		mutex_exit(&vp->v_lock);
2738 
2739 		destroy_rnode(rp);
2740 		return;
2741 	}
2742 
2743 	/*
2744 	 * Lock the hash queue and then recheck the reference count
2745 	 * to ensure that no other threads have acquired a reference
2746 	 * to indicate that the rnode should not be placed on the
2747 	 * freelist.  If another reference has been acquired, then
2748 	 * just release this one and let the other thread complete
2749 	 * the processing of adding this rnode to the freelist.
2750 	 */
2751 	rw_enter(&rp->r_hashq->r_lock, RW_WRITER);
2752 
2753 	mutex_enter(&vp->v_lock);
2754 	if (vp->v_count > 1) {
2755 		vp->v_count--;
2756 		mutex_exit(&vp->v_lock);
2757 		rw_exit(&rp->r_hashq->r_lock);
2758 		return;
2759 	}
2760 	mutex_exit(&vp->v_lock);
2761 
2762 	/*
2763 	 * If there is no cached data or metadata for this file, then
2764 	 * put the rnode on the front of the freelist so that it will
2765 	 * be reused before other rnodes which may have cached data or
2766 	 * metadata associated with them.
2767 	 */
2768 	mutex_enter(&rpfreelist_lock);
2769 	if (rpfreelist == NULL) {
2770 		rp->r_freef = rp;
2771 		rp->r_freeb = rp;
2772 		rpfreelist = rp;
2773 	} else {
2774 		rp->r_freef = rpfreelist;
2775 		rp->r_freeb = rpfreelist->r_freeb;
2776 		rpfreelist->r_freeb->r_freef = rp;
2777 		rpfreelist->r_freeb = rp;
2778 		if (!vn_has_cached_data(vp) &&
2779 		    !HAVE_RDDIR_CACHE(rp) &&
2780 		    rp->r_symlink.contents == NULL &&
2781 		    rp->r_secattr == NULL &&
2782 		    rp->r_pathconf == NULL)
2783 			rpfreelist = rp;
2784 	}
2785 	mutex_exit(&rpfreelist_lock);
2786 
2787 	rw_exit(&rp->r_hashq->r_lock);
2788 }
2789 
2790 /*
2791  * Remove an rnode from the free list.
2792  *
2793  * The caller must be holding rpfreelist_lock and the rnode
2794  * must be on the freelist.
2795  */
2796 static void
2797 rp_rmfree(rnode_t *rp)
2798 {
2799 
2800 	ASSERT(MUTEX_HELD(&rpfreelist_lock));
2801 	ASSERT(rp->r_freef != NULL && rp->r_freeb != NULL);
2802 
2803 	if (rp == rpfreelist) {
2804 		rpfreelist = rp->r_freef;
2805 		if (rp == rpfreelist)
2806 			rpfreelist = NULL;
2807 	}
2808 
2809 	rp->r_freeb->r_freef = rp->r_freef;
2810 	rp->r_freef->r_freeb = rp->r_freeb;
2811 
2812 	rp->r_freef = rp->r_freeb = NULL;
2813 }
2814 
2815 /*
2816  * Put a rnode in the hash table.
2817  *
2818  * The caller must be holding the exclusive hash queue lock.
2819  */
2820 static void
2821 rp_addhash(rnode_t *rp)
2822 {
2823 
2824 	ASSERT(RW_WRITE_HELD(&rp->r_hashq->r_lock));
2825 	ASSERT(!(rp->r_flags & RHASHED));
2826 
2827 	rp->r_hashf = rp->r_hashq->r_hashf;
2828 	rp->r_hashq->r_hashf = rp;
2829 	rp->r_hashb = (rnode_t *)rp->r_hashq;
2830 	rp->r_hashf->r_hashb = rp;
2831 
2832 	mutex_enter(&rp->r_statelock);
2833 	rp->r_flags |= RHASHED;
2834 	mutex_exit(&rp->r_statelock);
2835 }
2836 
2837 /*
2838  * Remove a rnode from the hash table.
2839  *
2840  * The caller must be holding the hash queue lock.
2841  */
2842 static void
2843 rp_rmhash_locked(rnode_t *rp)
2844 {
2845 
2846 	ASSERT(RW_WRITE_HELD(&rp->r_hashq->r_lock));
2847 	ASSERT(rp->r_flags & RHASHED);
2848 
2849 	rp->r_hashb->r_hashf = rp->r_hashf;
2850 	rp->r_hashf->r_hashb = rp->r_hashb;
2851 
2852 	mutex_enter(&rp->r_statelock);
2853 	rp->r_flags &= ~RHASHED;
2854 	mutex_exit(&rp->r_statelock);
2855 }
2856 
2857 /*
2858  * Remove a rnode from the hash table.
2859  *
2860  * The caller must not be holding the hash queue lock.
2861  */
2862 void
2863 rp_rmhash(rnode_t *rp)
2864 {
2865 
2866 	rw_enter(&rp->r_hashq->r_lock, RW_WRITER);
2867 	rp_rmhash_locked(rp);
2868 	rw_exit(&rp->r_hashq->r_lock);
2869 }
2870 
2871 /*
2872  * Lookup a rnode by fhandle.
2873  *
2874  * The caller must be holding the hash queue lock, either shared or exclusive.
2875  */
2876 static rnode_t *
2877 rfind(rhashq_t *rhtp, nfs_fhandle *fh, struct vfs *vfsp)
2878 {
2879 	rnode_t *rp;
2880 	vnode_t *vp;
2881 
2882 	ASSERT(RW_LOCK_HELD(&rhtp->r_lock));
2883 
2884 	for (rp = rhtp->r_hashf; rp != (rnode_t *)rhtp; rp = rp->r_hashf) {
2885 		vp = RTOV(rp);
2886 		if (vp->v_vfsp == vfsp &&
2887 		    rp->r_fh.fh_len == fh->fh_len &&
2888 		    bcmp(rp->r_fh.fh_buf, fh->fh_buf, fh->fh_len) == 0) {
2889 			/*
2890 			 * remove rnode from free list, if necessary.
2891 			 */
2892 			if (rp->r_freef != NULL) {
2893 				mutex_enter(&rpfreelist_lock);
2894 				/*
2895 				 * If the rnode is on the freelist,
2896 				 * then remove it and use that reference
2897 				 * as the new reference.  Otherwise,
2898 				 * need to increment the reference count.
2899 				 */
2900 				if (rp->r_freef != NULL) {
2901 					rp_rmfree(rp);
2902 					mutex_exit(&rpfreelist_lock);
2903 				} else {
2904 					mutex_exit(&rpfreelist_lock);
2905 					VN_HOLD(vp);
2906 				}
2907 			} else
2908 				VN_HOLD(vp);
2909 			return (rp);
2910 		}
2911 	}
2912 	return (NULL);
2913 }
2914 
2915 /*
2916  * Return 1 if there is a active vnode belonging to this vfs in the
2917  * rtable cache.
2918  *
2919  * Several of these checks are done without holding the usual
2920  * locks.  This is safe because destroy_rtable(), rp_addfree(),
2921  * etc. will redo the necessary checks before actually destroying
2922  * any rnodes.
2923  */
2924 int
2925 check_rtable(struct vfs *vfsp)
2926 {
2927 	int index;
2928 	rnode_t *rp;
2929 	vnode_t *vp;
2930 
2931 	for (index = 0; index < rtablesize; index++) {
2932 		rw_enter(&rtable[index].r_lock, RW_READER);
2933 		for (rp = rtable[index].r_hashf;
2934 		    rp != (rnode_t *)(&rtable[index]);
2935 		    rp = rp->r_hashf) {
2936 			vp = RTOV(rp);
2937 			if (vp->v_vfsp == vfsp) {
2938 				if (rp->r_freef == NULL ||
2939 				    (vn_has_cached_data(vp) &&
2940 				    (rp->r_flags & RDIRTY)) ||
2941 				    rp->r_count > 0) {
2942 					rw_exit(&rtable[index].r_lock);
2943 					return (1);
2944 				}
2945 			}
2946 		}
2947 		rw_exit(&rtable[index].r_lock);
2948 	}
2949 	return (0);
2950 }
2951 
2952 /*
2953  * Destroy inactive vnodes from the hash queues which belong to this
2954  * vfs.  It is essential that we destroy all inactive vnodes during a
2955  * forced unmount as well as during a normal unmount.
2956  */
2957 void
2958 destroy_rtable(struct vfs *vfsp, cred_t *cr)
2959 {
2960 	int index;
2961 	rnode_t *rp;
2962 	rnode_t *rlist;
2963 	rnode_t *r_hashf;
2964 	vnode_t *vp;
2965 
2966 	rlist = NULL;
2967 
2968 	for (index = 0; index < rtablesize; index++) {
2969 		rw_enter(&rtable[index].r_lock, RW_WRITER);
2970 		for (rp = rtable[index].r_hashf;
2971 		    rp != (rnode_t *)(&rtable[index]);
2972 		    rp = r_hashf) {
2973 			/* save the hash pointer before destroying */
2974 			r_hashf = rp->r_hashf;
2975 			vp = RTOV(rp);
2976 			if (vp->v_vfsp == vfsp) {
2977 				mutex_enter(&rpfreelist_lock);
2978 				if (rp->r_freef != NULL) {
2979 					rp_rmfree(rp);
2980 					mutex_exit(&rpfreelist_lock);
2981 					rp_rmhash_locked(rp);
2982 					rp->r_hashf = rlist;
2983 					rlist = rp;
2984 				} else
2985 					mutex_exit(&rpfreelist_lock);
2986 			}
2987 		}
2988 		rw_exit(&rtable[index].r_lock);
2989 	}
2990 
2991 	for (rp = rlist; rp != NULL; rp = rlist) {
2992 		rlist = rp->r_hashf;
2993 		/*
2994 		 * This call to rp_addfree will end up destroying the
2995 		 * rnode, but in a safe way with the appropriate set
2996 		 * of checks done.
2997 		 */
2998 		rp_addfree(rp, cr);
2999 	}
3000 
3001 }
3002 
3003 /*
3004  * This routine destroys all the resources associated with the rnode
3005  * and then the rnode itself.
3006  */
3007 static void
3008 destroy_rnode(rnode_t *rp)
3009 {
3010 	vnode_t *vp;
3011 	vfs_t *vfsp;
3012 
3013 	vp = RTOV(rp);
3014 	vfsp = vp->v_vfsp;
3015 
3016 	ASSERT(vp->v_count == 1);
3017 	ASSERT(rp->r_count == 0);
3018 	ASSERT(rp->r_lmpl == NULL);
3019 	ASSERT(rp->r_mapcnt == 0);
3020 	ASSERT(!(rp->r_flags & RHASHED));
3021 	ASSERT(rp->r_freef == NULL && rp->r_freeb == NULL);
3022 	atomic_add_long((ulong_t *)&rnew, -1);
3023 #ifdef DEBUG
3024 	clstat_debug.nrnode.value.ui64--;
3025 #endif
3026 	nfs_rw_destroy(&rp->r_rwlock);
3027 	nfs_rw_destroy(&rp->r_lkserlock);
3028 	mutex_destroy(&rp->r_statelock);
3029 	cv_destroy(&rp->r_cv);
3030 	cv_destroy(&rp->r_commit.c_cv);
3031 	if (rp->r_flags & RDELMAPLIST)
3032 		list_destroy(&rp->r_indelmap);
3033 	nfs_free_r_path(rp);
3034 	avl_destroy(&rp->r_dir);
3035 	vn_invalid(vp);
3036 	vn_free(vp);
3037 	kmem_cache_free(rnode_cache, rp);
3038 	VFS_RELE(vfsp);
3039 }
3040 
3041 /*
3042  * Flush all vnodes in this (or every) vfs.
3043  * Used by nfs_sync and by nfs_unmount.
3044  */
3045 void
3046 rflush(struct vfs *vfsp, cred_t *cr)
3047 {
3048 	int index;
3049 	rnode_t *rp;
3050 	vnode_t *vp, **vplist;
3051 	long num, cnt;
3052 
3053 	/*
3054 	 * Check to see whether there is anything to do.
3055 	 */
3056 	num = rnew;
3057 	if (num == 0)
3058 		return;
3059 
3060 	/*
3061 	 * Allocate a slot for all currently active rnodes on the
3062 	 * supposition that they all may need flushing.
3063 	 */
3064 	vplist = kmem_alloc(num * sizeof (*vplist), KM_SLEEP);
3065 	cnt = 0;
3066 
3067 	/*
3068 	 * Walk the hash queues looking for rnodes with page
3069 	 * lists associated with them.  Make a list of these
3070 	 * files.
3071 	 */
3072 	for (index = 0; index < rtablesize; index++) {
3073 		rw_enter(&rtable[index].r_lock, RW_READER);
3074 		for (rp = rtable[index].r_hashf;
3075 		    rp != (rnode_t *)(&rtable[index]);
3076 		    rp = rp->r_hashf) {
3077 			vp = RTOV(rp);
3078 			/*
3079 			 * Don't bother sync'ing a vp if it
3080 			 * is part of virtual swap device or
3081 			 * if VFS is read-only
3082 			 */
3083 			if (IS_SWAPVP(vp) || vn_is_readonly(vp))
3084 				continue;
3085 			/*
3086 			 * If flushing all mounted file systems or
3087 			 * the vnode belongs to this vfs, has pages
3088 			 * and is marked as either dirty or mmap'd,
3089 			 * hold and add this vnode to the list of
3090 			 * vnodes to flush.
3091 			 */
3092 			if ((vfsp == NULL || vp->v_vfsp == vfsp) &&
3093 			    vn_has_cached_data(vp) &&
3094 			    ((rp->r_flags & RDIRTY) || rp->r_mapcnt > 0)) {
3095 				VN_HOLD(vp);
3096 				vplist[cnt++] = vp;
3097 				if (cnt == num) {
3098 					rw_exit(&rtable[index].r_lock);
3099 					goto toomany;
3100 				}
3101 			}
3102 		}
3103 		rw_exit(&rtable[index].r_lock);
3104 	}
3105 toomany:
3106 
3107 	/*
3108 	 * Flush and release all of the files on the list.
3109 	 */
3110 	while (cnt-- > 0) {
3111 		vp = vplist[cnt];
3112 		(void) VOP_PUTPAGE(vp, (u_offset_t)0, 0, B_ASYNC, cr, NULL);
3113 		VN_RELE(vp);
3114 	}
3115 
3116 	/*
3117 	 * Free the space allocated to hold the list.
3118 	 */
3119 	kmem_free(vplist, num * sizeof (*vplist));
3120 }
3121 
3122 /*
3123  * This probably needs to be larger than or equal to
3124  * log2(sizeof (struct rnode)) due to the way that rnodes are
3125  * allocated.
3126  */
3127 #define	ACACHE_SHIFT_BITS	9
3128 
3129 static int
3130 acachehash(rnode_t *rp, cred_t *cr)
3131 {
3132 
3133 	return ((((intptr_t)rp >> ACACHE_SHIFT_BITS) + crgetuid(cr)) &
3134 	    acachemask);
3135 }
3136 
3137 #ifdef DEBUG
3138 static long nfs_access_cache_hits = 0;
3139 static long nfs_access_cache_misses = 0;
3140 #endif
3141 
3142 nfs_access_type_t
3143 nfs_access_check(rnode_t *rp, uint32_t acc, cred_t *cr)
3144 {
3145 	vnode_t *vp;
3146 	acache_t *ap;
3147 	acache_hash_t *hp;
3148 	nfs_access_type_t all;
3149 
3150 	vp = RTOV(rp);
3151 	if (!ATTRCACHE_VALID(vp) || nfs_waitfor_purge_complete(vp))
3152 		return (NFS_ACCESS_UNKNOWN);
3153 
3154 	if (rp->r_acache != NULL) {
3155 		hp = &acache[acachehash(rp, cr)];
3156 		rw_enter(&hp->lock, RW_READER);
3157 		ap = hp->next;
3158 		while (ap != (acache_t *)hp) {
3159 			if (crcmp(ap->cred, cr) == 0 && ap->rnode == rp) {
3160 				if ((ap->known & acc) == acc) {
3161 #ifdef DEBUG
3162 					nfs_access_cache_hits++;
3163 #endif
3164 					if ((ap->allowed & acc) == acc)
3165 						all = NFS_ACCESS_ALLOWED;
3166 					else
3167 						all = NFS_ACCESS_DENIED;
3168 				} else {
3169 #ifdef DEBUG
3170 					nfs_access_cache_misses++;
3171 #endif
3172 					all = NFS_ACCESS_UNKNOWN;
3173 				}
3174 				rw_exit(&hp->lock);
3175 				return (all);
3176 			}
3177 			ap = ap->next;
3178 		}
3179 		rw_exit(&hp->lock);
3180 	}
3181 
3182 #ifdef DEBUG
3183 	nfs_access_cache_misses++;
3184 #endif
3185 	return (NFS_ACCESS_UNKNOWN);
3186 }
3187 
3188 void
3189 nfs_access_cache(rnode_t *rp, uint32_t acc, uint32_t resacc, cred_t *cr)
3190 {
3191 	acache_t *ap;
3192 	acache_t *nap;
3193 	acache_hash_t *hp;
3194 
3195 	hp = &acache[acachehash(rp, cr)];
3196 
3197 	/*
3198 	 * Allocate now assuming that mostly an allocation will be
3199 	 * required.  This allows the allocation to happen without
3200 	 * holding the hash bucket locked.
3201 	 */
3202 	nap = kmem_cache_alloc(acache_cache, KM_NOSLEEP);
3203 	if (nap != NULL) {
3204 		nap->known = acc;
3205 		nap->allowed = resacc;
3206 		nap->rnode = rp;
3207 		crhold(cr);
3208 		nap->cred = cr;
3209 		nap->hashq = hp;
3210 	}
3211 
3212 	rw_enter(&hp->lock, RW_WRITER);
3213 
3214 	if (rp->r_acache != NULL) {
3215 		ap = hp->next;
3216 		while (ap != (acache_t *)hp) {
3217 			if (crcmp(ap->cred, cr) == 0 && ap->rnode == rp) {
3218 				ap->known |= acc;
3219 				ap->allowed &= ~acc;
3220 				ap->allowed |= resacc;
3221 				rw_exit(&hp->lock);
3222 				if (nap != NULL) {
3223 					crfree(nap->cred);
3224 					kmem_cache_free(acache_cache, nap);
3225 				}
3226 				return;
3227 			}
3228 			ap = ap->next;
3229 		}
3230 	}
3231 
3232 	if (nap != NULL) {
3233 #ifdef DEBUG
3234 		clstat_debug.access.value.ui64++;
3235 #endif
3236 		nap->next = hp->next;
3237 		hp->next = nap;
3238 		nap->next->prev = nap;
3239 		nap->prev = (acache_t *)hp;
3240 
3241 		mutex_enter(&rp->r_statelock);
3242 		nap->list = rp->r_acache;
3243 		rp->r_acache = nap;
3244 		mutex_exit(&rp->r_statelock);
3245 	}
3246 
3247 	rw_exit(&hp->lock);
3248 }
3249 
3250 int
3251 nfs_access_purge_rp(rnode_t *rp)
3252 {
3253 	acache_t *ap;
3254 	acache_t *tmpap;
3255 	acache_t *rplist;
3256 
3257 	/*
3258 	 * If there aren't any cached entries, then there is nothing
3259 	 * to free.
3260 	 */
3261 	if (rp->r_acache == NULL)
3262 		return (0);
3263 
3264 	mutex_enter(&rp->r_statelock);
3265 	rplist = rp->r_acache;
3266 	rp->r_acache = NULL;
3267 	mutex_exit(&rp->r_statelock);
3268 
3269 	/*
3270 	 * Loop through each entry in the list pointed to in the
3271 	 * rnode.  Remove each of these entries from the hash
3272 	 * queue that it is on and remove it from the list in
3273 	 * the rnode.
3274 	 */
3275 	for (ap = rplist; ap != NULL; ap = tmpap) {
3276 		rw_enter(&ap->hashq->lock, RW_WRITER);
3277 		ap->prev->next = ap->next;
3278 		ap->next->prev = ap->prev;
3279 		rw_exit(&ap->hashq->lock);
3280 
3281 		tmpap = ap->list;
3282 		crfree(ap->cred);
3283 		kmem_cache_free(acache_cache, ap);
3284 #ifdef DEBUG
3285 		clstat_debug.access.value.ui64--;
3286 #endif
3287 	}
3288 
3289 	return (1);
3290 }
3291 
3292 static const char prefix[] = ".nfs";
3293 
3294 static kmutex_t newnum_lock;
3295 
3296 int
3297 newnum(void)
3298 {
3299 	static uint_t newnum = 0;
3300 	uint_t id;
3301 
3302 	mutex_enter(&newnum_lock);
3303 	if (newnum == 0)
3304 		newnum = gethrestime_sec() & 0xffff;
3305 	id = newnum++;
3306 	mutex_exit(&newnum_lock);
3307 	return (id);
3308 }
3309 
3310 char *
3311 newname(void)
3312 {
3313 	char *news;
3314 	char *s;
3315 	const char *p;
3316 	uint_t id;
3317 
3318 	id = newnum();
3319 	news = kmem_alloc(MAXNAMELEN, KM_SLEEP);
3320 	s = news;
3321 	p = prefix;
3322 	while (*p != '\0')
3323 		*s++ = *p++;
3324 	while (id != 0) {
3325 		*s++ = "0123456789ABCDEF"[id & 0x0f];
3326 		id >>= 4;
3327 	}
3328 	*s = '\0';
3329 	return (news);
3330 }
3331 
3332 /*
3333  * Snapshot callback for nfs:0:nfs_client as registered with the kstat
3334  * framework.
3335  */
3336 static int
3337 cl_snapshot(kstat_t *ksp, void *buf, int rw)
3338 {
3339 	ksp->ks_snaptime = gethrtime();
3340 	if (rw == KSTAT_WRITE) {
3341 		bcopy(buf, ksp->ks_private, sizeof (clstat_tmpl));
3342 #ifdef DEBUG
3343 		/*
3344 		 * Currently only the global zone can write to kstats, but we
3345 		 * add the check just for paranoia.
3346 		 */
3347 		if (INGLOBALZONE(curproc))
3348 			bcopy((char *)buf + sizeof (clstat_tmpl), &clstat_debug,
3349 			    sizeof (clstat_debug));
3350 #endif
3351 	} else {
3352 		bcopy(ksp->ks_private, buf, sizeof (clstat_tmpl));
3353 #ifdef DEBUG
3354 		/*
3355 		 * If we're displaying the "global" debug kstat values, we
3356 		 * display them as-is to all zones since in fact they apply to
3357 		 * the system as a whole.
3358 		 */
3359 		bcopy(&clstat_debug, (char *)buf + sizeof (clstat_tmpl),
3360 		    sizeof (clstat_debug));
3361 #endif
3362 	}
3363 	return (0);
3364 }
3365 
3366 static void *
3367 clinit_zone(zoneid_t zoneid)
3368 {
3369 	kstat_t *nfs_client_kstat;
3370 	struct nfs_clnt *nfscl;
3371 	uint_t ndata;
3372 
3373 	nfscl = kmem_alloc(sizeof (*nfscl), KM_SLEEP);
3374 	mutex_init(&nfscl->nfscl_chtable_lock, NULL, MUTEX_DEFAULT, NULL);
3375 	nfscl->nfscl_chtable = NULL;
3376 	nfscl->nfscl_zoneid = zoneid;
3377 
3378 	bcopy(&clstat_tmpl, &nfscl->nfscl_stat, sizeof (clstat_tmpl));
3379 	ndata = sizeof (clstat_tmpl) / sizeof (kstat_named_t);
3380 #ifdef DEBUG
3381 	ndata += sizeof (clstat_debug) / sizeof (kstat_named_t);
3382 #endif
3383 	if ((nfs_client_kstat = kstat_create_zone("nfs", 0, "nfs_client",
3384 	    "misc", KSTAT_TYPE_NAMED, ndata,
3385 	    KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_WRITABLE, zoneid)) != NULL) {
3386 		nfs_client_kstat->ks_private = &nfscl->nfscl_stat;
3387 		nfs_client_kstat->ks_snapshot = cl_snapshot;
3388 		kstat_install(nfs_client_kstat);
3389 	}
3390 	mutex_enter(&nfs_clnt_list_lock);
3391 	list_insert_head(&nfs_clnt_list, nfscl);
3392 	mutex_exit(&nfs_clnt_list_lock);
3393 	return (nfscl);
3394 }
3395 
3396 /*ARGSUSED*/
3397 static void
3398 clfini_zone(zoneid_t zoneid, void *arg)
3399 {
3400 	struct nfs_clnt *nfscl = arg;
3401 	chhead_t *chp, *next;
3402 
3403 	if (nfscl == NULL)
3404 		return;
3405 	mutex_enter(&nfs_clnt_list_lock);
3406 	list_remove(&nfs_clnt_list, nfscl);
3407 	mutex_exit(&nfs_clnt_list_lock);
3408 	clreclaim_zone(nfscl, 0);
3409 	for (chp = nfscl->nfscl_chtable; chp != NULL; chp = next) {
3410 		ASSERT(chp->ch_list == NULL);
3411 		kmem_free(chp->ch_protofmly, strlen(chp->ch_protofmly) + 1);
3412 		next = chp->ch_next;
3413 		kmem_free(chp, sizeof (*chp));
3414 	}
3415 	kstat_delete_byname_zone("nfs", 0, "nfs_client", zoneid);
3416 	mutex_destroy(&nfscl->nfscl_chtable_lock);
3417 	kmem_free(nfscl, sizeof (*nfscl));
3418 }
3419 
3420 /*
3421  * Called by endpnt_destructor to make sure the client handles are
3422  * cleaned up before the RPC endpoints.  This becomes a no-op if
3423  * clfini_zone (above) is called first.  This function is needed
3424  * (rather than relying on clfini_zone to clean up) because the ZSD
3425  * callbacks have no ordering mechanism, so we have no way to ensure
3426  * that clfini_zone is called before endpnt_destructor.
3427  */
3428 void
3429 clcleanup_zone(zoneid_t zoneid)
3430 {
3431 	struct nfs_clnt *nfscl;
3432 
3433 	mutex_enter(&nfs_clnt_list_lock);
3434 	nfscl = list_head(&nfs_clnt_list);
3435 	for (; nfscl != NULL; nfscl = list_next(&nfs_clnt_list, nfscl)) {
3436 		if (nfscl->nfscl_zoneid == zoneid) {
3437 			clreclaim_zone(nfscl, 0);
3438 			break;
3439 		}
3440 	}
3441 	mutex_exit(&nfs_clnt_list_lock);
3442 }
3443 
3444 int
3445 nfs_subrinit(void)
3446 {
3447 	int i;
3448 	ulong_t nrnode_max;
3449 
3450 	/*
3451 	 * Allocate and initialize the rnode hash queues
3452 	 */
3453 	if (nrnode <= 0)
3454 		nrnode = ncsize;
3455 	nrnode_max = (ulong_t)((kmem_maxavail() >> 2) / sizeof (struct rnode));
3456 	if (nrnode > nrnode_max || (nrnode == 0 && ncsize == 0)) {
3457 		zcmn_err(GLOBAL_ZONEID, CE_NOTE,
3458 		    "!setting nrnode to max value of %ld", nrnode_max);
3459 		nrnode = nrnode_max;
3460 	}
3461 
3462 	rtablesize = 1 << highbit(nrnode / hashlen);
3463 	rtablemask = rtablesize - 1;
3464 	rtable = kmem_alloc(rtablesize * sizeof (*rtable), KM_SLEEP);
3465 	for (i = 0; i < rtablesize; i++) {
3466 		rtable[i].r_hashf = (rnode_t *)(&rtable[i]);
3467 		rtable[i].r_hashb = (rnode_t *)(&rtable[i]);
3468 		rw_init(&rtable[i].r_lock, NULL, RW_DEFAULT, NULL);
3469 	}
3470 	rnode_cache = kmem_cache_create("rnode_cache", sizeof (rnode_t),
3471 	    0, NULL, NULL, nfs_reclaim, NULL, NULL, 0);
3472 
3473 	/*
3474 	 * Allocate and initialize the access cache
3475 	 */
3476 
3477 	/*
3478 	 * Initial guess is one access cache entry per rnode unless
3479 	 * nacache is set to a non-zero value and then it is used to
3480 	 * indicate a guess at the number of access cache entries.
3481 	 */
3482 	if (nacache > 0)
3483 		acachesize = 1 << highbit(nacache / hashlen);
3484 	else
3485 		acachesize = rtablesize;
3486 	acachemask = acachesize - 1;
3487 	acache = kmem_alloc(acachesize * sizeof (*acache), KM_SLEEP);
3488 	for (i = 0; i < acachesize; i++) {
3489 		acache[i].next = (acache_t *)&acache[i];
3490 		acache[i].prev = (acache_t *)&acache[i];
3491 		rw_init(&acache[i].lock, NULL, RW_DEFAULT, NULL);
3492 	}
3493 	acache_cache = kmem_cache_create("nfs_access_cache",
3494 	    sizeof (acache_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
3495 	/*
3496 	 * Allocate and initialize the client handle cache
3497 	 */
3498 	chtab_cache = kmem_cache_create("client_handle_cache",
3499 	    sizeof (struct chtab), 0, NULL, NULL, clreclaim, NULL, NULL, 0);
3500 	/*
3501 	 * Initialize the list of per-zone client handles (and associated data).
3502 	 * This needs to be done before we call zone_key_create().
3503 	 */
3504 	list_create(&nfs_clnt_list, sizeof (struct nfs_clnt),
3505 	    offsetof(struct nfs_clnt, nfscl_node));
3506 	/*
3507 	 * Initialize the zone_key for per-zone client handle lists.
3508 	 */
3509 	zone_key_create(&nfsclnt_zone_key, clinit_zone, NULL, clfini_zone);
3510 	/*
3511 	 * Initialize the various mutexes and reader/writer locks
3512 	 */
3513 	mutex_init(&rpfreelist_lock, NULL, MUTEX_DEFAULT, NULL);
3514 	mutex_init(&newnum_lock, NULL, MUTEX_DEFAULT, NULL);
3515 	mutex_init(&nfs_minor_lock, NULL, MUTEX_DEFAULT, NULL);
3516 
3517 	/*
3518 	 * Assign unique major number for all nfs mounts
3519 	 */
3520 	if ((nfs_major = getudev()) == -1) {
3521 		zcmn_err(GLOBAL_ZONEID, CE_WARN,
3522 		    "nfs: init: can't get unique device number");
3523 		nfs_major = 0;
3524 	}
3525 	nfs_minor = 0;
3526 
3527 	if (nfs3_jukebox_delay == 0)
3528 		nfs3_jukebox_delay = NFS3_JUKEBOX_DELAY;
3529 
3530 	return (0);
3531 }
3532 
3533 void
3534 nfs_subrfini(void)
3535 {
3536 	int i;
3537 
3538 	/*
3539 	 * Deallocate the rnode hash queues
3540 	 */
3541 	kmem_cache_destroy(rnode_cache);
3542 
3543 	for (i = 0; i < rtablesize; i++)
3544 		rw_destroy(&rtable[i].r_lock);
3545 	kmem_free(rtable, rtablesize * sizeof (*rtable));
3546 
3547 	/*
3548 	 * Deallocated the access cache
3549 	 */
3550 	kmem_cache_destroy(acache_cache);
3551 
3552 	for (i = 0; i < acachesize; i++)
3553 		rw_destroy(&acache[i].lock);
3554 	kmem_free(acache, acachesize * sizeof (*acache));
3555 
3556 	/*
3557 	 * Deallocate the client handle cache
3558 	 */
3559 	kmem_cache_destroy(chtab_cache);
3560 
3561 	/*
3562 	 * Destroy the various mutexes and reader/writer locks
3563 	 */
3564 	mutex_destroy(&rpfreelist_lock);
3565 	mutex_destroy(&newnum_lock);
3566 	mutex_destroy(&nfs_minor_lock);
3567 	(void) zone_key_delete(nfsclnt_zone_key);
3568 }
3569 
3570 enum nfsstat
3571 puterrno(int error)
3572 {
3573 
3574 	switch (error) {
3575 	case EOPNOTSUPP:
3576 		return (NFSERR_OPNOTSUPP);
3577 	case ENAMETOOLONG:
3578 		return (NFSERR_NAMETOOLONG);
3579 	case ENOTEMPTY:
3580 		return (NFSERR_NOTEMPTY);
3581 	case EDQUOT:
3582 		return (NFSERR_DQUOT);
3583 	case ESTALE:
3584 		return (NFSERR_STALE);
3585 	case EREMOTE:
3586 		return (NFSERR_REMOTE);
3587 	case ENOSYS:
3588 		return (NFSERR_OPNOTSUPP);
3589 	case EOVERFLOW:
3590 		return (NFSERR_INVAL);
3591 	default:
3592 		return ((enum nfsstat)error);
3593 	}
3594 	/* NOTREACHED */
3595 }
3596 
3597 int
3598 geterrno(enum nfsstat status)
3599 {
3600 
3601 	switch (status) {
3602 	case NFSERR_OPNOTSUPP:
3603 		return (EOPNOTSUPP);
3604 	case NFSERR_NAMETOOLONG:
3605 		return (ENAMETOOLONG);
3606 	case NFSERR_NOTEMPTY:
3607 		return (ENOTEMPTY);
3608 	case NFSERR_DQUOT:
3609 		return (EDQUOT);
3610 	case NFSERR_STALE:
3611 		return (ESTALE);
3612 	case NFSERR_REMOTE:
3613 		return (EREMOTE);
3614 	case NFSERR_WFLUSH:
3615 		return (EIO);
3616 	default:
3617 		return ((int)status);
3618 	}
3619 	/* NOTREACHED */
3620 }
3621 
3622 enum nfsstat3
3623 puterrno3(int error)
3624 {
3625 
3626 #ifdef DEBUG
3627 	switch (error) {
3628 	case 0:
3629 		return (NFS3_OK);
3630 	case EPERM:
3631 		return (NFS3ERR_PERM);
3632 	case ENOENT:
3633 		return (NFS3ERR_NOENT);
3634 	case EIO:
3635 		return (NFS3ERR_IO);
3636 	case ENXIO:
3637 		return (NFS3ERR_NXIO);
3638 	case EACCES:
3639 		return (NFS3ERR_ACCES);
3640 	case EEXIST:
3641 		return (NFS3ERR_EXIST);
3642 	case EXDEV:
3643 		return (NFS3ERR_XDEV);
3644 	case ENODEV:
3645 		return (NFS3ERR_NODEV);
3646 	case ENOTDIR:
3647 		return (NFS3ERR_NOTDIR);
3648 	case EISDIR:
3649 		return (NFS3ERR_ISDIR);
3650 	case EINVAL:
3651 		return (NFS3ERR_INVAL);
3652 	case EFBIG:
3653 		return (NFS3ERR_FBIG);
3654 	case ENOSPC:
3655 		return (NFS3ERR_NOSPC);
3656 	case EROFS:
3657 		return (NFS3ERR_ROFS);
3658 	case EMLINK:
3659 		return (NFS3ERR_MLINK);
3660 	case ENAMETOOLONG:
3661 		return (NFS3ERR_NAMETOOLONG);
3662 	case ENOTEMPTY:
3663 		return (NFS3ERR_NOTEMPTY);
3664 	case EDQUOT:
3665 		return (NFS3ERR_DQUOT);
3666 	case ESTALE:
3667 		return (NFS3ERR_STALE);
3668 	case EREMOTE:
3669 		return (NFS3ERR_REMOTE);
3670 	case ENOSYS:
3671 	case EOPNOTSUPP:
3672 		return (NFS3ERR_NOTSUPP);
3673 	case EOVERFLOW:
3674 		return (NFS3ERR_INVAL);
3675 	default:
3676 		zcmn_err(getzoneid(), CE_WARN,
3677 		    "puterrno3: got error %d", error);
3678 		return ((enum nfsstat3)error);
3679 	}
3680 #else
3681 	switch (error) {
3682 	case ENAMETOOLONG:
3683 		return (NFS3ERR_NAMETOOLONG);
3684 	case ENOTEMPTY:
3685 		return (NFS3ERR_NOTEMPTY);
3686 	case EDQUOT:
3687 		return (NFS3ERR_DQUOT);
3688 	case ESTALE:
3689 		return (NFS3ERR_STALE);
3690 	case ENOSYS:
3691 	case EOPNOTSUPP:
3692 		return (NFS3ERR_NOTSUPP);
3693 	case EREMOTE:
3694 		return (NFS3ERR_REMOTE);
3695 	case EOVERFLOW:
3696 		return (NFS3ERR_INVAL);
3697 	default:
3698 		return ((enum nfsstat3)error);
3699 	}
3700 #endif
3701 }
3702 
3703 int
3704 geterrno3(enum nfsstat3 status)
3705 {
3706 
3707 #ifdef DEBUG
3708 	switch (status) {
3709 	case NFS3_OK:
3710 		return (0);
3711 	case NFS3ERR_PERM:
3712 		return (EPERM);
3713 	case NFS3ERR_NOENT:
3714 		return (ENOENT);
3715 	case NFS3ERR_IO:
3716 		return (EIO);
3717 	case NFS3ERR_NXIO:
3718 		return (ENXIO);
3719 	case NFS3ERR_ACCES:
3720 		return (EACCES);
3721 	case NFS3ERR_EXIST:
3722 		return (EEXIST);
3723 	case NFS3ERR_XDEV:
3724 		return (EXDEV);
3725 	case NFS3ERR_NODEV:
3726 		return (ENODEV);
3727 	case NFS3ERR_NOTDIR:
3728 		return (ENOTDIR);
3729 	case NFS3ERR_ISDIR:
3730 		return (EISDIR);
3731 	case NFS3ERR_INVAL:
3732 		return (EINVAL);
3733 	case NFS3ERR_FBIG:
3734 		return (EFBIG);
3735 	case NFS3ERR_NOSPC:
3736 		return (ENOSPC);
3737 	case NFS3ERR_ROFS:
3738 		return (EROFS);
3739 	case NFS3ERR_MLINK:
3740 		return (EMLINK);
3741 	case NFS3ERR_NAMETOOLONG:
3742 		return (ENAMETOOLONG);
3743 	case NFS3ERR_NOTEMPTY:
3744 		return (ENOTEMPTY);
3745 	case NFS3ERR_DQUOT:
3746 		return (EDQUOT);
3747 	case NFS3ERR_STALE:
3748 		return (ESTALE);
3749 	case NFS3ERR_REMOTE:
3750 		return (EREMOTE);
3751 	case NFS3ERR_BADHANDLE:
3752 		return (ESTALE);
3753 	case NFS3ERR_NOT_SYNC:
3754 		return (EINVAL);
3755 	case NFS3ERR_BAD_COOKIE:
3756 		return (ENOENT);
3757 	case NFS3ERR_NOTSUPP:
3758 		return (EOPNOTSUPP);
3759 	case NFS3ERR_TOOSMALL:
3760 		return (EINVAL);
3761 	case NFS3ERR_SERVERFAULT:
3762 		return (EIO);
3763 	case NFS3ERR_BADTYPE:
3764 		return (EINVAL);
3765 	case NFS3ERR_JUKEBOX:
3766 		return (ENXIO);
3767 	default:
3768 		zcmn_err(getzoneid(), CE_WARN,
3769 		    "geterrno3: got status %d", status);
3770 		return ((int)status);
3771 	}
3772 #else
3773 	switch (status) {
3774 	case NFS3ERR_NAMETOOLONG:
3775 		return (ENAMETOOLONG);
3776 	case NFS3ERR_NOTEMPTY:
3777 		return (ENOTEMPTY);
3778 	case NFS3ERR_DQUOT:
3779 		return (EDQUOT);
3780 	case NFS3ERR_STALE:
3781 	case NFS3ERR_BADHANDLE:
3782 		return (ESTALE);
3783 	case NFS3ERR_NOTSUPP:
3784 		return (EOPNOTSUPP);
3785 	case NFS3ERR_REMOTE:
3786 		return (EREMOTE);
3787 	case NFS3ERR_NOT_SYNC:
3788 	case NFS3ERR_TOOSMALL:
3789 	case NFS3ERR_BADTYPE:
3790 		return (EINVAL);
3791 	case NFS3ERR_BAD_COOKIE:
3792 		return (ENOENT);
3793 	case NFS3ERR_SERVERFAULT:
3794 		return (EIO);
3795 	case NFS3ERR_JUKEBOX:
3796 		return (ENXIO);
3797 	default:
3798 		return ((int)status);
3799 	}
3800 #endif
3801 }
3802 
3803 rddir_cache *
3804 rddir_cache_alloc(int flags)
3805 {
3806 	rddir_cache *rc;
3807 
3808 	rc = kmem_alloc(sizeof (*rc), flags);
3809 	if (rc != NULL) {
3810 		rc->entries = NULL;
3811 		rc->flags = RDDIR;
3812 		cv_init(&rc->cv, NULL, CV_DEFAULT, NULL);
3813 		mutex_init(&rc->lock, NULL, MUTEX_DEFAULT, NULL);
3814 		rc->count = 1;
3815 #ifdef DEBUG
3816 		atomic_add_64(&clstat_debug.dirent.value.ui64, 1);
3817 #endif
3818 	}
3819 	return (rc);
3820 }
3821 
3822 static void
3823 rddir_cache_free(rddir_cache *rc)
3824 {
3825 
3826 #ifdef DEBUG
3827 	atomic_add_64(&clstat_debug.dirent.value.ui64, -1);
3828 #endif
3829 	if (rc->entries != NULL) {
3830 #ifdef DEBUG
3831 		rddir_cache_buf_free(rc->entries, rc->buflen);
3832 #else
3833 		kmem_free(rc->entries, rc->buflen);
3834 #endif
3835 	}
3836 	cv_destroy(&rc->cv);
3837 	mutex_destroy(&rc->lock);
3838 	kmem_free(rc, sizeof (*rc));
3839 }
3840 
3841 void
3842 rddir_cache_hold(rddir_cache *rc)
3843 {
3844 
3845 	mutex_enter(&rc->lock);
3846 	rc->count++;
3847 	mutex_exit(&rc->lock);
3848 }
3849 
3850 void
3851 rddir_cache_rele(rddir_cache *rc)
3852 {
3853 
3854 	mutex_enter(&rc->lock);
3855 	ASSERT(rc->count > 0);
3856 	if (--rc->count == 0) {
3857 		mutex_exit(&rc->lock);
3858 		rddir_cache_free(rc);
3859 	} else
3860 		mutex_exit(&rc->lock);
3861 }
3862 
3863 #ifdef DEBUG
3864 char *
3865 rddir_cache_buf_alloc(size_t size, int flags)
3866 {
3867 	char *rc;
3868 
3869 	rc = kmem_alloc(size, flags);
3870 	if (rc != NULL)
3871 		atomic_add_64(&clstat_debug.dirents.value.ui64, size);
3872 	return (rc);
3873 }
3874 
3875 void
3876 rddir_cache_buf_free(void *addr, size_t size)
3877 {
3878 
3879 	atomic_add_64(&clstat_debug.dirents.value.ui64, -(int64_t)size);
3880 	kmem_free(addr, size);
3881 }
3882 #endif
3883 
3884 static int
3885 nfs_free_data_reclaim(rnode_t *rp)
3886 {
3887 	char *contents;
3888 	int size;
3889 	vsecattr_t *vsp;
3890 	nfs3_pathconf_info *info;
3891 	int freed;
3892 	cred_t *cred;
3893 
3894 	/*
3895 	 * Free any held credentials and caches which
3896 	 * may be associated with this rnode.
3897 	 */
3898 	mutex_enter(&rp->r_statelock);
3899 	cred = rp->r_cred;
3900 	rp->r_cred = NULL;
3901 	contents = rp->r_symlink.contents;
3902 	size = rp->r_symlink.size;
3903 	rp->r_symlink.contents = NULL;
3904 	vsp = rp->r_secattr;
3905 	rp->r_secattr = NULL;
3906 	info = rp->r_pathconf;
3907 	rp->r_pathconf = NULL;
3908 	mutex_exit(&rp->r_statelock);
3909 
3910 	if (cred != NULL)
3911 		crfree(cred);
3912 
3913 	/*
3914 	 * Free the access cache entries.
3915 	 */
3916 	freed = nfs_access_purge_rp(rp);
3917 
3918 	if (!HAVE_RDDIR_CACHE(rp) &&
3919 	    contents == NULL &&
3920 	    vsp == NULL &&
3921 	    info == NULL)
3922 		return (freed);
3923 
3924 	/*
3925 	 * Free the readdir cache entries
3926 	 */
3927 	if (HAVE_RDDIR_CACHE(rp))
3928 		nfs_purge_rddir_cache(RTOV(rp));
3929 
3930 	/*
3931 	 * Free the symbolic link cache.
3932 	 */
3933 	if (contents != NULL) {
3934 
3935 		kmem_free((void *)contents, size);
3936 	}
3937 
3938 	/*
3939 	 * Free any cached ACL.
3940 	 */
3941 	if (vsp != NULL)
3942 		nfs_acl_free(vsp);
3943 
3944 	/*
3945 	 * Free any cached pathconf information.
3946 	 */
3947 	if (info != NULL)
3948 		kmem_free(info, sizeof (*info));
3949 
3950 	return (1);
3951 }
3952 
3953 static int
3954 nfs_active_data_reclaim(rnode_t *rp)
3955 {
3956 	char *contents;
3957 	int size;
3958 	vsecattr_t *vsp;
3959 	nfs3_pathconf_info *info;
3960 	int freed;
3961 
3962 	/*
3963 	 * Free any held credentials and caches which
3964 	 * may be associated with this rnode.
3965 	 */
3966 	if (!mutex_tryenter(&rp->r_statelock))
3967 		return (0);
3968 	contents = rp->r_symlink.contents;
3969 	size = rp->r_symlink.size;
3970 	rp->r_symlink.contents = NULL;
3971 	vsp = rp->r_secattr;
3972 	rp->r_secattr = NULL;
3973 	info = rp->r_pathconf;
3974 	rp->r_pathconf = NULL;
3975 	mutex_exit(&rp->r_statelock);
3976 
3977 	/*
3978 	 * Free the access cache entries.
3979 	 */
3980 	freed = nfs_access_purge_rp(rp);
3981 
3982 	if (!HAVE_RDDIR_CACHE(rp) &&
3983 	    contents == NULL &&
3984 	    vsp == NULL &&
3985 	    info == NULL)
3986 		return (freed);
3987 
3988 	/*
3989 	 * Free the readdir cache entries
3990 	 */
3991 	if (HAVE_RDDIR_CACHE(rp))
3992 		nfs_purge_rddir_cache(RTOV(rp));
3993 
3994 	/*
3995 	 * Free the symbolic link cache.
3996 	 */
3997 	if (contents != NULL) {
3998 
3999 		kmem_free((void *)contents, size);
4000 	}
4001 
4002 	/*
4003 	 * Free any cached ACL.
4004 	 */
4005 	if (vsp != NULL)
4006 		nfs_acl_free(vsp);
4007 
4008 	/*
4009 	 * Free any cached pathconf information.
4010 	 */
4011 	if (info != NULL)
4012 		kmem_free(info, sizeof (*info));
4013 
4014 	return (1);
4015 }
4016 
4017 static int
4018 nfs_free_reclaim(void)
4019 {
4020 	int freed;
4021 	rnode_t *rp;
4022 
4023 #ifdef DEBUG
4024 	clstat_debug.f_reclaim.value.ui64++;
4025 #endif
4026 	freed = 0;
4027 	mutex_enter(&rpfreelist_lock);
4028 	rp = rpfreelist;
4029 	if (rp != NULL) {
4030 		do {
4031 			if (nfs_free_data_reclaim(rp))
4032 				freed = 1;
4033 		} while ((rp = rp->r_freef) != rpfreelist);
4034 	}
4035 	mutex_exit(&rpfreelist_lock);
4036 	return (freed);
4037 }
4038 
4039 static int
4040 nfs_active_reclaim(void)
4041 {
4042 	int freed;
4043 	int index;
4044 	rnode_t *rp;
4045 
4046 #ifdef DEBUG
4047 	clstat_debug.a_reclaim.value.ui64++;
4048 #endif
4049 	freed = 0;
4050 	for (index = 0; index < rtablesize; index++) {
4051 		rw_enter(&rtable[index].r_lock, RW_READER);
4052 		for (rp = rtable[index].r_hashf;
4053 		    rp != (rnode_t *)(&rtable[index]);
4054 		    rp = rp->r_hashf) {
4055 			if (nfs_active_data_reclaim(rp))
4056 				freed = 1;
4057 		}
4058 		rw_exit(&rtable[index].r_lock);
4059 	}
4060 	return (freed);
4061 }
4062 
4063 static int
4064 nfs_rnode_reclaim(void)
4065 {
4066 	int freed;
4067 	rnode_t *rp;
4068 	vnode_t *vp;
4069 
4070 #ifdef DEBUG
4071 	clstat_debug.r_reclaim.value.ui64++;
4072 #endif
4073 	freed = 0;
4074 	mutex_enter(&rpfreelist_lock);
4075 	while ((rp = rpfreelist) != NULL) {
4076 		rp_rmfree(rp);
4077 		mutex_exit(&rpfreelist_lock);
4078 		if (rp->r_flags & RHASHED) {
4079 			vp = RTOV(rp);
4080 			rw_enter(&rp->r_hashq->r_lock, RW_WRITER);
4081 			mutex_enter(&vp->v_lock);
4082 			if (vp->v_count > 1) {
4083 				vp->v_count--;
4084 				mutex_exit(&vp->v_lock);
4085 				rw_exit(&rp->r_hashq->r_lock);
4086 				mutex_enter(&rpfreelist_lock);
4087 				continue;
4088 			}
4089 			mutex_exit(&vp->v_lock);
4090 			rp_rmhash_locked(rp);
4091 			rw_exit(&rp->r_hashq->r_lock);
4092 		}
4093 		/*
4094 		 * This call to rp_addfree will end up destroying the
4095 		 * rnode, but in a safe way with the appropriate set
4096 		 * of checks done.
4097 		 */
4098 		rp_addfree(rp, CRED());
4099 		mutex_enter(&rpfreelist_lock);
4100 	}
4101 	mutex_exit(&rpfreelist_lock);
4102 	return (freed);
4103 }
4104 
4105 /*ARGSUSED*/
4106 static void
4107 nfs_reclaim(void *cdrarg)
4108 {
4109 
4110 #ifdef DEBUG
4111 	clstat_debug.reclaim.value.ui64++;
4112 #endif
4113 	if (nfs_free_reclaim())
4114 		return;
4115 
4116 	if (nfs_active_reclaim())
4117 		return;
4118 
4119 	(void) nfs_rnode_reclaim();
4120 }
4121 
4122 /*
4123  * NFS client failover support
4124  *
4125  * Routines to copy filehandles
4126  */
4127 void
4128 nfscopyfh(caddr_t fhp, vnode_t *vp)
4129 {
4130 	fhandle_t *dest = (fhandle_t *)fhp;
4131 
4132 	if (dest != NULL)
4133 		*dest = *VTOFH(vp);
4134 }
4135 
4136 void
4137 nfs3copyfh(caddr_t fhp, vnode_t *vp)
4138 {
4139 	nfs_fh3 *dest = (nfs_fh3 *)fhp;
4140 
4141 	if (dest != NULL)
4142 		*dest = *VTOFH3(vp);
4143 }
4144 
4145 /*
4146  * NFS client failover support
4147  *
4148  * failover_safe() will test various conditions to ensure that
4149  * failover is permitted for this vnode.  It will be denied
4150  * if:
4151  *	1) the operation in progress does not support failover (NULL fi)
4152  *	2) there are no available replicas (NULL mi_servers->sv_next)
4153  *	3) any locks are outstanding on this file
4154  */
4155 static int
4156 failover_safe(failinfo_t *fi)
4157 {
4158 
4159 	/*
4160 	 * Does this op permit failover?
4161 	 */
4162 	if (fi == NULL || fi->vp == NULL)
4163 		return (0);
4164 
4165 	/*
4166 	 * Are there any alternates to failover to?
4167 	 */
4168 	if (VTOMI(fi->vp)->mi_servers->sv_next == NULL)
4169 		return (0);
4170 
4171 	/*
4172 	 * Disable check; we've forced local locking
4173 	 *
4174 	 * if (flk_has_remote_locks(fi->vp))
4175 	 *	return (0);
4176 	 */
4177 
4178 	/*
4179 	 * If we have no partial path, we can't do anything
4180 	 */
4181 	if (VTOR(fi->vp)->r_path == NULL)
4182 		return (0);
4183 
4184 	return (1);
4185 }
4186 
4187 #include <sys/thread.h>
4188 
4189 /*
4190  * NFS client failover support
4191  *
4192  * failover_newserver() will start a search for a new server,
4193  * preferably by starting an async thread to do the work.  If
4194  * someone is already doing this (recognizable by MI_BINDINPROG
4195  * being set), it will simply return and the calling thread
4196  * will queue on the mi_failover_cv condition variable.
4197  */
4198 static void
4199 failover_newserver(mntinfo_t *mi)
4200 {
4201 	/*
4202 	 * Check if someone else is doing this already
4203 	 */
4204 	mutex_enter(&mi->mi_lock);
4205 	if (mi->mi_flags & MI_BINDINPROG) {
4206 		mutex_exit(&mi->mi_lock);
4207 		return;
4208 	}
4209 	mi->mi_flags |= MI_BINDINPROG;
4210 
4211 	/*
4212 	 * Need to hold the vfs struct so that it can't be released
4213 	 * while the failover thread is selecting a new server.
4214 	 */
4215 	VFS_HOLD(mi->mi_vfsp);
4216 
4217 	/*
4218 	 * Start a thread to do the real searching.
4219 	 */
4220 	(void) zthread_create(NULL, 0, failover_thread, mi, 0, minclsyspri);
4221 
4222 	mutex_exit(&mi->mi_lock);
4223 }
4224 
4225 /*
4226  * NFS client failover support
4227  *
4228  * failover_thread() will find a new server to replace the one
4229  * currently in use, wake up other threads waiting on this mount
4230  * point, and die.  It will start at the head of the server list
4231  * and poll servers until it finds one with an NFS server which is
4232  * registered and responds to a NULL procedure ping.
4233  *
4234  * XXX failover_thread is unsafe within the scope of the
4235  * present model defined for cpr to suspend the system.
4236  * Specifically, over-the-wire calls made by the thread
4237  * are unsafe. The thread needs to be reevaluated in case of
4238  * future updates to the cpr suspend model.
4239  */
4240 static void
4241 failover_thread(mntinfo_t *mi)
4242 {
4243 	servinfo_t *svp = NULL;
4244 	CLIENT *cl;
4245 	enum clnt_stat status;
4246 	struct timeval tv;
4247 	int error;
4248 	int oncethru = 0;
4249 	callb_cpr_t cprinfo;
4250 	rnode_t *rp;
4251 	int index;
4252 	char *srvnames;
4253 	size_t srvnames_len;
4254 	struct nfs_clnt *nfscl = NULL;
4255 	zoneid_t zoneid = getzoneid();
4256 
4257 #ifdef DEBUG
4258 	/*
4259 	 * This is currently only needed to access counters which exist on
4260 	 * DEBUG kernels, hence we don't want to pay the penalty of the lookup
4261 	 * on non-DEBUG kernels.
4262 	 */
4263 	nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
4264 	ASSERT(nfscl != NULL);
4265 #endif
4266 
4267 	/*
4268 	 * Its safe to piggyback on the mi_lock since failover_newserver()
4269 	 * code guarantees that there will be only one failover thread
4270 	 * per mountinfo at any instance.
4271 	 */
4272 	CALLB_CPR_INIT(&cprinfo, &mi->mi_lock, callb_generic_cpr,
4273 	    "failover_thread");
4274 
4275 	mutex_enter(&mi->mi_lock);
4276 	while (mi->mi_readers) {
4277 		CALLB_CPR_SAFE_BEGIN(&cprinfo);
4278 		cv_wait(&mi->mi_failover_cv, &mi->mi_lock);
4279 		CALLB_CPR_SAFE_END(&cprinfo, &mi->mi_lock);
4280 	}
4281 	mutex_exit(&mi->mi_lock);
4282 
4283 	tv.tv_sec = 2;
4284 	tv.tv_usec = 0;
4285 
4286 	/*
4287 	 * Ping the null NFS procedure of every server in
4288 	 * the list until one responds.  We always start
4289 	 * at the head of the list and always skip the one
4290 	 * that is current, since it's caused us a problem.
4291 	 */
4292 	while (svp == NULL) {
4293 		for (svp = mi->mi_servers; svp; svp = svp->sv_next) {
4294 			if (!oncethru && svp == mi->mi_curr_serv)
4295 				continue;
4296 
4297 			/*
4298 			 * If the file system was forcibly umounted
4299 			 * while trying to do a failover, then just
4300 			 * give up on the failover.  It won't matter
4301 			 * what the server is.
4302 			 */
4303 			if (FS_OR_ZONE_GONE(mi->mi_vfsp)) {
4304 				svp = NULL;
4305 				goto done;
4306 			}
4307 
4308 			error = clnt_tli_kcreate(svp->sv_knconf, &svp->sv_addr,
4309 			    NFS_PROGRAM, NFS_VERSION, 0, 1, CRED(), &cl);
4310 			if (error)
4311 				continue;
4312 
4313 			if (!(mi->mi_flags & MI_INT))
4314 				cl->cl_nosignal = TRUE;
4315 			status = CLNT_CALL(cl, RFS_NULL, xdr_void, NULL,
4316 			    xdr_void, NULL, tv);
4317 			if (!(mi->mi_flags & MI_INT))
4318 				cl->cl_nosignal = FALSE;
4319 			AUTH_DESTROY(cl->cl_auth);
4320 			CLNT_DESTROY(cl);
4321 			if (status == RPC_SUCCESS) {
4322 				if (svp == mi->mi_curr_serv) {
4323 #ifdef DEBUG
4324 					zcmn_err(zoneid, CE_NOTE,
4325 			"NFS%d: failing over: selecting original server %s",
4326 					    mi->mi_vers, svp->sv_hostname);
4327 #else
4328 					zcmn_err(zoneid, CE_NOTE,
4329 			"NFS: failing over: selecting original server %s",
4330 					    svp->sv_hostname);
4331 #endif
4332 				} else {
4333 #ifdef DEBUG
4334 					zcmn_err(zoneid, CE_NOTE,
4335 				    "NFS%d: failing over from %s to %s",
4336 					    mi->mi_vers,
4337 					    mi->mi_curr_serv->sv_hostname,
4338 					    svp->sv_hostname);
4339 #else
4340 					zcmn_err(zoneid, CE_NOTE,
4341 				    "NFS: failing over from %s to %s",
4342 					    mi->mi_curr_serv->sv_hostname,
4343 					    svp->sv_hostname);
4344 #endif
4345 				}
4346 				break;
4347 			}
4348 		}
4349 
4350 		if (svp == NULL) {
4351 			if (!oncethru) {
4352 				srvnames = nfs_getsrvnames(mi, &srvnames_len);
4353 #ifdef DEBUG
4354 				zprintf(zoneid,
4355 				    "NFS%d servers %s not responding "
4356 				    "still trying\n", mi->mi_vers, srvnames);
4357 #else
4358 				zprintf(zoneid, "NFS servers %s not responding "
4359 				    "still trying\n", srvnames);
4360 #endif
4361 				oncethru = 1;
4362 			}
4363 			mutex_enter(&mi->mi_lock);
4364 			CALLB_CPR_SAFE_BEGIN(&cprinfo);
4365 			mutex_exit(&mi->mi_lock);
4366 			delay(hz);
4367 			mutex_enter(&mi->mi_lock);
4368 			CALLB_CPR_SAFE_END(&cprinfo, &mi->mi_lock);
4369 			mutex_exit(&mi->mi_lock);
4370 		}
4371 	}
4372 
4373 	if (oncethru) {
4374 #ifdef DEBUG
4375 		zprintf(zoneid, "NFS%d servers %s ok\n", mi->mi_vers, srvnames);
4376 #else
4377 		zprintf(zoneid, "NFS servers %s ok\n", srvnames);
4378 #endif
4379 	}
4380 
4381 	if (svp != mi->mi_curr_serv) {
4382 		(void) dnlc_purge_vfsp(mi->mi_vfsp, 0);
4383 		index = rtablehash(&mi->mi_curr_serv->sv_fhandle);
4384 		rw_enter(&rtable[index].r_lock, RW_WRITER);
4385 		rp = rfind(&rtable[index], &mi->mi_curr_serv->sv_fhandle,
4386 		    mi->mi_vfsp);
4387 		if (rp != NULL) {
4388 			if (rp->r_flags & RHASHED)
4389 				rp_rmhash_locked(rp);
4390 			rw_exit(&rtable[index].r_lock);
4391 			rp->r_server = svp;
4392 			rp->r_fh = svp->sv_fhandle;
4393 			(void) nfs_free_data_reclaim(rp);
4394 			index = rtablehash(&rp->r_fh);
4395 			rp->r_hashq = &rtable[index];
4396 			rw_enter(&rp->r_hashq->r_lock, RW_WRITER);
4397 			vn_exists(RTOV(rp));
4398 			rp_addhash(rp);
4399 			rw_exit(&rp->r_hashq->r_lock);
4400 			VN_RELE(RTOV(rp));
4401 		} else
4402 			rw_exit(&rtable[index].r_lock);
4403 	}
4404 
4405 done:
4406 	if (oncethru)
4407 		kmem_free(srvnames, srvnames_len);
4408 	mutex_enter(&mi->mi_lock);
4409 	mi->mi_flags &= ~MI_BINDINPROG;
4410 	if (svp != NULL) {
4411 		mi->mi_curr_serv = svp;
4412 		mi->mi_failover++;
4413 #ifdef DEBUG
4414 	nfscl->nfscl_stat.failover.value.ui64++;
4415 #endif
4416 	}
4417 	cv_broadcast(&mi->mi_failover_cv);
4418 	CALLB_CPR_EXIT(&cprinfo);
4419 	VFS_RELE(mi->mi_vfsp);
4420 	zthread_exit();
4421 	/* NOTREACHED */
4422 }
4423 
4424 /*
4425  * NFS client failover support
4426  *
4427  * failover_wait() will put the thread to sleep until MI_BINDINPROG
4428  * is cleared, meaning that failover is complete.  Called with
4429  * mi_lock mutex held.
4430  */
4431 static int
4432 failover_wait(mntinfo_t *mi)
4433 {
4434 	k_sigset_t smask;
4435 
4436 	/*
4437 	 * If someone else is hunting for a living server,
4438 	 * sleep until it's done.  After our sleep, we may
4439 	 * be bound to the right server and get off cheaply.
4440 	 */
4441 	while (mi->mi_flags & MI_BINDINPROG) {
4442 		/*
4443 		 * Mask out all signals except SIGHUP, SIGINT, SIGQUIT
4444 		 * and SIGTERM. (Preserving the existing masks).
4445 		 * Mask out SIGINT if mount option nointr is specified.
4446 		 */
4447 		sigintr(&smask, (int)mi->mi_flags & MI_INT);
4448 		if (!cv_wait_sig(&mi->mi_failover_cv, &mi->mi_lock)) {
4449 			/*
4450 			 * restore original signal mask
4451 			 */
4452 			sigunintr(&smask);
4453 			return (EINTR);
4454 		}
4455 		/*
4456 		 * restore original signal mask
4457 		 */
4458 		sigunintr(&smask);
4459 	}
4460 	return (0);
4461 }
4462 
4463 /*
4464  * NFS client failover support
4465  *
4466  * failover_remap() will do a partial pathname lookup and find the
4467  * desired vnode on the current server.  The interim vnode will be
4468  * discarded after we pilfer the new filehandle.
4469  *
4470  * Side effects:
4471  * - This routine will also update the filehandle in the args structure
4472  *    pointed to by the fi->fhp pointer if it is non-NULL.
4473  */
4474 
4475 static int
4476 failover_remap(failinfo_t *fi)
4477 {
4478 	vnode_t *vp, *nvp, *rootvp;
4479 	rnode_t *rp, *nrp;
4480 	mntinfo_t *mi;
4481 	int error;
4482 #ifdef DEBUG
4483 	struct nfs_clnt *nfscl;
4484 
4485 	nfscl = zone_getspecific(nfsclnt_zone_key, nfs_zone());
4486 	ASSERT(nfscl != NULL);
4487 #endif
4488 	/*
4489 	 * Sanity check
4490 	 */
4491 	if (fi == NULL || fi->vp == NULL || fi->lookupproc == NULL)
4492 		return (EINVAL);
4493 	vp = fi->vp;
4494 	rp = VTOR(vp);
4495 	mi = VTOMI(vp);
4496 
4497 	if (!(vp->v_flag & VROOT)) {
4498 		/*
4499 		 * Given the root fh, use the path stored in
4500 		 * the rnode to find the fh for the new server.
4501 		 */
4502 		error = VFS_ROOT(mi->mi_vfsp, &rootvp);
4503 		if (error)
4504 			return (error);
4505 
4506 		error = failover_lookup(rp->r_path, rootvp,
4507 		    fi->lookupproc, fi->xattrdirproc, &nvp);
4508 
4509 		VN_RELE(rootvp);
4510 
4511 		if (error)
4512 			return (error);
4513 
4514 		/*
4515 		 * If we found the same rnode, we're done now
4516 		 */
4517 		if (nvp == vp) {
4518 			/*
4519 			 * Failed and the new server may physically be same
4520 			 * OR may share a same disk subsystem. In this case
4521 			 * file handle for a particular file path is not going
4522 			 * to change, given the same filehandle lookup will
4523 			 * always locate the same rnode as the existing one.
4524 			 * All we might need to do is to update the r_server
4525 			 * with the current servinfo.
4526 			 */
4527 			if (!VALID_FH(fi)) {
4528 				rp->r_server = mi->mi_curr_serv;
4529 			}
4530 			VN_RELE(nvp);
4531 			return (0);
4532 		}
4533 
4534 		/*
4535 		 * Try to make it so that no one else will find this
4536 		 * vnode because it is just a temporary to hold the
4537 		 * new file handle until that file handle can be
4538 		 * copied to the original vnode/rnode.
4539 		 */
4540 		nrp = VTOR(nvp);
4541 		mutex_enter(&mi->mi_remap_lock);
4542 		/*
4543 		 * Some other thread could have raced in here and could
4544 		 * have done the remap for this particular rnode before
4545 		 * this thread here. Check for rp->r_server and
4546 		 * mi->mi_curr_serv and return if they are same.
4547 		 */
4548 		if (VALID_FH(fi)) {
4549 			mutex_exit(&mi->mi_remap_lock);
4550 			VN_RELE(nvp);
4551 			return (0);
4552 		}
4553 
4554 		if (nrp->r_flags & RHASHED)
4555 			rp_rmhash(nrp);
4556 
4557 		/*
4558 		 * As a heuristic check on the validity of the new
4559 		 * file, check that the size and type match against
4560 		 * that we remember from the old version.
4561 		 */
4562 		if (rp->r_size != nrp->r_size || vp->v_type != nvp->v_type) {
4563 			mutex_exit(&mi->mi_remap_lock);
4564 			zcmn_err(mi->mi_zone->zone_id, CE_WARN,
4565 			    "NFS replicas %s and %s: file %s not same.",
4566 			    rp->r_server->sv_hostname,
4567 			    nrp->r_server->sv_hostname, rp->r_path);
4568 			VN_RELE(nvp);
4569 			return (EINVAL);
4570 		}
4571 
4572 		/*
4573 		 * snarf the filehandle from the new rnode
4574 		 * then release it, again while updating the
4575 		 * hash queues for the rnode.
4576 		 */
4577 		if (rp->r_flags & RHASHED)
4578 			rp_rmhash(rp);
4579 		rp->r_server = mi->mi_curr_serv;
4580 		rp->r_fh = nrp->r_fh;
4581 		rp->r_hashq = nrp->r_hashq;
4582 		/*
4583 		 * Copy the attributes from the new rnode to the old
4584 		 * rnode.  This will help to reduce unnecessary page
4585 		 * cache flushes.
4586 		 */
4587 		rp->r_attr = nrp->r_attr;
4588 		rp->r_attrtime = nrp->r_attrtime;
4589 		rp->r_mtime = nrp->r_mtime;
4590 		(void) nfs_free_data_reclaim(rp);
4591 		nfs_setswaplike(vp, &rp->r_attr);
4592 		rw_enter(&rp->r_hashq->r_lock, RW_WRITER);
4593 		rp_addhash(rp);
4594 		rw_exit(&rp->r_hashq->r_lock);
4595 		mutex_exit(&mi->mi_remap_lock);
4596 		VN_RELE(nvp);
4597 	}
4598 
4599 	/*
4600 	 * Update successful failover remap count
4601 	 */
4602 	mutex_enter(&mi->mi_lock);
4603 	mi->mi_remap++;
4604 	mutex_exit(&mi->mi_lock);
4605 #ifdef DEBUG
4606 	nfscl->nfscl_stat.remap.value.ui64++;
4607 #endif
4608 
4609 	/*
4610 	 * If we have a copied filehandle to update, do it now.
4611 	 */
4612 	if (fi->fhp != NULL && fi->copyproc != NULL)
4613 		(*fi->copyproc)(fi->fhp, vp);
4614 
4615 	return (0);
4616 }
4617 
4618 /*
4619  * NFS client failover support
4620  *
4621  * We want a simple pathname lookup routine to parse the pieces
4622  * of path in rp->r_path.  We know that the path was a created
4623  * as rnodes were made, so we know we have only to deal with
4624  * paths that look like:
4625  *	dir1/dir2/dir3/file
4626  * Any evidence of anything like .., symlinks, and ENOTDIR
4627  * are hard errors, because they mean something in this filesystem
4628  * is different from the one we came from, or has changed under
4629  * us in some way.  If this is true, we want the failure.
4630  *
4631  * Extended attributes: if the filesystem is mounted with extended
4632  * attributes enabled (-o xattr), the attribute directory will be
4633  * represented in the r_path as the magic name XATTR_RPATH. So if
4634  * we see that name in the pathname, is must be because this node
4635  * is an extended attribute.  Therefore, look it up that way.
4636  */
4637 static int
4638 failover_lookup(char *path, vnode_t *root,
4639     int (*lookupproc)(vnode_t *, char *, vnode_t **, struct pathname *, int,
4640 	vnode_t *, cred_t *, int),
4641     int (*xattrdirproc)(vnode_t *, vnode_t **, bool_t, cred_t *, int),
4642     vnode_t **new)
4643 {
4644 	vnode_t *dvp, *nvp;
4645 	int error = EINVAL;
4646 	char *s, *p, *tmppath;
4647 	size_t len;
4648 	mntinfo_t *mi;
4649 	bool_t xattr;
4650 
4651 	/* Make local copy of path */
4652 	len = strlen(path) + 1;
4653 	tmppath = kmem_alloc(len, KM_SLEEP);
4654 	(void) strcpy(tmppath, path);
4655 	s = tmppath;
4656 
4657 	dvp = root;
4658 	VN_HOLD(dvp);
4659 	mi = VTOMI(root);
4660 	xattr = mi->mi_flags & MI_EXTATTR;
4661 
4662 	do {
4663 		p = strchr(s, '/');
4664 		if (p != NULL)
4665 			*p = '\0';
4666 		if (xattr && strcmp(s, XATTR_RPATH) == 0) {
4667 			error = (*xattrdirproc)(dvp, &nvp, FALSE, CRED(),
4668 			    RFSCALL_SOFT);
4669 		} else {
4670 			error = (*lookupproc)(dvp, s, &nvp, NULL, 0, NULL,
4671 			    CRED(), RFSCALL_SOFT);
4672 		}
4673 		if (p != NULL)
4674 			*p++ = '/';
4675 		if (error) {
4676 			VN_RELE(dvp);
4677 			kmem_free(tmppath, len);
4678 			return (error);
4679 		}
4680 		s = p;
4681 		VN_RELE(dvp);
4682 		dvp = nvp;
4683 	} while (p != NULL);
4684 
4685 	if (nvp != NULL && new != NULL)
4686 		*new = nvp;
4687 	kmem_free(tmppath, len);
4688 	return (0);
4689 }
4690 
4691 /*
4692  * NFS client failover support
4693  *
4694  * sv_free() frees the malloc'd portion of a "servinfo_t".
4695  */
4696 void
4697 sv_free(servinfo_t *svp)
4698 {
4699 	servinfo_t *next;
4700 	struct knetconfig *knconf;
4701 
4702 	while (svp != NULL) {
4703 		next = svp->sv_next;
4704 		if (svp->sv_secdata)
4705 			sec_clnt_freeinfo(svp->sv_secdata);
4706 		if (svp->sv_hostname && svp->sv_hostnamelen > 0)
4707 			kmem_free(svp->sv_hostname, svp->sv_hostnamelen);
4708 		knconf = svp->sv_knconf;
4709 		if (knconf != NULL) {
4710 			if (knconf->knc_protofmly != NULL)
4711 				kmem_free(knconf->knc_protofmly, KNC_STRSIZE);
4712 			if (knconf->knc_proto != NULL)
4713 				kmem_free(knconf->knc_proto, KNC_STRSIZE);
4714 			kmem_free(knconf, sizeof (*knconf));
4715 		}
4716 		knconf = svp->sv_origknconf;
4717 		if (knconf != NULL) {
4718 			if (knconf->knc_protofmly != NULL)
4719 				kmem_free(knconf->knc_protofmly, KNC_STRSIZE);
4720 			if (knconf->knc_proto != NULL)
4721 				kmem_free(knconf->knc_proto, KNC_STRSIZE);
4722 			kmem_free(knconf, sizeof (*knconf));
4723 		}
4724 		if (svp->sv_addr.buf != NULL && svp->sv_addr.maxlen != 0)
4725 			kmem_free(svp->sv_addr.buf, svp->sv_addr.maxlen);
4726 		mutex_destroy(&svp->sv_lock);
4727 		kmem_free(svp, sizeof (*svp));
4728 		svp = next;
4729 	}
4730 }
4731 
4732 /*
4733  * Only can return non-zero if intr != 0.
4734  */
4735 int
4736 nfs_rw_enter_sig(nfs_rwlock_t *l, krw_t rw, int intr)
4737 {
4738 
4739 	mutex_enter(&l->lock);
4740 
4741 	/*
4742 	 * If this is a nested enter, then allow it.  There
4743 	 * must be as many exits as enters through.
4744 	 */
4745 	if (l->owner == curthread) {
4746 		/* lock is held for writing by current thread */
4747 		ASSERT(rw == RW_READER || rw == RW_WRITER);
4748 		l->count--;
4749 	} else if (rw == RW_READER) {
4750 		/*
4751 		 * While there is a writer active or writers waiting,
4752 		 * then wait for them to finish up and move on.  Then,
4753 		 * increment the count to indicate that a reader is
4754 		 * active.
4755 		 */
4756 		while (l->count < 0 || l->waiters > 0) {
4757 			if (intr) {
4758 				klwp_t *lwp = ttolwp(curthread);
4759 
4760 				if (lwp != NULL)
4761 					lwp->lwp_nostop++;
4762 				if (!cv_wait_sig(&l->cv, &l->lock)) {
4763 					if (lwp != NULL)
4764 						lwp->lwp_nostop--;
4765 					mutex_exit(&l->lock);
4766 					return (EINTR);
4767 				}
4768 				if (lwp != NULL)
4769 					lwp->lwp_nostop--;
4770 			} else
4771 				cv_wait(&l->cv, &l->lock);
4772 		}
4773 		ASSERT(l->count < INT_MAX);
4774 #ifdef	DEBUG
4775 		if ((l->count % 10000) == 9999)
4776 			cmn_err(CE_WARN, "nfs_rw_enter_sig: count %d on"
4777 			    "rwlock @ %p\n", l->count, (void *)&l);
4778 #endif
4779 		l->count++;
4780 	} else {
4781 		ASSERT(rw == RW_WRITER);
4782 		/*
4783 		 * While there are readers active or a writer
4784 		 * active, then wait for all of the readers
4785 		 * to finish or for the writer to finish.
4786 		 * Then, set the owner field to curthread and
4787 		 * decrement count to indicate that a writer
4788 		 * is active.
4789 		 */
4790 		while (l->count > 0 || l->owner != NULL) {
4791 			l->waiters++;
4792 			if (intr) {
4793 				klwp_t *lwp = ttolwp(curthread);
4794 
4795 				if (lwp != NULL)
4796 					lwp->lwp_nostop++;
4797 				if (!cv_wait_sig(&l->cv, &l->lock)) {
4798 					if (lwp != NULL)
4799 						lwp->lwp_nostop--;
4800 					l->waiters--;
4801 					cv_broadcast(&l->cv);
4802 					mutex_exit(&l->lock);
4803 					return (EINTR);
4804 				}
4805 				if (lwp != NULL)
4806 					lwp->lwp_nostop--;
4807 			} else
4808 				cv_wait(&l->cv, &l->lock);
4809 			l->waiters--;
4810 		}
4811 		l->owner = curthread;
4812 		l->count--;
4813 	}
4814 
4815 	mutex_exit(&l->lock);
4816 
4817 	return (0);
4818 }
4819 
4820 /*
4821  * If the lock is available, obtain it and return non-zero.  If there is
4822  * already a conflicting lock, return 0 immediately.
4823  */
4824 
4825 int
4826 nfs_rw_tryenter(nfs_rwlock_t *l, krw_t rw)
4827 {
4828 	mutex_enter(&l->lock);
4829 
4830 	/*
4831 	 * If this is a nested enter, then allow it.  There
4832 	 * must be as many exits as enters through.
4833 	 */
4834 	if (l->owner == curthread) {
4835 		/* lock is held for writing by current thread */
4836 		ASSERT(rw == RW_READER || rw == RW_WRITER);
4837 		l->count--;
4838 	} else if (rw == RW_READER) {
4839 		/*
4840 		 * If there is a writer active or writers waiting, deny the
4841 		 * lock.  Otherwise, bump the count of readers.
4842 		 */
4843 		if (l->count < 0 || l->waiters > 0) {
4844 			mutex_exit(&l->lock);
4845 			return (0);
4846 		}
4847 		l->count++;
4848 	} else {
4849 		ASSERT(rw == RW_WRITER);
4850 		/*
4851 		 * If there are readers active or a writer active, deny the
4852 		 * lock.  Otherwise, set the owner field to curthread and
4853 		 * decrement count to indicate that a writer is active.
4854 		 */
4855 		if (l->count > 0 || l->owner != NULL) {
4856 			mutex_exit(&l->lock);
4857 			return (0);
4858 		}
4859 		l->owner = curthread;
4860 		l->count--;
4861 	}
4862 
4863 	mutex_exit(&l->lock);
4864 
4865 	return (1);
4866 }
4867 
4868 void
4869 nfs_rw_exit(nfs_rwlock_t *l)
4870 {
4871 
4872 	mutex_enter(&l->lock);
4873 	/*
4874 	 * If this is releasing a writer lock, then increment count to
4875 	 * indicate that there is one less writer active.  If this was
4876 	 * the last of possibly nested writer locks, then clear the owner
4877 	 * field as well to indicate that there is no writer active
4878 	 * and wakeup any possible waiting writers or readers.
4879 	 *
4880 	 * If releasing a reader lock, then just decrement count to
4881 	 * indicate that there is one less reader active.  If this was
4882 	 * the last active reader and there are writer(s) waiting,
4883 	 * then wake up the first.
4884 	 */
4885 	if (l->owner != NULL) {
4886 		ASSERT(l->owner == curthread);
4887 		l->count++;
4888 		if (l->count == 0) {
4889 			l->owner = NULL;
4890 			cv_broadcast(&l->cv);
4891 		}
4892 	} else {
4893 		ASSERT(l->count > 0);
4894 		l->count--;
4895 		if (l->count == 0 && l->waiters > 0)
4896 			cv_broadcast(&l->cv);
4897 	}
4898 	mutex_exit(&l->lock);
4899 }
4900 
4901 int
4902 nfs_rw_lock_held(nfs_rwlock_t *l, krw_t rw)
4903 {
4904 
4905 	if (rw == RW_READER)
4906 		return (l->count > 0);
4907 	ASSERT(rw == RW_WRITER);
4908 	return (l->count < 0);
4909 }
4910 
4911 /* ARGSUSED */
4912 void
4913 nfs_rw_init(nfs_rwlock_t *l, char *name, krw_type_t type, void *arg)
4914 {
4915 
4916 	l->count = 0;
4917 	l->waiters = 0;
4918 	l->owner = NULL;
4919 	mutex_init(&l->lock, NULL, MUTEX_DEFAULT, NULL);
4920 	cv_init(&l->cv, NULL, CV_DEFAULT, NULL);
4921 }
4922 
4923 void
4924 nfs_rw_destroy(nfs_rwlock_t *l)
4925 {
4926 
4927 	mutex_destroy(&l->lock);
4928 	cv_destroy(&l->cv);
4929 }
4930 
4931 int
4932 nfs3_rddir_compar(const void *x, const void *y)
4933 {
4934 	rddir_cache *a = (rddir_cache *)x;
4935 	rddir_cache *b = (rddir_cache *)y;
4936 
4937 	if (a->nfs3_cookie == b->nfs3_cookie) {
4938 		if (a->buflen == b->buflen)
4939 			return (0);
4940 		if (a->buflen < b->buflen)
4941 			return (-1);
4942 		return (1);
4943 	}
4944 
4945 	if (a->nfs3_cookie < b->nfs3_cookie)
4946 		return (-1);
4947 
4948 	return (1);
4949 }
4950 
4951 int
4952 nfs_rddir_compar(const void *x, const void *y)
4953 {
4954 	rddir_cache *a = (rddir_cache *)x;
4955 	rddir_cache *b = (rddir_cache *)y;
4956 
4957 	if (a->nfs_cookie == b->nfs_cookie) {
4958 		if (a->buflen == b->buflen)
4959 			return (0);
4960 		if (a->buflen < b->buflen)
4961 			return (-1);
4962 		return (1);
4963 	}
4964 
4965 	if (a->nfs_cookie < b->nfs_cookie)
4966 		return (-1);
4967 
4968 	return (1);
4969 }
4970 
4971 static char *
4972 nfs_getsrvnames(mntinfo_t *mi, size_t *len)
4973 {
4974 	servinfo_t *s;
4975 	char *srvnames;
4976 	char *namep;
4977 	size_t length;
4978 
4979 	/*
4980 	 * Calculate the length of the string required to hold all
4981 	 * of the server names plus either a comma or a null
4982 	 * character following each individual one.
4983 	 */
4984 	length = 0;
4985 	for (s = mi->mi_servers; s != NULL; s = s->sv_next)
4986 		length += s->sv_hostnamelen;
4987 
4988 	srvnames = kmem_alloc(length, KM_SLEEP);
4989 
4990 	namep = srvnames;
4991 	for (s = mi->mi_servers; s != NULL; s = s->sv_next) {
4992 		(void) strcpy(namep, s->sv_hostname);
4993 		namep += s->sv_hostnamelen - 1;
4994 		*namep++ = ',';
4995 	}
4996 	*--namep = '\0';
4997 
4998 	*len = length;
4999 
5000 	return (srvnames);
5001 }
5002 
5003 /*
5004  * These two functions are temporary and designed for the upgrade-workaround
5005  * only.  They cannot be used for general zone-crossing NFS client support, and
5006  * will be removed shortly.
5007  *
5008  * When the workaround is enabled, all NFS traffic is forced into the global
5009  * zone.  These functions are called when the code needs to refer to the state
5010  * of the underlying network connection.  They're not called when the function
5011  * needs to refer to the state of the process that invoked the system call.
5012  * (E.g., when checking whether the zone is shutting down during the mount()
5013  * call.)
5014  */
5015 
5016 struct zone *
5017 nfs_zone(void)
5018 {
5019 	return (nfs_global_client_only != 0 ? global_zone : curproc->p_zone);
5020 }
5021 
5022 zoneid_t
5023 nfs_zoneid(void)
5024 {
5025 	return (nfs_global_client_only != 0 ? GLOBAL_ZONEID : getzoneid());
5026 }
5027 
5028 /*
5029  * nfs_mount_label_policy:
5030  *	Determine whether the mount is allowed according to MAC check,
5031  *	by comparing (where appropriate) label of the remote server
5032  *	against the label of the zone being mounted into.
5033  *
5034  *	Returns:
5035  *		 0 :	access allowed
5036  *		-1 :	read-only access allowed (i.e., read-down)
5037  *		>0 :	error code, such as EACCES
5038  */
5039 int
5040 nfs_mount_label_policy(vfs_t *vfsp, struct netbuf *addr,
5041     struct knetconfig *knconf, cred_t *cr)
5042 {
5043 	int		addr_type;
5044 	void		*ipaddr;
5045 	bslabel_t	*server_sl, *mntlabel;
5046 	zone_t		*mntzone = NULL;
5047 	ts_label_t	*zlabel;
5048 	tsol_tpc_t	*tp;
5049 	ts_label_t	*tsl = NULL;
5050 	int		retv;
5051 
5052 	/*
5053 	 * Get the zone's label.  Each zone on a labeled system has a label.
5054 	 */
5055 	mntzone = zone_find_by_any_path(refstr_value(vfsp->vfs_mntpt), B_FALSE);
5056 	zlabel = mntzone->zone_slabel;
5057 	ASSERT(zlabel != NULL);
5058 	label_hold(zlabel);
5059 
5060 	if (strcmp(knconf->knc_protofmly, NC_INET) == 0) {
5061 		addr_type = IPV4_VERSION;
5062 		ipaddr = &((struct sockaddr_in *)addr->buf)->sin_addr;
5063 	} else if (strcmp(knconf->knc_protofmly, NC_INET6) == 0) {
5064 		addr_type = IPV6_VERSION;
5065 		ipaddr = &((struct sockaddr_in6 *)addr->buf)->sin6_addr;
5066 	} else {
5067 		retv = 0;
5068 		goto out;
5069 	}
5070 
5071 	retv = EACCES;				/* assume the worst */
5072 
5073 	/*
5074 	 * Next, get the assigned label of the remote server.
5075 	 */
5076 	tp = find_tpc(ipaddr, addr_type, B_FALSE);
5077 	if (tp == NULL)
5078 		goto out;			/* error getting host entry */
5079 
5080 	if (tp->tpc_tp.tp_doi != zlabel->tsl_doi)
5081 		goto rel_tpc;			/* invalid domain */
5082 	if ((tp->tpc_tp.host_type != SUN_CIPSO) &&
5083 	    (tp->tpc_tp.host_type != UNLABELED))
5084 		goto rel_tpc;			/* invalid hosttype */
5085 
5086 	if (tp->tpc_tp.host_type == SUN_CIPSO) {
5087 		tsl = getflabel_cipso(vfsp);
5088 		if (tsl == NULL)
5089 			goto rel_tpc;		/* error getting server lbl */
5090 
5091 		server_sl = label2bslabel(tsl);
5092 	} else {	/* UNLABELED */
5093 		server_sl = &tp->tpc_tp.tp_def_label;
5094 	}
5095 
5096 	mntlabel = label2bslabel(zlabel);
5097 
5098 	/*
5099 	 * Now compare labels to complete the MAC check.  If the labels
5100 	 * are equal or if the requestor is in the global zone and has
5101 	 * NET_MAC_AWARE, then allow read-write access.   (Except for
5102 	 * mounts into the global zone itself; restrict these to
5103 	 * read-only.)
5104 	 *
5105 	 * If the requestor is in some other zone, but his label
5106 	 * dominates the server, then allow read-down.
5107 	 *
5108 	 * Otherwise, access is denied.
5109 	 */
5110 	if (blequal(mntlabel, server_sl) ||
5111 	    (crgetzoneid(cr) == GLOBAL_ZONEID &&
5112 	    getpflags(NET_MAC_AWARE, cr) != 0)) {
5113 		if ((mntzone == global_zone) ||
5114 		    !blequal(mntlabel, server_sl))
5115 			retv = -1;		/* read-only */
5116 		else
5117 			retv = 0;		/* access OK */
5118 	} else if (bldominates(mntlabel, server_sl)) {
5119 		retv = -1;			/* read-only */
5120 	} else {
5121 		retv = EACCES;
5122 	}
5123 
5124 	if (tsl != NULL)
5125 		label_rele(tsl);
5126 
5127 rel_tpc:
5128 	TPC_RELE(tp);
5129 out:
5130 	if (mntzone)
5131 		zone_rele(mntzone);
5132 	label_rele(zlabel);
5133 	return (retv);
5134 }
5135 
5136 boolean_t
5137 nfs_has_ctty(void)
5138 {
5139 	boolean_t rv;
5140 	mutex_enter(&curproc->p_splock);
5141 	rv = (curproc->p_sessp->s_vp != NULL);
5142 	mutex_exit(&curproc->p_splock);
5143 	return (rv);
5144 }
5145 
5146 /*
5147  * See if xattr directory to see if it has any generic user attributes
5148  */
5149 int
5150 do_xattr_exists_check(vnode_t *vp, ulong_t *valp, cred_t *cr)
5151 {
5152 	struct uio uio;
5153 	struct iovec iov;
5154 	char *dbuf;
5155 	struct dirent64 *dp;
5156 	size_t dlen = 8 * 1024;
5157 	size_t dbuflen;
5158 	int eof = 0;
5159 	int error;
5160 
5161 	*valp = 0;
5162 	dbuf = kmem_alloc(dlen, KM_SLEEP);
5163 	uio.uio_iov = &iov;
5164 	uio.uio_iovcnt = 1;
5165 	uio.uio_segflg = UIO_SYSSPACE;
5166 	uio.uio_fmode = 0;
5167 	uio.uio_extflg = UIO_COPY_CACHED;
5168 	uio.uio_loffset = 0;
5169 	uio.uio_resid = dlen;
5170 	iov.iov_base = dbuf;
5171 	iov.iov_len = dlen;
5172 	(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
5173 	error = VOP_READDIR(vp, &uio, cr, &eof, NULL, 0);
5174 	VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
5175 
5176 	dbuflen = dlen - uio.uio_resid;
5177 
5178 	if (error || dbuflen == 0) {
5179 		kmem_free(dbuf, dlen);
5180 		return (error);
5181 	}
5182 
5183 	dp = (dirent64_t *)dbuf;
5184 
5185 	while ((intptr_t)dp < (intptr_t)dbuf + dbuflen) {
5186 		if (strcmp(dp->d_name, ".") == 0 ||
5187 		    strcmp(dp->d_name, "..") == 0 || strcmp(dp->d_name,
5188 		    VIEW_READWRITE) == 0 || strcmp(dp->d_name,
5189 		    VIEW_READONLY) == 0) {
5190 			dp = (dirent64_t *)((intptr_t)dp + dp->d_reclen);
5191 			continue;
5192 		}
5193 
5194 		*valp = 1;
5195 		break;
5196 	}
5197 	kmem_free(dbuf, dlen);
5198 	return (0);
5199 }
5200