xref: /dflybsd-src/sys/vfs/nfs/nfs_vnops.c (revision 41871674d0079dec70d55eb824f39d07dc7b3310)
1 /*
2  * Copyright (c) 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Rick Macklem at The University of Guelph.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  *	@(#)nfs_vnops.c	8.16 (Berkeley) 5/27/95
37  * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $
38  * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.55 2006/04/07 06:38:33 dillon Exp $
39  */
40 
41 
42 /*
43  * vnode op calls for Sun NFS version 2 and 3
44  */
45 
46 #include "opt_inet.h"
47 
48 #include <sys/param.h>
49 #include <sys/kernel.h>
50 #include <sys/systm.h>
51 #include <sys/resourcevar.h>
52 #include <sys/proc.h>
53 #include <sys/mount.h>
54 #include <sys/buf.h>
55 #include <sys/malloc.h>
56 #include <sys/mbuf.h>
57 #include <sys/namei.h>
58 #include <sys/nlookup.h>
59 #include <sys/socket.h>
60 #include <sys/vnode.h>
61 #include <sys/dirent.h>
62 #include <sys/fcntl.h>
63 #include <sys/lockf.h>
64 #include <sys/stat.h>
65 #include <sys/sysctl.h>
66 #include <sys/conf.h>
67 
68 #include <vm/vm.h>
69 #include <vm/vm_extern.h>
70 #include <vm/vm_zone.h>
71 
72 #include <sys/buf2.h>
73 
74 #include <vfs/fifofs/fifo.h>
75 #include <vfs/ufs/dir.h>
76 
77 #undef DIRBLKSIZ
78 
79 #include "rpcv2.h"
80 #include "nfsproto.h"
81 #include "nfs.h"
82 #include "nfsmount.h"
83 #include "nfsnode.h"
84 #include "xdr_subs.h"
85 #include "nfsm_subs.h"
86 
87 #include <net/if.h>
88 #include <netinet/in.h>
89 #include <netinet/in_var.h>
90 
91 #include <sys/thread2.h>
92 
93 /* Defs */
94 #define	TRUE	1
95 #define	FALSE	0
96 
97 /*
98  * Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these
99  * calls are not in getblk() and brelse() so that they would not be necessary
100  * here.
101  */
102 #ifndef B_VMIO
103 #define vfs_busy_pages(bp, f)
104 #endif
105 
106 static int	nfsspec_read (struct vop_read_args *);
107 static int	nfsspec_write (struct vop_write_args *);
108 static int	nfsfifo_read (struct vop_read_args *);
109 static int	nfsfifo_write (struct vop_write_args *);
110 static int	nfsspec_close (struct vop_close_args *);
111 static int	nfsfifo_close (struct vop_close_args *);
112 #define nfs_poll vop_nopoll
113 static int	nfs_setattrrpc (struct vnode *,struct vattr *,struct ucred *,struct thread *);
114 static	int	nfs_lookup (struct vop_old_lookup_args *);
115 static	int	nfs_create (struct vop_old_create_args *);
116 static	int	nfs_mknod (struct vop_old_mknod_args *);
117 static	int	nfs_open (struct vop_open_args *);
118 static	int	nfs_close (struct vop_close_args *);
119 static	int	nfs_access (struct vop_access_args *);
120 static	int	nfs_getattr (struct vop_getattr_args *);
121 static	int	nfs_setattr (struct vop_setattr_args *);
122 static	int	nfs_read (struct vop_read_args *);
123 static	int	nfs_mmap (struct vop_mmap_args *);
124 static	int	nfs_fsync (struct vop_fsync_args *);
125 static	int	nfs_remove (struct vop_old_remove_args *);
126 static	int	nfs_link (struct vop_old_link_args *);
127 static	int	nfs_rename (struct vop_old_rename_args *);
128 static	int	nfs_mkdir (struct vop_old_mkdir_args *);
129 static	int	nfs_rmdir (struct vop_old_rmdir_args *);
130 static	int	nfs_symlink (struct vop_old_symlink_args *);
131 static	int	nfs_readdir (struct vop_readdir_args *);
132 static	int	nfs_bmap (struct vop_bmap_args *);
133 static	int	nfs_strategy (struct vop_strategy_args *);
134 static	int	nfs_lookitup (struct vnode *, const char *, int,
135 			struct ucred *, struct thread *, struct nfsnode **);
136 static	int	nfs_sillyrename (struct vnode *,struct vnode *,struct componentname *);
137 static int	nfsspec_access (struct vop_access_args *);
138 static int	nfs_readlink (struct vop_readlink_args *);
139 static int	nfs_print (struct vop_print_args *);
140 static int	nfs_advlock (struct vop_advlock_args *);
141 static int	nfs_bwrite (struct vop_bwrite_args *);
142 
143 static	int	nfs_nresolve (struct vop_nresolve_args *);
144 /*
145  * Global vfs data structures for nfs
146  */
147 struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = {
148 	{ &vop_default_desc,		vop_defaultop },
149 	{ &vop_access_desc,		(vnodeopv_entry_t) nfs_access },
150 	{ &vop_advlock_desc,		(vnodeopv_entry_t) nfs_advlock },
151 	{ &vop_bmap_desc,		(vnodeopv_entry_t) nfs_bmap },
152 	{ &vop_bwrite_desc,		(vnodeopv_entry_t) nfs_bwrite },
153 	{ &vop_close_desc,		(vnodeopv_entry_t) nfs_close },
154 	{ &vop_old_create_desc,		(vnodeopv_entry_t) nfs_create },
155 	{ &vop_fsync_desc,		(vnodeopv_entry_t) nfs_fsync },
156 	{ &vop_getattr_desc,		(vnodeopv_entry_t) nfs_getattr },
157 	{ &vop_getpages_desc,		(vnodeopv_entry_t) nfs_getpages },
158 	{ &vop_putpages_desc,		(vnodeopv_entry_t) nfs_putpages },
159 	{ &vop_inactive_desc,		(vnodeopv_entry_t) nfs_inactive },
160 	{ &vop_islocked_desc,		(vnodeopv_entry_t) vop_stdislocked },
161 	{ &vop_old_link_desc,		(vnodeopv_entry_t) nfs_link },
162 	{ &vop_lock_desc,		(vnodeopv_entry_t) vop_stdlock },
163 	{ &vop_old_lookup_desc,		(vnodeopv_entry_t) nfs_lookup },
164 	{ &vop_old_mkdir_desc,		(vnodeopv_entry_t) nfs_mkdir },
165 	{ &vop_old_mknod_desc,		(vnodeopv_entry_t) nfs_mknod },
166 	{ &vop_mmap_desc,		(vnodeopv_entry_t) nfs_mmap },
167 	{ &vop_open_desc,		(vnodeopv_entry_t) nfs_open },
168 	{ &vop_poll_desc,		(vnodeopv_entry_t) nfs_poll },
169 	{ &vop_print_desc,		(vnodeopv_entry_t) nfs_print },
170 	{ &vop_read_desc,		(vnodeopv_entry_t) nfs_read },
171 	{ &vop_readdir_desc,		(vnodeopv_entry_t) nfs_readdir },
172 	{ &vop_readlink_desc,		(vnodeopv_entry_t) nfs_readlink },
173 	{ &vop_reclaim_desc,		(vnodeopv_entry_t) nfs_reclaim },
174 	{ &vop_old_remove_desc,		(vnodeopv_entry_t) nfs_remove },
175 	{ &vop_old_rename_desc,		(vnodeopv_entry_t) nfs_rename },
176 	{ &vop_old_rmdir_desc,		(vnodeopv_entry_t) nfs_rmdir },
177 	{ &vop_setattr_desc,		(vnodeopv_entry_t) nfs_setattr },
178 	{ &vop_strategy_desc,		(vnodeopv_entry_t) nfs_strategy },
179 	{ &vop_old_symlink_desc,	(vnodeopv_entry_t) nfs_symlink },
180 	{ &vop_unlock_desc,		(vnodeopv_entry_t) vop_stdunlock },
181 	{ &vop_write_desc,		(vnodeopv_entry_t) nfs_write },
182 
183 	{ &vop_nresolve_desc,		(vnodeopv_entry_t) nfs_nresolve },
184 	{ NULL, NULL }
185 };
186 
187 /*
188  * Special device vnode ops
189  */
190 struct vnodeopv_entry_desc nfsv2_specop_entries[] = {
191 	{ &vop_default_desc,		(vnodeopv_entry_t) spec_vnoperate },
192 	{ &vop_access_desc,		(vnodeopv_entry_t) nfsspec_access },
193 	{ &vop_close_desc,		(vnodeopv_entry_t) nfsspec_close },
194 	{ &vop_fsync_desc,		(vnodeopv_entry_t) nfs_fsync },
195 	{ &vop_getattr_desc,		(vnodeopv_entry_t) nfs_getattr },
196 	{ &vop_inactive_desc,		(vnodeopv_entry_t) nfs_inactive },
197 	{ &vop_islocked_desc,		(vnodeopv_entry_t) vop_stdislocked },
198 	{ &vop_lock_desc,		(vnodeopv_entry_t) vop_stdlock },
199 	{ &vop_print_desc,		(vnodeopv_entry_t) nfs_print },
200 	{ &vop_read_desc,		(vnodeopv_entry_t) nfsspec_read },
201 	{ &vop_reclaim_desc,		(vnodeopv_entry_t) nfs_reclaim },
202 	{ &vop_setattr_desc,		(vnodeopv_entry_t) nfs_setattr },
203 	{ &vop_unlock_desc,		(vnodeopv_entry_t) vop_stdunlock },
204 	{ &vop_write_desc,		(vnodeopv_entry_t) nfsspec_write },
205 	{ NULL, NULL }
206 };
207 
208 struct vnodeopv_entry_desc nfsv2_fifoop_entries[] = {
209 	{ &vop_default_desc,		(vnodeopv_entry_t) fifo_vnoperate },
210 	{ &vop_access_desc,		(vnodeopv_entry_t) nfsspec_access },
211 	{ &vop_close_desc,		(vnodeopv_entry_t) nfsfifo_close },
212 	{ &vop_fsync_desc,		(vnodeopv_entry_t) nfs_fsync },
213 	{ &vop_getattr_desc,		(vnodeopv_entry_t) nfs_getattr },
214 	{ &vop_inactive_desc,		(vnodeopv_entry_t) nfs_inactive },
215 	{ &vop_islocked_desc,		(vnodeopv_entry_t) vop_stdislocked },
216 	{ &vop_lock_desc,		(vnodeopv_entry_t) vop_stdlock },
217 	{ &vop_print_desc,		(vnodeopv_entry_t) nfs_print },
218 	{ &vop_read_desc,		(vnodeopv_entry_t) nfsfifo_read },
219 	{ &vop_reclaim_desc,		(vnodeopv_entry_t) nfs_reclaim },
220 	{ &vop_setattr_desc,		(vnodeopv_entry_t) nfs_setattr },
221 	{ &vop_unlock_desc,		(vnodeopv_entry_t) vop_stdunlock },
222 	{ &vop_write_desc,		(vnodeopv_entry_t) nfsfifo_write },
223 	{ NULL, NULL }
224 };
225 
226 static int	nfs_mknodrpc (struct vnode *dvp, struct vnode **vpp,
227 				  struct componentname *cnp,
228 				  struct vattr *vap);
229 static int	nfs_removerpc (struct vnode *dvp, const char *name,
230 				   int namelen,
231 				   struct ucred *cred, struct thread *td);
232 static int	nfs_renamerpc (struct vnode *fdvp, const char *fnameptr,
233 				   int fnamelen, struct vnode *tdvp,
234 				   const char *tnameptr, int tnamelen,
235 				   struct ucred *cred, struct thread *td);
236 static int	nfs_renameit (struct vnode *sdvp,
237 				  struct componentname *scnp,
238 				  struct sillyrename *sp);
239 
240 /*
241  * Global variables
242  */
243 extern u_int32_t nfs_true, nfs_false;
244 extern u_int32_t nfs_xdrneg1;
245 extern struct nfsstats nfsstats;
246 extern nfstype nfsv3_type[9];
247 struct thread *nfs_iodwant[NFS_MAXASYNCDAEMON];
248 struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON];
249 int nfs_numasync = 0;
250 
251 SYSCTL_DECL(_vfs_nfs);
252 
253 static int	nfsaccess_cache_timeout = NFS_DEFATTRTIMO;
254 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_timeout, CTLFLAG_RW,
255 	   &nfsaccess_cache_timeout, 0, "NFS ACCESS cache timeout");
256 
257 static int	nfsneg_cache_timeout = NFS_MINATTRTIMO;
258 SYSCTL_INT(_vfs_nfs, OID_AUTO, neg_cache_timeout, CTLFLAG_RW,
259 	   &nfsneg_cache_timeout, 0, "NFS NEGATIVE ACCESS cache timeout");
260 
261 static int	nfsv3_commit_on_close = 0;
262 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW,
263 	   &nfsv3_commit_on_close, 0, "write+commit on close, else only write");
264 #if 0
265 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_hits, CTLFLAG_RD,
266 	   &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count");
267 
268 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_misses, CTLFLAG_RD,
269 	   &nfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count");
270 #endif
271 
272 #define	NFSV3ACCESS_ALL (NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY		\
273 			 | NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE	\
274 			 | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP)
275 static int
276 nfs3_access_otw(struct vnode *vp, int wmode,
277 		struct thread *td, struct ucred *cred)
278 {
279 	const int v3 = 1;
280 	u_int32_t *tl;
281 	int error = 0, attrflag;
282 
283 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
284 	caddr_t bpos, dpos, cp2;
285 	int32_t t1, t2;
286 	caddr_t cp;
287 	u_int32_t rmode;
288 	struct nfsnode *np = VTONFS(vp);
289 
290 	nfsstats.rpccnt[NFSPROC_ACCESS]++;
291 	nfsm_reqhead(vp, NFSPROC_ACCESS, NFSX_FH(v3) + NFSX_UNSIGNED);
292 	nfsm_fhtom(vp, v3);
293 	nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
294 	*tl = txdr_unsigned(wmode);
295 	nfsm_request(vp, NFSPROC_ACCESS, td, cred);
296 	nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK);
297 	if (!error) {
298 		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
299 		rmode = fxdr_unsigned(u_int32_t, *tl);
300 		np->n_mode = rmode;
301 		np->n_modeuid = cred->cr_uid;
302 		np->n_modestamp = mycpu->gd_time_seconds;
303 	}
304 	m_freem(mrep);
305 nfsmout:
306 	return error;
307 }
308 
309 /*
310  * nfs access vnode op.
311  * For nfs version 2, just return ok. File accesses may fail later.
312  * For nfs version 3, use the access rpc to check accessibility. If file modes
313  * are changed on the server, accesses might still fail later.
314  *
315  * nfs_access(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
316  *	      struct thread *a_td)
317  */
318 static int
319 nfs_access(struct vop_access_args *ap)
320 {
321 	struct vnode *vp = ap->a_vp;
322 	int error = 0;
323 	u_int32_t mode, wmode;
324 	int v3 = NFS_ISV3(vp);
325 	struct nfsnode *np = VTONFS(vp);
326 
327 	/*
328 	 * Disallow write attempts on filesystems mounted read-only;
329 	 * unless the file is a socket, fifo, or a block or character
330 	 * device resident on the filesystem.
331 	 */
332 	if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
333 		switch (vp->v_type) {
334 		case VREG:
335 		case VDIR:
336 		case VLNK:
337 			return (EROFS);
338 		default:
339 			break;
340 		}
341 	}
342 	/*
343 	 * For nfs v3, check to see if we have done this recently, and if
344 	 * so return our cached result instead of making an ACCESS call.
345 	 * If not, do an access rpc, otherwise you are stuck emulating
346 	 * ufs_access() locally using the vattr. This may not be correct,
347 	 * since the server may apply other access criteria such as
348 	 * client uid-->server uid mapping that we do not know about.
349 	 */
350 	if (v3) {
351 		if (ap->a_mode & VREAD)
352 			mode = NFSV3ACCESS_READ;
353 		else
354 			mode = 0;
355 		if (vp->v_type != VDIR) {
356 			if (ap->a_mode & VWRITE)
357 				mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
358 			if (ap->a_mode & VEXEC)
359 				mode |= NFSV3ACCESS_EXECUTE;
360 		} else {
361 			if (ap->a_mode & VWRITE)
362 				mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
363 					 NFSV3ACCESS_DELETE);
364 			if (ap->a_mode & VEXEC)
365 				mode |= NFSV3ACCESS_LOOKUP;
366 		}
367 		/* XXX safety belt, only make blanket request if caching */
368 		if (nfsaccess_cache_timeout > 0) {
369 			wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY |
370 				NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE |
371 				NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP;
372 		} else {
373 			wmode = mode;
374 		}
375 
376 		/*
377 		 * Does our cached result allow us to give a definite yes to
378 		 * this request?
379 		 */
380 		if (np->n_modestamp &&
381 		   (mycpu->gd_time_seconds < (np->n_modestamp + nfsaccess_cache_timeout)) &&
382 		   (ap->a_cred->cr_uid == np->n_modeuid) &&
383 		   ((np->n_mode & mode) == mode)) {
384 			nfsstats.accesscache_hits++;
385 		} else {
386 			/*
387 			 * Either a no, or a don't know.  Go to the wire.
388 			 */
389 			nfsstats.accesscache_misses++;
390 		        error = nfs3_access_otw(vp, wmode, ap->a_td,ap->a_cred);
391 			if (!error) {
392 				if ((np->n_mode & mode) != mode) {
393 					error = EACCES;
394 				}
395 			}
396 		}
397 	} else {
398 		if ((error = nfsspec_access(ap)) != 0)
399 			return (error);
400 
401 		/*
402 		 * Attempt to prevent a mapped root from accessing a file
403 		 * which it shouldn't.  We try to read a byte from the file
404 		 * if the user is root and the file is not zero length.
405 		 * After calling nfsspec_access, we should have the correct
406 		 * file size cached.
407 		 */
408 		if (ap->a_cred->cr_uid == 0 && (ap->a_mode & VREAD)
409 		    && VTONFS(vp)->n_size > 0) {
410 			struct iovec aiov;
411 			struct uio auio;
412 			char buf[1];
413 
414 			aiov.iov_base = buf;
415 			aiov.iov_len = 1;
416 			auio.uio_iov = &aiov;
417 			auio.uio_iovcnt = 1;
418 			auio.uio_offset = 0;
419 			auio.uio_resid = 1;
420 			auio.uio_segflg = UIO_SYSSPACE;
421 			auio.uio_rw = UIO_READ;
422 			auio.uio_td = ap->a_td;
423 
424 			if (vp->v_type == VREG) {
425 				error = nfs_readrpc(vp, &auio);
426 			} else if (vp->v_type == VDIR) {
427 				char* bp;
428 				bp = malloc(NFS_DIRBLKSIZ, M_TEMP, M_WAITOK);
429 				aiov.iov_base = bp;
430 				aiov.iov_len = auio.uio_resid = NFS_DIRBLKSIZ;
431 				error = nfs_readdirrpc(vp, &auio);
432 				free(bp, M_TEMP);
433 			} else if (vp->v_type == VLNK) {
434 				error = nfs_readlinkrpc(vp, &auio);
435 			} else {
436 				error = EACCES;
437 			}
438 		}
439 	}
440 	/*
441 	 * [re]record creds for reading and/or writing if access
442 	 * was granted.  Assume the NFS server will grant read access
443 	 * for execute requests.
444 	 */
445 	if (error == 0) {
446 		if ((ap->a_mode & (VREAD|VEXEC)) && ap->a_cred != np->n_rucred) {
447 			crhold(ap->a_cred);
448 			if (np->n_rucred)
449 				crfree(np->n_rucred);
450 			np->n_rucred = ap->a_cred;
451 		}
452 		if ((ap->a_mode & VWRITE) && ap->a_cred != np->n_wucred) {
453 			crhold(ap->a_cred);
454 			if (np->n_wucred)
455 				crfree(np->n_wucred);
456 			np->n_wucred = ap->a_cred;
457 		}
458 	}
459 	return(error);
460 }
461 
462 /*
463  * nfs open vnode op
464  * Check to see if the type is ok
465  * and that deletion is not in progress.
466  * For paged in text files, you will need to flush the page cache
467  * if consistency is lost.
468  *
469  * nfs_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
470  *	    struct thread *a_td)
471  */
472 /* ARGSUSED */
473 static int
474 nfs_open(struct vop_open_args *ap)
475 {
476 	struct vnode *vp = ap->a_vp;
477 	struct nfsnode *np = VTONFS(vp);
478 	struct vattr vattr;
479 	int error;
480 
481 	if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) {
482 #ifdef DIAGNOSTIC
483 		printf("open eacces vtyp=%d\n",vp->v_type);
484 #endif
485 		return (EOPNOTSUPP);
486 	}
487 
488 	/*
489 	 * Clear the attribute cache only if opening with write access.  It
490 	 * is unclear if we should do this at all here, but we certainly
491 	 * should not clear the cache unconditionally simply because a file
492 	 * is being opened.
493 	 */
494 	if (ap->a_mode & FWRITE)
495 		np->n_attrstamp = 0;
496 
497 	/*
498 	 * For normal NFS, reconcile changes made locally verses
499 	 * changes made remotely.  Note that VOP_GETATTR only goes
500 	 * to the wire if the cached attribute has timed out or been
501 	 * cleared.
502 	 *
503 	 * If local modifications have been made clear the attribute
504 	 * cache to force an attribute and modified time check.  If
505 	 * GETATTR detects that the file has been changed by someone
506 	 * other then us it will set NRMODIFIED.
507 	 *
508 	 * If we are opening a directory and local changes have been
509 	 * made we have to invalidate the cache in order to ensure
510 	 * that we get the most up-to-date information from the
511 	 * server.  XXX
512 	 */
513 	if (np->n_flag & NLMODIFIED) {
514 		np->n_attrstamp = 0;
515 		if (vp->v_type == VDIR) {
516 			error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
517 			if (error == EINTR)
518 				return (error);
519 			nfs_invaldir(vp);
520 		}
521 	}
522 	error = VOP_GETATTR(vp, &vattr, ap->a_td);
523 	if (error)
524 		return (error);
525 	if (np->n_flag & NRMODIFIED) {
526 		if (vp->v_type == VDIR)
527 			nfs_invaldir(vp);
528 		error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
529 		if (error == EINTR)
530 			return (error);
531 		np->n_flag &= ~NRMODIFIED;
532 	}
533 
534 	return (vop_stdopen(ap));
535 }
536 
537 /*
538  * nfs close vnode op
539  * What an NFS client should do upon close after writing is a debatable issue.
540  * Most NFS clients push delayed writes to the server upon close, basically for
541  * two reasons:
542  * 1 - So that any write errors may be reported back to the client process
543  *     doing the close system call. By far the two most likely errors are
544  *     NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure.
545  * 2 - To put a worst case upper bound on cache inconsistency between
546  *     multiple clients for the file.
547  * There is also a consistency problem for Version 2 of the protocol w.r.t.
548  * not being able to tell if other clients are writing a file concurrently,
549  * since there is no way of knowing if the changed modify time in the reply
550  * is only due to the write for this client.
551  * (NFS Version 3 provides weak cache consistency data in the reply that
552  *  should be sufficient to detect and handle this case.)
553  *
554  * The current code does the following:
555  * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers
556  * for NFS Version 3 - flush dirty buffers to the server but don't invalidate
557  *                     or commit them (this satisfies 1 and 2 except for the
558  *                     case where the server crashes after this close but
559  *                     before the commit RPC, which is felt to be "good
560  *                     enough". Changing the last argument to nfs_flush() to
561  *                     a 1 would force a commit operation, if it is felt a
562  *                     commit is necessary now.
563  * for NQNFS         - do nothing now, since 2 is dealt with via leases and
564  *                     1 should be dealt with via an fsync() system call for
565  *                     cases where write errors are important.
566  *
567  * nfs_close(struct vnodeop_desc *a_desc, struct vnode *a_vp, int a_fflag,
568  *	     struct ucred *a_cred, struct thread *a_td)
569  */
570 /* ARGSUSED */
571 static int
572 nfs_close(struct vop_close_args *ap)
573 {
574 	struct vnode *vp = ap->a_vp;
575 	struct nfsnode *np = VTONFS(vp);
576 	int error = 0;
577 
578 	if (vp->v_type == VREG) {
579 	    if (np->n_flag & NLMODIFIED) {
580 		if (NFS_ISV3(vp)) {
581 		    /*
582 		     * Under NFSv3 we have dirty buffers to dispose of.  We
583 		     * must flush them to the NFS server.  We have the option
584 		     * of waiting all the way through the commit rpc or just
585 		     * waiting for the initial write.  The default is to only
586 		     * wait through the initial write so the data is in the
587 		     * server's cache, which is roughly similar to the state
588 		     * a standard disk subsystem leaves the file in on close().
589 		     *
590 		     * We cannot clear the NLMODIFIED bit in np->n_flag due to
591 		     * potential races with other processes, and certainly
592 		     * cannot clear it if we don't commit.
593 		     */
594 		    int cm = nfsv3_commit_on_close ? 1 : 0;
595 		    error = nfs_flush(vp, MNT_WAIT, ap->a_td, cm);
596 		    /* np->n_flag &= ~NLMODIFIED; */
597 		} else {
598 		    error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
599 		}
600 		np->n_attrstamp = 0;
601 	    }
602 	    if (np->n_flag & NWRITEERR) {
603 		np->n_flag &= ~NWRITEERR;
604 		error = np->n_error;
605 	    }
606 	}
607 	vop_stdclose(ap);
608 	return (error);
609 }
610 
611 /*
612  * nfs getattr call from vfs.
613  *
614  * nfs_getattr(struct vnode *a_vp, struct vattr *a_vap, struct ucred *a_cred,
615  *		struct thread *a_td)
616  */
617 static int
618 nfs_getattr(struct vop_getattr_args *ap)
619 {
620 	struct vnode *vp = ap->a_vp;
621 	struct nfsnode *np = VTONFS(vp);
622 	caddr_t cp;
623 	u_int32_t *tl;
624 	int32_t t1, t2;
625 	caddr_t bpos, dpos;
626 	int error = 0;
627 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
628 	int v3 = NFS_ISV3(vp);
629 
630 	/*
631 	 * Update local times for special files.
632 	 */
633 	if (np->n_flag & (NACC | NUPD))
634 		np->n_flag |= NCHG;
635 	/*
636 	 * First look in the cache.
637 	 */
638 	if (nfs_getattrcache(vp, ap->a_vap) == 0)
639 		return (0);
640 
641 	if (v3 && nfsaccess_cache_timeout > 0) {
642 		nfsstats.accesscache_misses++;
643 		nfs3_access_otw(vp, NFSV3ACCESS_ALL, ap->a_td, nfs_vpcred(vp, ND_CHECK));
644 		if (nfs_getattrcache(vp, ap->a_vap) == 0)
645 			return (0);
646 	}
647 
648 	nfsstats.rpccnt[NFSPROC_GETATTR]++;
649 	nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH(v3));
650 	nfsm_fhtom(vp, v3);
651 	nfsm_request(vp, NFSPROC_GETATTR, ap->a_td, nfs_vpcred(vp, ND_CHECK));
652 	if (!error) {
653 		nfsm_loadattr(vp, ap->a_vap);
654 	}
655 	m_freem(mrep);
656 nfsmout:
657 	return (error);
658 }
659 
660 /*
661  * nfs setattr call.
662  *
663  * nfs_setattr(struct vnodeop_desc *a_desc, struct vnode *a_vp,
664  *		struct vattr *a_vap, struct ucred *a_cred,
665  *		struct thread *a_td)
666  */
667 static int
668 nfs_setattr(struct vop_setattr_args *ap)
669 {
670 	struct vnode *vp = ap->a_vp;
671 	struct nfsnode *np = VTONFS(vp);
672 	struct vattr *vap = ap->a_vap;
673 	int error = 0;
674 	u_quad_t tsize;
675 
676 #ifndef nolint
677 	tsize = (u_quad_t)0;
678 #endif
679 
680 	/*
681 	 * Setting of flags is not supported.
682 	 */
683 	if (vap->va_flags != VNOVAL)
684 		return (EOPNOTSUPP);
685 
686 	/*
687 	 * Disallow write attempts if the filesystem is mounted read-only.
688 	 */
689   	if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
690 	    vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
691 	    vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
692 	    (vp->v_mount->mnt_flag & MNT_RDONLY))
693 		return (EROFS);
694 	if (vap->va_size != VNOVAL) {
695  		switch (vp->v_type) {
696  		case VDIR:
697  			return (EISDIR);
698  		case VCHR:
699  		case VBLK:
700  		case VSOCK:
701  		case VFIFO:
702 			if (vap->va_mtime.tv_sec == VNOVAL &&
703 			    vap->va_atime.tv_sec == VNOVAL &&
704 			    vap->va_mode == (mode_t)VNOVAL &&
705 			    vap->va_uid == (uid_t)VNOVAL &&
706 			    vap->va_gid == (gid_t)VNOVAL)
707 				return (0);
708  			vap->va_size = VNOVAL;
709  			break;
710  		default:
711 			/*
712 			 * Disallow write attempts if the filesystem is
713 			 * mounted read-only.
714 			 */
715 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
716 				return (EROFS);
717 
718 			/*
719 			 * This is nasty.  The RPCs we send to flush pending
720 			 * data often return attribute information which is
721 			 * cached via a callback to nfs_loadattrcache(), which
722 			 * has the effect of changing our notion of the file
723 			 * size.  Due to flushed appends and other operations
724 			 * the file size can be set to virtually anything,
725 			 * including values that do not match either the old
726 			 * or intended file size.
727 			 *
728 			 * When this condition is detected we must loop to
729 			 * try the operation again.  Hopefully no more
730 			 * flushing is required on the loop so it works the
731 			 * second time around.  THIS CASE ALMOST ALWAYS
732 			 * HAPPENS!
733 			 */
734 			tsize = np->n_size;
735 again:
736 			error = nfs_meta_setsize(vp, ap->a_td, vap->va_size);
737 
738  			if (np->n_flag & NLMODIFIED) {
739  			    if (vap->va_size == 0)
740  				error = nfs_vinvalbuf(vp, 0, ap->a_td, 1);
741  			    else
742  				error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
743  			}
744 			/*
745 			 * note: this loop case almost always happens at
746 			 * least once per truncation.
747 			 */
748 			if (error == 0 && np->n_size != vap->va_size)
749 				goto again;
750 			np->n_vattr.va_size = vap->va_size;
751 			break;
752 		}
753   	} else if ((vap->va_mtime.tv_sec != VNOVAL ||
754 		vap->va_atime.tv_sec != VNOVAL) && (np->n_flag & NLMODIFIED) &&
755 		vp->v_type == VREG &&
756   		(error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1)) == EINTR
757 	) {
758 		return (error);
759 	}
760 	error = nfs_setattrrpc(vp, vap, ap->a_cred, ap->a_td);
761 
762 	/*
763 	 * Sanity check if a truncation was issued.  This should only occur
764 	 * if multiple processes are racing on the same file.
765 	 */
766 	if (error == 0 && vap->va_size != VNOVAL &&
767 	    np->n_size != vap->va_size) {
768 		printf("NFS ftruncate: server disagrees on the file size: %lld/%lld/%lld\n", tsize, vap->va_size, np->n_size);
769 		goto again;
770 	}
771 	if (error && vap->va_size != VNOVAL) {
772 		np->n_size = np->n_vattr.va_size = tsize;
773 		vnode_pager_setsize(vp, np->n_size);
774 	}
775 	return (error);
776 }
777 
778 /*
779  * Do an nfs setattr rpc.
780  */
781 static int
782 nfs_setattrrpc(struct vnode *vp, struct vattr *vap,
783 	       struct ucred *cred, struct thread *td)
784 {
785 	struct nfsv2_sattr *sp;
786 	struct nfsnode *np = VTONFS(vp);
787 	caddr_t cp;
788 	int32_t t1, t2;
789 	caddr_t bpos, dpos, cp2;
790 	u_int32_t *tl;
791 	int error = 0, wccflag = NFSV3_WCCRATTR;
792 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
793 	int v3 = NFS_ISV3(vp);
794 
795 	nfsstats.rpccnt[NFSPROC_SETATTR]++;
796 	nfsm_reqhead(vp, NFSPROC_SETATTR, NFSX_FH(v3) + NFSX_SATTR(v3));
797 	nfsm_fhtom(vp, v3);
798 	if (v3) {
799 		nfsm_v3attrbuild(vap, TRUE);
800 		nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
801 		*tl = nfs_false;
802 	} else {
803 		nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
804 		if (vap->va_mode == (mode_t)VNOVAL)
805 			sp->sa_mode = nfs_xdrneg1;
806 		else
807 			sp->sa_mode = vtonfsv2_mode(vp->v_type, vap->va_mode);
808 		if (vap->va_uid == (uid_t)VNOVAL)
809 			sp->sa_uid = nfs_xdrneg1;
810 		else
811 			sp->sa_uid = txdr_unsigned(vap->va_uid);
812 		if (vap->va_gid == (gid_t)VNOVAL)
813 			sp->sa_gid = nfs_xdrneg1;
814 		else
815 			sp->sa_gid = txdr_unsigned(vap->va_gid);
816 		sp->sa_size = txdr_unsigned(vap->va_size);
817 		txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
818 		txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
819 	}
820 	nfsm_request(vp, NFSPROC_SETATTR, td, cred);
821 	if (v3) {
822 		np->n_modestamp = 0;
823 		nfsm_wcc_data(vp, wccflag);
824 	} else
825 		nfsm_loadattr(vp, (struct vattr *)0);
826 	m_freem(mrep);
827 nfsmout:
828 	return (error);
829 }
830 
831 /*
832  * NEW API CALL - replaces nfs_lookup().  However, we cannot remove
833  * nfs_lookup() until all remaining new api calls are implemented.
834  *
835  * Resolve a namecache entry.  This function is passed a locked ncp and
836  * must call cache_setvp() on it as appropriate to resolve the entry.
837  */
838 static int
839 nfs_nresolve(struct vop_nresolve_args *ap)
840 {
841 	struct thread *td = curthread;
842 	struct namecache *ncp;
843 	struct ucred *cred;
844 	struct nfsnode *np;
845 	struct vnode *dvp;
846 	struct vnode *nvp;
847 	nfsfh_t *fhp;
848 	int attrflag;
849 	int fhsize;
850 	int error;
851 	int len;
852 	int v3;
853 	/******NFSM MACROS********/
854 	struct mbuf *mb, *mrep, *mreq, *mb2, *md;
855 	caddr_t bpos, dpos, cp, cp2;
856 	u_int32_t *tl;
857 	int32_t t1, t2;
858 
859 	cred = ap->a_cred;
860 	ncp = ap->a_ncp;
861 
862 	KKASSERT(ncp->nc_parent && ncp->nc_parent->nc_vp);
863 	dvp = ncp->nc_parent->nc_vp;
864 	if ((error = vget(dvp, LK_SHARED, td)) != 0)
865 		return (error);
866 
867 	nvp = NULL;
868 	v3 = NFS_ISV3(dvp);
869 	nfsstats.lookupcache_misses++;
870 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
871 	len = ncp->nc_nlen;
872 	nfsm_reqhead(dvp, NFSPROC_LOOKUP,
873 		NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len));
874 	nfsm_fhtom(dvp, v3);
875 	nfsm_strtom(ncp->nc_name, len, NFS_MAXNAMLEN);
876 	nfsm_request(dvp, NFSPROC_LOOKUP, td, ap->a_cred);
877 	if (error) {
878 		/*
879 		 * Cache negatve lookups to reduce NFS traffic, but use
880 		 * a fast timeout.  Otherwise use a timeout of 1 tick.
881 		 * XXX we should add a namecache flag for no-caching
882 		 * to uncache the negative hit as soon as possible, but
883 		 * we cannot simply destroy the entry because it is used
884 		 * as a placeholder by the caller.
885 		 */
886 		if (error == ENOENT) {
887 			int nticks;
888 
889 			if (nfsneg_cache_timeout)
890 				nticks = nfsneg_cache_timeout * hz;
891 			else
892 				nticks = 1;
893 			cache_setvp(ncp, NULL);
894 			cache_settimeout(ncp, nticks);
895 		}
896 		nfsm_postop_attr(dvp, attrflag, NFS_LATTR_NOSHRINK);
897 		m_freem(mrep);
898 		goto nfsmout;
899 	}
900 
901 	/*
902 	 * Success, get the file handle, do various checks, and load
903 	 * post-operation data from the reply packet.  Theoretically
904 	 * we should never be looking up "." so, theoretically, we
905 	 * should never get the same file handle as our directory.  But
906 	 * we check anyway. XXX
907 	 *
908 	 * Note that no timeout is set for the positive cache hit.  We
909 	 * assume, theoretically, that ESTALE returns will be dealt with
910 	 * properly to handle NFS races and in anycase we cannot depend
911 	 * on a timeout to deal with NFS open/create/excl issues so instead
912 	 * of a bad hack here the rest of the NFS client code needs to do
913 	 * the right thing.
914 	 */
915 	nfsm_getfh(fhp, fhsize, v3);
916 
917 	np = VTONFS(dvp);
918 	if (NFS_CMPFH(np, fhp, fhsize)) {
919 		vref(dvp);
920 		nvp = dvp;
921 	} else {
922 		error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
923 		if (error) {
924 			m_freem(mrep);
925 			vput(dvp);
926 			return (error);
927 		}
928 		nvp = NFSTOV(np);
929 	}
930 	if (v3) {
931 		nfsm_postop_attr(nvp, attrflag, NFS_LATTR_NOSHRINK);
932 		nfsm_postop_attr(dvp, attrflag, NFS_LATTR_NOSHRINK);
933 	} else {
934 		nfsm_loadattr(nvp, NULL);
935 	}
936 	cache_setvp(ncp, nvp);
937 	m_freem(mrep);
938 nfsmout:
939 	vput(dvp);
940 	if (nvp) {
941 		if (nvp == dvp)
942 			vrele(nvp);
943 		else
944 			vput(nvp);
945 	}
946 	return (error);
947 }
948 
949 /*
950  * 'cached' nfs directory lookup
951  *
952  * NOTE: cannot be removed until NFS implements all the new n*() API calls.
953  *
954  * nfs_lookup(struct vnodeop_desc *a_desc, struct vnode *a_dvp,
955  *	      struct vnode **a_vpp, struct componentname *a_cnp)
956  */
957 static int
958 nfs_lookup(struct vop_old_lookup_args *ap)
959 {
960 	struct componentname *cnp = ap->a_cnp;
961 	struct vnode *dvp = ap->a_dvp;
962 	struct vnode **vpp = ap->a_vpp;
963 	int flags = cnp->cn_flags;
964 	struct vnode *newvp;
965 	u_int32_t *tl;
966 	caddr_t cp;
967 	int32_t t1, t2;
968 	struct nfsmount *nmp;
969 	caddr_t bpos, dpos, cp2;
970 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
971 	long len;
972 	nfsfh_t *fhp;
973 	struct nfsnode *np;
974 	int lockparent, wantparent, error = 0, attrflag, fhsize;
975 	int v3 = NFS_ISV3(dvp);
976 	struct thread *td = cnp->cn_td;
977 
978 	/*
979 	 * Read-only mount check and directory check.
980 	 */
981 	*vpp = NULLVP;
982 	if ((dvp->v_mount->mnt_flag & MNT_RDONLY) &&
983 	    (cnp->cn_nameiop == NAMEI_DELETE || cnp->cn_nameiop == NAMEI_RENAME))
984 		return (EROFS);
985 
986 	if (dvp->v_type != VDIR)
987 		return (ENOTDIR);
988 
989 	/*
990 	 * Look it up in the cache.  Note that ENOENT is only returned if we
991 	 * previously entered a negative hit (see later on).  The additional
992 	 * nfsneg_cache_timeout check causes previously cached results to
993 	 * be instantly ignored if the negative caching is turned off.
994 	 */
995 	lockparent = flags & CNP_LOCKPARENT;
996 	wantparent = flags & (CNP_LOCKPARENT|CNP_WANTPARENT);
997 	nmp = VFSTONFS(dvp->v_mount);
998 	np = VTONFS(dvp);
999 
1000 	/*
1001 	 * Go to the wire.
1002 	 */
1003 	error = 0;
1004 	newvp = NULLVP;
1005 	nfsstats.lookupcache_misses++;
1006 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
1007 	len = cnp->cn_namelen;
1008 	nfsm_reqhead(dvp, NFSPROC_LOOKUP,
1009 		NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len));
1010 	nfsm_fhtom(dvp, v3);
1011 	nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);
1012 	nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_td, cnp->cn_cred);
1013 	if (error) {
1014 		nfsm_postop_attr(dvp, attrflag, NFS_LATTR_NOSHRINK);
1015 		m_freem(mrep);
1016 		goto nfsmout;
1017 	}
1018 	nfsm_getfh(fhp, fhsize, v3);
1019 
1020 	/*
1021 	 * Handle RENAME case...
1022 	 */
1023 	if (cnp->cn_nameiop == NAMEI_RENAME && wantparent) {
1024 		if (NFS_CMPFH(np, fhp, fhsize)) {
1025 			m_freem(mrep);
1026 			return (EISDIR);
1027 		}
1028 		error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
1029 		if (error) {
1030 			m_freem(mrep);
1031 			return (error);
1032 		}
1033 		newvp = NFSTOV(np);
1034 		if (v3) {
1035 			nfsm_postop_attr(newvp, attrflag, NFS_LATTR_NOSHRINK);
1036 			nfsm_postop_attr(dvp, attrflag, NFS_LATTR_NOSHRINK);
1037 		} else
1038 			nfsm_loadattr(newvp, (struct vattr *)0);
1039 		*vpp = newvp;
1040 		m_freem(mrep);
1041 		if (!lockparent) {
1042 			VOP_UNLOCK(dvp, 0, td);
1043 			cnp->cn_flags |= CNP_PDIRUNLOCK;
1044 		}
1045 		return (0);
1046 	}
1047 
1048 	if (flags & CNP_ISDOTDOT) {
1049 		VOP_UNLOCK(dvp, 0, td);
1050 		cnp->cn_flags |= CNP_PDIRUNLOCK;
1051 		error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
1052 		if (error) {
1053 			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
1054 			cnp->cn_flags &= ~CNP_PDIRUNLOCK;
1055 			return (error); /* NOTE: return error from nget */
1056 		}
1057 		newvp = NFSTOV(np);
1058 		if (lockparent) {
1059 			error = vn_lock(dvp, LK_EXCLUSIVE, td);
1060 			if (error) {
1061 				vput(newvp);
1062 				return (error);
1063 			}
1064 			cnp->cn_flags |= CNP_PDIRUNLOCK;
1065 		}
1066 	} else if (NFS_CMPFH(np, fhp, fhsize)) {
1067 		vref(dvp);
1068 		newvp = dvp;
1069 	} else {
1070 		error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
1071 		if (error) {
1072 			m_freem(mrep);
1073 			return (error);
1074 		}
1075 		if (!lockparent) {
1076 			VOP_UNLOCK(dvp, 0, td);
1077 			cnp->cn_flags |= CNP_PDIRUNLOCK;
1078 		}
1079 		newvp = NFSTOV(np);
1080 	}
1081 	if (v3) {
1082 		nfsm_postop_attr(newvp, attrflag, NFS_LATTR_NOSHRINK);
1083 		nfsm_postop_attr(dvp, attrflag, NFS_LATTR_NOSHRINK);
1084 	} else
1085 		nfsm_loadattr(newvp, (struct vattr *)0);
1086 #if 0
1087 	/* XXX MOVE TO nfs_nremove() */
1088 	if ((cnp->cn_flags & CNP_MAKEENTRY) &&
1089 	    cnp->cn_nameiop != NAMEI_DELETE) {
1090 		np->n_ctime = np->n_vattr.va_ctime.tv_sec; /* XXX */
1091 	}
1092 #endif
1093 	*vpp = newvp;
1094 	m_freem(mrep);
1095 nfsmout:
1096 	if (error) {
1097 		if (newvp != NULLVP) {
1098 			vrele(newvp);
1099 			*vpp = NULLVP;
1100 		}
1101 		if ((cnp->cn_nameiop == NAMEI_CREATE ||
1102 		     cnp->cn_nameiop == NAMEI_RENAME) &&
1103 		    error == ENOENT) {
1104 			if (!lockparent) {
1105 				VOP_UNLOCK(dvp, 0, td);
1106 				cnp->cn_flags |= CNP_PDIRUNLOCK;
1107 			}
1108 			if (dvp->v_mount->mnt_flag & MNT_RDONLY)
1109 				error = EROFS;
1110 			else
1111 				error = EJUSTRETURN;
1112 		}
1113 	}
1114 	return (error);
1115 }
1116 
1117 /*
1118  * nfs read call.
1119  * Just call nfs_bioread() to do the work.
1120  *
1121  * nfs_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
1122  *	    struct ucred *a_cred)
1123  */
1124 static int
1125 nfs_read(struct vop_read_args *ap)
1126 {
1127 	struct vnode *vp = ap->a_vp;
1128 
1129 	return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag));
1130 	switch (vp->v_type) {
1131 	case VREG:
1132 		return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag));
1133 	case VDIR:
1134 		return (EISDIR);
1135 	default:
1136 		return EOPNOTSUPP;
1137 	}
1138 }
1139 
1140 /*
1141  * nfs readlink call
1142  *
1143  * nfs_readlink(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred)
1144  */
1145 static int
1146 nfs_readlink(struct vop_readlink_args *ap)
1147 {
1148 	struct vnode *vp = ap->a_vp;
1149 
1150 	if (vp->v_type != VLNK)
1151 		return (EINVAL);
1152 	return (nfs_bioread(vp, ap->a_uio, 0));
1153 }
1154 
1155 /*
1156  * Do a readlink rpc.
1157  * Called by nfs_doio() from below the buffer cache.
1158  */
1159 int
1160 nfs_readlinkrpc(struct vnode *vp, struct uio *uiop)
1161 {
1162 	u_int32_t *tl;
1163 	caddr_t cp;
1164 	int32_t t1, t2;
1165 	caddr_t bpos, dpos, cp2;
1166 	int error = 0, len, attrflag;
1167 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1168 	int v3 = NFS_ISV3(vp);
1169 
1170 	nfsstats.rpccnt[NFSPROC_READLINK]++;
1171 	nfsm_reqhead(vp, NFSPROC_READLINK, NFSX_FH(v3));
1172 	nfsm_fhtom(vp, v3);
1173 	nfsm_request(vp, NFSPROC_READLINK, uiop->uio_td, nfs_vpcred(vp, ND_CHECK));
1174 	if (v3)
1175 		nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK);
1176 	if (!error) {
1177 		nfsm_strsiz(len, NFS_MAXPATHLEN);
1178 		if (len == NFS_MAXPATHLEN) {
1179 			struct nfsnode *np = VTONFS(vp);
1180 			if (np->n_size && np->n_size < NFS_MAXPATHLEN)
1181 				len = np->n_size;
1182 		}
1183 		nfsm_mtouio(uiop, len);
1184 	}
1185 	m_freem(mrep);
1186 nfsmout:
1187 	return (error);
1188 }
1189 
1190 /*
1191  * nfs read rpc call
1192  * Ditto above
1193  */
1194 int
1195 nfs_readrpc(struct vnode *vp, struct uio *uiop)
1196 {
1197 	u_int32_t *tl;
1198 	caddr_t cp;
1199 	int32_t t1, t2;
1200 	caddr_t bpos, dpos, cp2;
1201 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1202 	struct nfsmount *nmp;
1203 	int error = 0, len, retlen, tsiz, eof, attrflag;
1204 	int v3 = NFS_ISV3(vp);
1205 
1206 #ifndef nolint
1207 	eof = 0;
1208 #endif
1209 	nmp = VFSTONFS(vp->v_mount);
1210 	tsiz = uiop->uio_resid;
1211 	if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
1212 		return (EFBIG);
1213 	while (tsiz > 0) {
1214 		nfsstats.rpccnt[NFSPROC_READ]++;
1215 		len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
1216 		nfsm_reqhead(vp, NFSPROC_READ, NFSX_FH(v3) + NFSX_UNSIGNED * 3);
1217 		nfsm_fhtom(vp, v3);
1218 		nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED * 3);
1219 		if (v3) {
1220 			txdr_hyper(uiop->uio_offset, tl);
1221 			*(tl + 2) = txdr_unsigned(len);
1222 		} else {
1223 			*tl++ = txdr_unsigned(uiop->uio_offset);
1224 			*tl++ = txdr_unsigned(len);
1225 			*tl = 0;
1226 		}
1227 		nfsm_request(vp, NFSPROC_READ, uiop->uio_td, nfs_vpcred(vp, ND_READ));
1228 		if (v3) {
1229 			nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK);
1230 			if (error) {
1231 				m_freem(mrep);
1232 				goto nfsmout;
1233 			}
1234 			nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
1235 			eof = fxdr_unsigned(int, *(tl + 1));
1236 		} else
1237 			nfsm_loadattr(vp, (struct vattr *)0);
1238 		nfsm_strsiz(retlen, nmp->nm_rsize);
1239 		nfsm_mtouio(uiop, retlen);
1240 		m_freem(mrep);
1241 		tsiz -= retlen;
1242 		if (v3) {
1243 			if (eof || retlen == 0) {
1244 				tsiz = 0;
1245 			}
1246 		} else if (retlen < len) {
1247 			tsiz = 0;
1248 		}
1249 	}
1250 nfsmout:
1251 	return (error);
1252 }
1253 
1254 /*
1255  * nfs write call
1256  */
1257 int
1258 nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit)
1259 {
1260 	u_int32_t *tl;
1261 	caddr_t cp;
1262 	int32_t t1, t2, backup;
1263 	caddr_t bpos, dpos, cp2;
1264 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1265 	struct nfsmount *nmp = VFSTONFS(vp->v_mount);
1266 	int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit;
1267 	int v3 = NFS_ISV3(vp), committed = NFSV3WRITE_FILESYNC;
1268 
1269 #ifndef DIAGNOSTIC
1270 	if (uiop->uio_iovcnt != 1)
1271 		panic("nfs: writerpc iovcnt > 1");
1272 #endif
1273 	*must_commit = 0;
1274 	tsiz = uiop->uio_resid;
1275 	if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
1276 		return (EFBIG);
1277 	while (tsiz > 0) {
1278 		nfsstats.rpccnt[NFSPROC_WRITE]++;
1279 		len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz;
1280 		nfsm_reqhead(vp, NFSPROC_WRITE,
1281 			NFSX_FH(v3) + 5 * NFSX_UNSIGNED + nfsm_rndup(len));
1282 		nfsm_fhtom(vp, v3);
1283 		if (v3) {
1284 			nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
1285 			txdr_hyper(uiop->uio_offset, tl);
1286 			tl += 2;
1287 			*tl++ = txdr_unsigned(len);
1288 			*tl++ = txdr_unsigned(*iomode);
1289 			*tl = txdr_unsigned(len);
1290 		} else {
1291 			u_int32_t x;
1292 
1293 			nfsm_build(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
1294 			/* Set both "begin" and "current" to non-garbage. */
1295 			x = txdr_unsigned((u_int32_t)uiop->uio_offset);
1296 			*tl++ = x;	/* "begin offset" */
1297 			*tl++ = x;	/* "current offset" */
1298 			x = txdr_unsigned(len);
1299 			*tl++ = x;	/* total to this offset */
1300 			*tl = x;	/* size of this write */
1301 		}
1302 		nfsm_uiotom(uiop, len);
1303 		nfsm_request(vp, NFSPROC_WRITE, uiop->uio_td, nfs_vpcred(vp, ND_WRITE));
1304 		if (v3) {
1305 			/*
1306 			 * The write RPC returns a before and after mtime.  The
1307 			 * nfsm_wcc_data() macro checks the before n_mtime
1308 			 * against the before time and stores the after time
1309 			 * in the nfsnode's cached vattr and n_mtime field.
1310 			 * The NRMODIFIED bit will be set if the before
1311 			 * time did not match the original mtime.
1312 			 */
1313 			wccflag = NFSV3_WCCCHK;
1314 			nfsm_wcc_data(vp, wccflag);
1315 			if (!error) {
1316 				nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED
1317 					+ NFSX_V3WRITEVERF);
1318 				rlen = fxdr_unsigned(int, *tl++);
1319 				if (rlen == 0) {
1320 					error = NFSERR_IO;
1321 					m_freem(mrep);
1322 					break;
1323 				} else if (rlen < len) {
1324 					backup = len - rlen;
1325 					uiop->uio_iov->iov_base -= backup;
1326 					uiop->uio_iov->iov_len += backup;
1327 					uiop->uio_offset -= backup;
1328 					uiop->uio_resid += backup;
1329 					len = rlen;
1330 				}
1331 				commit = fxdr_unsigned(int, *tl++);
1332 
1333 				/*
1334 				 * Return the lowest committment level
1335 				 * obtained by any of the RPCs.
1336 				 */
1337 				if (committed == NFSV3WRITE_FILESYNC)
1338 					committed = commit;
1339 				else if (committed == NFSV3WRITE_DATASYNC &&
1340 					commit == NFSV3WRITE_UNSTABLE)
1341 					committed = commit;
1342 				if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0){
1343 				    bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
1344 					NFSX_V3WRITEVERF);
1345 				    nmp->nm_state |= NFSSTA_HASWRITEVERF;
1346 				} else if (bcmp((caddr_t)tl,
1347 				    (caddr_t)nmp->nm_verf, NFSX_V3WRITEVERF)) {
1348 				    *must_commit = 1;
1349 				    bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
1350 					NFSX_V3WRITEVERF);
1351 				}
1352 			}
1353 		} else {
1354 			nfsm_loadattr(vp, (struct vattr *)0);
1355 		}
1356 		m_freem(mrep);
1357 		if (error)
1358 			break;
1359 		tsiz -= len;
1360 	}
1361 nfsmout:
1362 	if (vp->v_mount->mnt_flag & MNT_ASYNC)
1363 		committed = NFSV3WRITE_FILESYNC;
1364 	*iomode = committed;
1365 	if (error)
1366 		uiop->uio_resid = tsiz;
1367 	return (error);
1368 }
1369 
1370 /*
1371  * nfs mknod rpc
1372  * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the
1373  * mode set to specify the file type and the size field for rdev.
1374  */
1375 static int
1376 nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
1377 	     struct vattr *vap)
1378 {
1379 	struct nfsv2_sattr *sp;
1380 	u_int32_t *tl;
1381 	caddr_t cp;
1382 	int32_t t1, t2;
1383 	struct vnode *newvp = (struct vnode *)0;
1384 	struct nfsnode *np = (struct nfsnode *)0;
1385 	struct vattr vattr;
1386 	char *cp2;
1387 	caddr_t bpos, dpos;
1388 	int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0;
1389 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1390 	u_int32_t rdev;
1391 	int v3 = NFS_ISV3(dvp);
1392 
1393 	if (vap->va_type == VCHR || vap->va_type == VBLK)
1394 		rdev = txdr_unsigned(vap->va_rdev);
1395 	else if (vap->va_type == VFIFO || vap->va_type == VSOCK)
1396 		rdev = nfs_xdrneg1;
1397 	else {
1398 		return (EOPNOTSUPP);
1399 	}
1400 	if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_td)) != 0) {
1401 		return (error);
1402 	}
1403 	nfsstats.rpccnt[NFSPROC_MKNOD]++;
1404 	nfsm_reqhead(dvp, NFSPROC_MKNOD, NFSX_FH(v3) + 4 * NFSX_UNSIGNED +
1405 		+ nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3));
1406 	nfsm_fhtom(dvp, v3);
1407 	nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
1408 	if (v3) {
1409 		nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
1410 		*tl++ = vtonfsv3_type(vap->va_type);
1411 		nfsm_v3attrbuild(vap, FALSE);
1412 		if (vap->va_type == VCHR || vap->va_type == VBLK) {
1413 			nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
1414 			*tl++ = txdr_unsigned(umajor(vap->va_rdev));
1415 			*tl = txdr_unsigned(uminor(vap->va_rdev));
1416 		}
1417 	} else {
1418 		nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
1419 		sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
1420 		sp->sa_uid = nfs_xdrneg1;
1421 		sp->sa_gid = nfs_xdrneg1;
1422 		sp->sa_size = rdev;
1423 		txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
1424 		txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
1425 	}
1426 	nfsm_request(dvp, NFSPROC_MKNOD, cnp->cn_td, cnp->cn_cred);
1427 	if (!error) {
1428 		nfsm_mtofh(dvp, newvp, v3, gotvp);
1429 		if (!gotvp) {
1430 			if (newvp) {
1431 				vput(newvp);
1432 				newvp = (struct vnode *)0;
1433 			}
1434 			error = nfs_lookitup(dvp, cnp->cn_nameptr,
1435 			    cnp->cn_namelen, cnp->cn_cred, cnp->cn_td, &np);
1436 			if (!error)
1437 				newvp = NFSTOV(np);
1438 		}
1439 	}
1440 	if (v3)
1441 		nfsm_wcc_data(dvp, wccflag);
1442 	m_freem(mrep);
1443 nfsmout:
1444 	if (error) {
1445 		if (newvp)
1446 			vput(newvp);
1447 	} else {
1448 		*vpp = newvp;
1449 	}
1450 	VTONFS(dvp)->n_flag |= NLMODIFIED;
1451 	if (!wccflag)
1452 		VTONFS(dvp)->n_attrstamp = 0;
1453 	return (error);
1454 }
1455 
1456 /*
1457  * nfs mknod vop
1458  * just call nfs_mknodrpc() to do the work.
1459  *
1460  * nfs_mknod(struct vnode *a_dvp, struct vnode **a_vpp,
1461  *	     struct componentname *a_cnp, struct vattr *a_vap)
1462  */
1463 /* ARGSUSED */
1464 static int
1465 nfs_mknod(struct vop_old_mknod_args *ap)
1466 {
1467 	return nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap);
1468 }
1469 
1470 static u_long create_verf;
1471 /*
1472  * nfs file create call
1473  *
1474  * nfs_create(struct vnode *a_dvp, struct vnode **a_vpp,
1475  *	      struct componentname *a_cnp, struct vattr *a_vap)
1476  */
1477 static int
1478 nfs_create(struct vop_old_create_args *ap)
1479 {
1480 	struct vnode *dvp = ap->a_dvp;
1481 	struct vattr *vap = ap->a_vap;
1482 	struct componentname *cnp = ap->a_cnp;
1483 	struct nfsv2_sattr *sp;
1484 	u_int32_t *tl;
1485 	caddr_t cp;
1486 	int32_t t1, t2;
1487 	struct nfsnode *np = (struct nfsnode *)0;
1488 	struct vnode *newvp = (struct vnode *)0;
1489 	caddr_t bpos, dpos, cp2;
1490 	int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0;
1491 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1492 	struct vattr vattr;
1493 	int v3 = NFS_ISV3(dvp);
1494 
1495 	/*
1496 	 * Oops, not for me..
1497 	 */
1498 	if (vap->va_type == VSOCK)
1499 		return (nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap));
1500 
1501 	if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_td)) != 0) {
1502 		return (error);
1503 	}
1504 	if (vap->va_vaflags & VA_EXCLUSIVE)
1505 		fmode |= O_EXCL;
1506 again:
1507 	nfsstats.rpccnt[NFSPROC_CREATE]++;
1508 	nfsm_reqhead(dvp, NFSPROC_CREATE, NFSX_FH(v3) + 2 * NFSX_UNSIGNED +
1509 		nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3));
1510 	nfsm_fhtom(dvp, v3);
1511 	nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
1512 	if (v3) {
1513 		nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);
1514 		if (fmode & O_EXCL) {
1515 			*tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE);
1516 			nfsm_build(tl, u_int32_t *, NFSX_V3CREATEVERF);
1517 #ifdef INET
1518 			if (!TAILQ_EMPTY(&in_ifaddrhead))
1519 				*tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr.s_addr;
1520 			else
1521 #endif
1522 				*tl++ = create_verf;
1523 			*tl = ++create_verf;
1524 		} else {
1525 			*tl = txdr_unsigned(NFSV3CREATE_UNCHECKED);
1526 			nfsm_v3attrbuild(vap, FALSE);
1527 		}
1528 	} else {
1529 		nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
1530 		sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
1531 		sp->sa_uid = nfs_xdrneg1;
1532 		sp->sa_gid = nfs_xdrneg1;
1533 		sp->sa_size = 0;
1534 		txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
1535 		txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
1536 	}
1537 	nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_td, cnp->cn_cred);
1538 	if (!error) {
1539 		nfsm_mtofh(dvp, newvp, v3, gotvp);
1540 		if (!gotvp) {
1541 			if (newvp) {
1542 				vput(newvp);
1543 				newvp = (struct vnode *)0;
1544 			}
1545 			error = nfs_lookitup(dvp, cnp->cn_nameptr,
1546 			    cnp->cn_namelen, cnp->cn_cred, cnp->cn_td, &np);
1547 			if (!error)
1548 				newvp = NFSTOV(np);
1549 		}
1550 	}
1551 	if (v3)
1552 		nfsm_wcc_data(dvp, wccflag);
1553 	m_freem(mrep);
1554 nfsmout:
1555 	if (error) {
1556 		if (v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) {
1557 			fmode &= ~O_EXCL;
1558 			goto again;
1559 		}
1560 		if (newvp)
1561 			vput(newvp);
1562 	} else if (v3 && (fmode & O_EXCL)) {
1563 		/*
1564 		 * We are normally called with only a partially initialized
1565 		 * VAP.  Since the NFSv3 spec says that server may use the
1566 		 * file attributes to store the verifier, the spec requires
1567 		 * us to do a SETATTR RPC. FreeBSD servers store the verifier
1568 		 * in atime, but we can't really assume that all servers will
1569 		 * so we ensure that our SETATTR sets both atime and mtime.
1570 		 */
1571 		if (vap->va_mtime.tv_sec == VNOVAL)
1572 			vfs_timestamp(&vap->va_mtime);
1573 		if (vap->va_atime.tv_sec == VNOVAL)
1574 			vap->va_atime = vap->va_mtime;
1575 		error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_td);
1576 	}
1577 	if (!error) {
1578 		/*
1579 		 * The new np may have enough info for access
1580 		 * checks, make sure rucred and wucred are
1581 		 * initialized for read and write rpc's.
1582 		 */
1583 		np = VTONFS(newvp);
1584 		if (np->n_rucred == NULL)
1585 			np->n_rucred = crhold(cnp->cn_cred);
1586 		if (np->n_wucred == NULL)
1587 			np->n_wucred = crhold(cnp->cn_cred);
1588 		*ap->a_vpp = newvp;
1589 	}
1590 	VTONFS(dvp)->n_flag |= NLMODIFIED;
1591 	if (!wccflag)
1592 		VTONFS(dvp)->n_attrstamp = 0;
1593 	return (error);
1594 }
1595 
1596 /*
1597  * nfs file remove call
1598  * To try and make nfs semantics closer to ufs semantics, a file that has
1599  * other processes using the vnode is renamed instead of removed and then
1600  * removed later on the last close.
1601  * - If v_usecount > 1
1602  *	  If a rename is not already in the works
1603  *	     call nfs_sillyrename() to set it up
1604  *     else
1605  *	  do the remove rpc
1606  *
1607  * nfs_remove(struct vnodeop_desc *a_desc, struct vnode *a_dvp,
1608  *	      struct vnode *a_vp, struct componentname *a_cnp)
1609  */
1610 static int
1611 nfs_remove(struct vop_old_remove_args *ap)
1612 {
1613 	struct vnode *vp = ap->a_vp;
1614 	struct vnode *dvp = ap->a_dvp;
1615 	struct componentname *cnp = ap->a_cnp;
1616 	struct nfsnode *np = VTONFS(vp);
1617 	int error = 0;
1618 	struct vattr vattr;
1619 
1620 #ifndef DIAGNOSTIC
1621 	if (vp->v_usecount < 1)
1622 		panic("nfs_remove: bad v_usecount");
1623 #endif
1624 	if (vp->v_type == VDIR)
1625 		error = EPERM;
1626 	else if (vp->v_usecount == 1 || (np->n_sillyrename &&
1627 	    VOP_GETATTR(vp, &vattr, cnp->cn_td) == 0 &&
1628 	    vattr.va_nlink > 1)) {
1629 		/*
1630 		 * throw away biocache buffers, mainly to avoid
1631 		 * unnecessary delayed writes later.
1632 		 */
1633 		error = nfs_vinvalbuf(vp, 0, cnp->cn_td, 1);
1634 		/* Do the rpc */
1635 		if (error != EINTR)
1636 			error = nfs_removerpc(dvp, cnp->cn_nameptr,
1637 				cnp->cn_namelen, cnp->cn_cred, cnp->cn_td);
1638 		/*
1639 		 * Kludge City: If the first reply to the remove rpc is lost..
1640 		 *   the reply to the retransmitted request will be ENOENT
1641 		 *   since the file was in fact removed
1642 		 *   Therefore, we cheat and return success.
1643 		 */
1644 		if (error == ENOENT)
1645 			error = 0;
1646 	} else if (!np->n_sillyrename) {
1647 		error = nfs_sillyrename(dvp, vp, cnp);
1648 	}
1649 	np->n_attrstamp = 0;
1650 	return (error);
1651 }
1652 
1653 /*
1654  * nfs file remove rpc called from nfs_inactive
1655  */
1656 int
1657 nfs_removeit(struct sillyrename *sp)
1658 {
1659 	return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen,
1660 		sp->s_cred, NULL));
1661 }
1662 
1663 /*
1664  * Nfs remove rpc, called from nfs_remove() and nfs_removeit().
1665  */
1666 static int
1667 nfs_removerpc(struct vnode *dvp, const char *name, int namelen,
1668 	      struct ucred *cred, struct thread *td)
1669 {
1670 	u_int32_t *tl;
1671 	caddr_t cp;
1672 	int32_t t1, t2;
1673 	caddr_t bpos, dpos, cp2;
1674 	int error = 0, wccflag = NFSV3_WCCRATTR;
1675 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1676 	int v3 = NFS_ISV3(dvp);
1677 
1678 	nfsstats.rpccnt[NFSPROC_REMOVE]++;
1679 	nfsm_reqhead(dvp, NFSPROC_REMOVE,
1680 		NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen));
1681 	nfsm_fhtom(dvp, v3);
1682 	nfsm_strtom(name, namelen, NFS_MAXNAMLEN);
1683 	nfsm_request(dvp, NFSPROC_REMOVE, td, cred);
1684 	if (v3)
1685 		nfsm_wcc_data(dvp, wccflag);
1686 	m_freem(mrep);
1687 nfsmout:
1688 	VTONFS(dvp)->n_flag |= NLMODIFIED;
1689 	if (!wccflag)
1690 		VTONFS(dvp)->n_attrstamp = 0;
1691 	return (error);
1692 }
1693 
1694 /*
1695  * nfs file rename call
1696  *
1697  * nfs_rename(struct vnode *a_fdvp, struct vnode *a_fvp,
1698  *	      struct componentname *a_fcnp, struct vnode *a_tdvp,
1699  *	      struct vnode *a_tvp, struct componentname *a_tcnp)
1700  */
1701 static int
1702 nfs_rename(struct vop_old_rename_args *ap)
1703 {
1704 	struct vnode *fvp = ap->a_fvp;
1705 	struct vnode *tvp = ap->a_tvp;
1706 	struct vnode *fdvp = ap->a_fdvp;
1707 	struct vnode *tdvp = ap->a_tdvp;
1708 	struct componentname *tcnp = ap->a_tcnp;
1709 	struct componentname *fcnp = ap->a_fcnp;
1710 	int error;
1711 
1712 	/* Check for cross-device rename */
1713 	if ((fvp->v_mount != tdvp->v_mount) ||
1714 	    (tvp && (fvp->v_mount != tvp->v_mount))) {
1715 		error = EXDEV;
1716 		goto out;
1717 	}
1718 
1719 	/*
1720 	 * We have to flush B_DELWRI data prior to renaming
1721 	 * the file.  If we don't, the delayed-write buffers
1722 	 * can be flushed out later after the file has gone stale
1723 	 * under NFSV3.  NFSV2 does not have this problem because
1724 	 * ( as far as I can tell ) it flushes dirty buffers more
1725 	 * often.
1726 	 */
1727 
1728 	VOP_FSYNC(fvp, MNT_WAIT, fcnp->cn_td);
1729 	if (tvp)
1730 	    VOP_FSYNC(tvp, MNT_WAIT, tcnp->cn_td);
1731 
1732 	/*
1733 	 * If the tvp exists and is in use, sillyrename it before doing the
1734 	 * rename of the new file over it.
1735 	 *
1736 	 * XXX Can't sillyrename a directory.
1737 	 *
1738 	 * We do not attempt to do any namecache purges in this old API
1739 	 * routine.  The new API compat functions have access to the actual
1740 	 * namecache structures and will do it for us.
1741 	 */
1742 	if (tvp && tvp->v_usecount > 1 && !VTONFS(tvp)->n_sillyrename &&
1743 		tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) {
1744 		vput(tvp);
1745 		tvp = NULL;
1746 	} else if (tvp) {
1747 		;
1748 	}
1749 
1750 	error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen,
1751 		tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred,
1752 		tcnp->cn_td);
1753 
1754 out:
1755 	if (tdvp == tvp)
1756 		vrele(tdvp);
1757 	else
1758 		vput(tdvp);
1759 	if (tvp)
1760 		vput(tvp);
1761 	vrele(fdvp);
1762 	vrele(fvp);
1763 	/*
1764 	 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
1765 	 */
1766 	if (error == ENOENT)
1767 		error = 0;
1768 	return (error);
1769 }
1770 
1771 /*
1772  * nfs file rename rpc called from nfs_remove() above
1773  */
1774 static int
1775 nfs_renameit(struct vnode *sdvp, struct componentname *scnp,
1776 	     struct sillyrename *sp)
1777 {
1778 	return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen,
1779 		sdvp, sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_td));
1780 }
1781 
1782 /*
1783  * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit().
1784  */
1785 static int
1786 nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen,
1787 	      struct vnode *tdvp, const char *tnameptr, int tnamelen,
1788 	      struct ucred *cred, struct thread *td)
1789 {
1790 	u_int32_t *tl;
1791 	caddr_t cp;
1792 	int32_t t1, t2;
1793 	caddr_t bpos, dpos, cp2;
1794 	int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR;
1795 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1796 	int v3 = NFS_ISV3(fdvp);
1797 
1798 	nfsstats.rpccnt[NFSPROC_RENAME]++;
1799 	nfsm_reqhead(fdvp, NFSPROC_RENAME,
1800 		(NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) +
1801 		nfsm_rndup(tnamelen));
1802 	nfsm_fhtom(fdvp, v3);
1803 	nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN);
1804 	nfsm_fhtom(tdvp, v3);
1805 	nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN);
1806 	nfsm_request(fdvp, NFSPROC_RENAME, td, cred);
1807 	if (v3) {
1808 		nfsm_wcc_data(fdvp, fwccflag);
1809 		nfsm_wcc_data(tdvp, twccflag);
1810 	}
1811 	m_freem(mrep);
1812 nfsmout:
1813 	VTONFS(fdvp)->n_flag |= NLMODIFIED;
1814 	VTONFS(tdvp)->n_flag |= NLMODIFIED;
1815 	if (!fwccflag)
1816 		VTONFS(fdvp)->n_attrstamp = 0;
1817 	if (!twccflag)
1818 		VTONFS(tdvp)->n_attrstamp = 0;
1819 	return (error);
1820 }
1821 
1822 /*
1823  * nfs hard link create call
1824  *
1825  * nfs_link(struct vnode *a_tdvp, struct vnode *a_vp,
1826  *	    struct componentname *a_cnp)
1827  */
1828 static int
1829 nfs_link(struct vop_old_link_args *ap)
1830 {
1831 	struct vnode *vp = ap->a_vp;
1832 	struct vnode *tdvp = ap->a_tdvp;
1833 	struct componentname *cnp = ap->a_cnp;
1834 	u_int32_t *tl;
1835 	caddr_t cp;
1836 	int32_t t1, t2;
1837 	caddr_t bpos, dpos, cp2;
1838 	int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0;
1839 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1840 	int v3;
1841 
1842 	if (vp->v_mount != tdvp->v_mount) {
1843 		return (EXDEV);
1844 	}
1845 
1846 	/*
1847 	 * Push all writes to the server, so that the attribute cache
1848 	 * doesn't get "out of sync" with the server.
1849 	 * XXX There should be a better way!
1850 	 */
1851 	VOP_FSYNC(vp, MNT_WAIT, cnp->cn_td);
1852 
1853 	v3 = NFS_ISV3(vp);
1854 	nfsstats.rpccnt[NFSPROC_LINK]++;
1855 	nfsm_reqhead(vp, NFSPROC_LINK,
1856 		NFSX_FH(v3)*2 + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen));
1857 	nfsm_fhtom(vp, v3);
1858 	nfsm_fhtom(tdvp, v3);
1859 	nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
1860 	nfsm_request(vp, NFSPROC_LINK, cnp->cn_td, cnp->cn_cred);
1861 	if (v3) {
1862 		nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK);
1863 		nfsm_wcc_data(tdvp, wccflag);
1864 	}
1865 	m_freem(mrep);
1866 nfsmout:
1867 	VTONFS(tdvp)->n_flag |= NLMODIFIED;
1868 	if (!attrflag)
1869 		VTONFS(vp)->n_attrstamp = 0;
1870 	if (!wccflag)
1871 		VTONFS(tdvp)->n_attrstamp = 0;
1872 	/*
1873 	 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
1874 	 */
1875 	if (error == EEXIST)
1876 		error = 0;
1877 	return (error);
1878 }
1879 
1880 /*
1881  * nfs symbolic link create call
1882  *
1883  * nfs_symlink(struct vnode *a_dvp, struct vnode **a_vpp,
1884  *		struct componentname *a_cnp, struct vattr *a_vap,
1885  *		char *a_target)
1886  */
1887 static int
1888 nfs_symlink(struct vop_old_symlink_args *ap)
1889 {
1890 	struct vnode *dvp = ap->a_dvp;
1891 	struct vattr *vap = ap->a_vap;
1892 	struct componentname *cnp = ap->a_cnp;
1893 	struct nfsv2_sattr *sp;
1894 	u_int32_t *tl;
1895 	caddr_t cp;
1896 	int32_t t1, t2;
1897 	caddr_t bpos, dpos, cp2;
1898 	int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp;
1899 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1900 	struct vnode *newvp = (struct vnode *)0;
1901 	int v3 = NFS_ISV3(dvp);
1902 
1903 	nfsstats.rpccnt[NFSPROC_SYMLINK]++;
1904 	slen = strlen(ap->a_target);
1905 	nfsm_reqhead(dvp, NFSPROC_SYMLINK, NFSX_FH(v3) + 2*NFSX_UNSIGNED +
1906 	    nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3));
1907 	nfsm_fhtom(dvp, v3);
1908 	nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
1909 	if (v3) {
1910 		nfsm_v3attrbuild(vap, FALSE);
1911 	}
1912 	nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN);
1913 	if (!v3) {
1914 		nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
1915 		sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode);
1916 		sp->sa_uid = nfs_xdrneg1;
1917 		sp->sa_gid = nfs_xdrneg1;
1918 		sp->sa_size = nfs_xdrneg1;
1919 		txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
1920 		txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
1921 	}
1922 
1923 	/*
1924 	 * Issue the NFS request and get the rpc response.
1925 	 *
1926 	 * Only NFSv3 responses returning an error of 0 actually return
1927 	 * a file handle that can be converted into newvp without having
1928 	 * to do an extra lookup rpc.
1929 	 */
1930 	nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_td, cnp->cn_cred);
1931 	if (v3) {
1932 		if (error == 0)
1933 			nfsm_mtofh(dvp, newvp, v3, gotvp);
1934 		nfsm_wcc_data(dvp, wccflag);
1935 	}
1936 
1937 	/*
1938 	 * out code jumps -> here, mrep is also freed.
1939 	 */
1940 
1941 	m_freem(mrep);
1942 nfsmout:
1943 
1944 	/*
1945 	 * If we get an EEXIST error, silently convert it to no-error
1946 	 * in case of an NFS retry.
1947 	 */
1948 	if (error == EEXIST)
1949 		error = 0;
1950 
1951 	/*
1952 	 * If we do not have (or no longer have) an error, and we could
1953 	 * not extract the newvp from the response due to the request being
1954 	 * NFSv2 or the error being EEXIST.  We have to do a lookup in order
1955 	 * to obtain a newvp to return.
1956 	 */
1957 	if (error == 0 && newvp == NULL) {
1958 		struct nfsnode *np = NULL;
1959 
1960 		error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen,
1961 		    cnp->cn_cred, cnp->cn_td, &np);
1962 		if (!error)
1963 			newvp = NFSTOV(np);
1964 	}
1965 	if (error) {
1966 		if (newvp)
1967 			vput(newvp);
1968 	} else {
1969 		*ap->a_vpp = newvp;
1970 	}
1971 	VTONFS(dvp)->n_flag |= NLMODIFIED;
1972 	if (!wccflag)
1973 		VTONFS(dvp)->n_attrstamp = 0;
1974 	return (error);
1975 }
1976 
1977 /*
1978  * nfs make dir call
1979  *
1980  * nfs_mkdir(struct vnode *a_dvp, struct vnode **a_vpp,
1981  *	     struct componentname *a_cnp, struct vattr *a_vap)
1982  */
1983 static int
1984 nfs_mkdir(struct vop_old_mkdir_args *ap)
1985 {
1986 	struct vnode *dvp = ap->a_dvp;
1987 	struct vattr *vap = ap->a_vap;
1988 	struct componentname *cnp = ap->a_cnp;
1989 	struct nfsv2_sattr *sp;
1990 	u_int32_t *tl;
1991 	caddr_t cp;
1992 	int32_t t1, t2;
1993 	int len;
1994 	struct nfsnode *np = (struct nfsnode *)0;
1995 	struct vnode *newvp = (struct vnode *)0;
1996 	caddr_t bpos, dpos, cp2;
1997 	int error = 0, wccflag = NFSV3_WCCRATTR;
1998 	int gotvp = 0;
1999 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
2000 	struct vattr vattr;
2001 	int v3 = NFS_ISV3(dvp);
2002 
2003 	if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_td)) != 0) {
2004 		return (error);
2005 	}
2006 	len = cnp->cn_namelen;
2007 	nfsstats.rpccnt[NFSPROC_MKDIR]++;
2008 	nfsm_reqhead(dvp, NFSPROC_MKDIR,
2009 	  NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) + NFSX_SATTR(v3));
2010 	nfsm_fhtom(dvp, v3);
2011 	nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);
2012 	if (v3) {
2013 		nfsm_v3attrbuild(vap, FALSE);
2014 	} else {
2015 		nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
2016 		sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode);
2017 		sp->sa_uid = nfs_xdrneg1;
2018 		sp->sa_gid = nfs_xdrneg1;
2019 		sp->sa_size = nfs_xdrneg1;
2020 		txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
2021 		txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
2022 	}
2023 	nfsm_request(dvp, NFSPROC_MKDIR, cnp->cn_td, cnp->cn_cred);
2024 	if (!error)
2025 		nfsm_mtofh(dvp, newvp, v3, gotvp);
2026 	if (v3)
2027 		nfsm_wcc_data(dvp, wccflag);
2028 	m_freem(mrep);
2029 nfsmout:
2030 	VTONFS(dvp)->n_flag |= NLMODIFIED;
2031 	if (!wccflag)
2032 		VTONFS(dvp)->n_attrstamp = 0;
2033 	/*
2034 	 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry
2035 	 * if we can succeed in looking up the directory.
2036 	 */
2037 	if (error == EEXIST || (!error && !gotvp)) {
2038 		if (newvp) {
2039 			vrele(newvp);
2040 			newvp = (struct vnode *)0;
2041 		}
2042 		error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred,
2043 			cnp->cn_td, &np);
2044 		if (!error) {
2045 			newvp = NFSTOV(np);
2046 			if (newvp->v_type != VDIR)
2047 				error = EEXIST;
2048 		}
2049 	}
2050 	if (error) {
2051 		if (newvp)
2052 			vrele(newvp);
2053 	} else
2054 		*ap->a_vpp = newvp;
2055 	return (error);
2056 }
2057 
2058 /*
2059  * nfs remove directory call
2060  *
2061  * nfs_rmdir(struct vnode *a_dvp, struct vnode *a_vp,
2062  *	     struct componentname *a_cnp)
2063  */
2064 static int
2065 nfs_rmdir(struct vop_old_rmdir_args *ap)
2066 {
2067 	struct vnode *vp = ap->a_vp;
2068 	struct vnode *dvp = ap->a_dvp;
2069 	struct componentname *cnp = ap->a_cnp;
2070 	u_int32_t *tl;
2071 	caddr_t cp;
2072 	int32_t t1, t2;
2073 	caddr_t bpos, dpos, cp2;
2074 	int error = 0, wccflag = NFSV3_WCCRATTR;
2075 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
2076 	int v3 = NFS_ISV3(dvp);
2077 
2078 	if (dvp == vp)
2079 		return (EINVAL);
2080 	nfsstats.rpccnt[NFSPROC_RMDIR]++;
2081 	nfsm_reqhead(dvp, NFSPROC_RMDIR,
2082 		NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen));
2083 	nfsm_fhtom(dvp, v3);
2084 	nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
2085 	nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_td, cnp->cn_cred);
2086 	if (v3)
2087 		nfsm_wcc_data(dvp, wccflag);
2088 	m_freem(mrep);
2089 nfsmout:
2090 	VTONFS(dvp)->n_flag |= NLMODIFIED;
2091 	if (!wccflag)
2092 		VTONFS(dvp)->n_attrstamp = 0;
2093 	/*
2094 	 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
2095 	 */
2096 	if (error == ENOENT)
2097 		error = 0;
2098 	return (error);
2099 }
2100 
2101 /*
2102  * nfs readdir call
2103  *
2104  * nfs_readdir(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred)
2105  */
2106 static int
2107 nfs_readdir(struct vop_readdir_args *ap)
2108 {
2109 	struct vnode *vp = ap->a_vp;
2110 	struct nfsnode *np = VTONFS(vp);
2111 	struct uio *uio = ap->a_uio;
2112 	int tresid, error;
2113 	struct vattr vattr;
2114 
2115 	if (vp->v_type != VDIR)
2116 		return (EPERM);
2117 
2118 	/*
2119 	 * If we have a valid EOF offset cache we must call VOP_GETATTR()
2120 	 * and then check that is still valid, or if this is an NQNFS mount
2121 	 * we call NQNFS_CKCACHEABLE() instead of VOP_GETATTR().  Note that
2122 	 * VOP_GETATTR() does not necessarily go to the wire.
2123 	 */
2124 	if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset &&
2125 	    (np->n_flag & (NLMODIFIED|NRMODIFIED)) == 0) {
2126 		if (VOP_GETATTR(vp, &vattr, uio->uio_td) == 0 &&
2127 		    (np->n_flag & (NLMODIFIED|NRMODIFIED)) == 0
2128 		) {
2129 			nfsstats.direofcache_hits++;
2130 			return (0);
2131 		}
2132 	}
2133 
2134 	/*
2135 	 * Call nfs_bioread() to do the real work.  nfs_bioread() does its
2136 	 * own cache coherency checks so we do not have to.
2137 	 */
2138 	tresid = uio->uio_resid;
2139 	error = nfs_bioread(vp, uio, 0);
2140 
2141 	if (!error && uio->uio_resid == tresid)
2142 		nfsstats.direofcache_misses++;
2143 	return (error);
2144 }
2145 
2146 /*
2147  * Readdir rpc call.  nfs_bioread->nfs_doio->nfs_readdirrpc.
2148  *
2149  * Note that for directories, nfs_bioread maintains the underlying nfs-centric
2150  * offset/block and converts the nfs formatted directory entries for userland
2151  * consumption as well as deals with offsets into the middle of blocks.
2152  * nfs_doio only deals with logical blocks.  In particular, uio_offset will
2153  * be block-bounded.  It must convert to cookies for the actual RPC.
2154  */
2155 int
2156 nfs_readdirrpc(struct vnode *vp, struct uio *uiop)
2157 {
2158 	int len, left;
2159 	struct nfs_dirent *dp = NULL;
2160 	u_int32_t *tl;
2161 	caddr_t cp;
2162 	int32_t t1, t2;
2163 	nfsuint64 *cookiep;
2164 	caddr_t bpos, dpos, cp2;
2165 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
2166 	nfsuint64 cookie;
2167 	struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2168 	struct nfsnode *dnp = VTONFS(vp);
2169 	u_quad_t fileno;
2170 	int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1;
2171 	int attrflag;
2172 	int v3 = NFS_ISV3(vp);
2173 
2174 #ifndef DIAGNOSTIC
2175 	if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) ||
2176 		(uiop->uio_resid & (DIRBLKSIZ - 1)))
2177 		panic("nfs readdirrpc bad uio");
2178 #endif
2179 
2180 	/*
2181 	 * If there is no cookie, assume directory was stale.
2182 	 */
2183 	cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0);
2184 	if (cookiep)
2185 		cookie = *cookiep;
2186 	else
2187 		return (NFSERR_BAD_COOKIE);
2188 	/*
2189 	 * Loop around doing readdir rpc's of size nm_readdirsize
2190 	 * truncated to a multiple of DIRBLKSIZ.
2191 	 * The stopping criteria is EOF or buffer full.
2192 	 */
2193 	while (more_dirs && bigenough) {
2194 		nfsstats.rpccnt[NFSPROC_READDIR]++;
2195 		nfsm_reqhead(vp, NFSPROC_READDIR, NFSX_FH(v3) +
2196 			NFSX_READDIR(v3));
2197 		nfsm_fhtom(vp, v3);
2198 		if (v3) {
2199 			nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
2200 			*tl++ = cookie.nfsuquad[0];
2201 			*tl++ = cookie.nfsuquad[1];
2202 			*tl++ = dnp->n_cookieverf.nfsuquad[0];
2203 			*tl++ = dnp->n_cookieverf.nfsuquad[1];
2204 		} else {
2205 			nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
2206 			*tl++ = cookie.nfsuquad[0];
2207 		}
2208 		*tl = txdr_unsigned(nmp->nm_readdirsize);
2209 		nfsm_request(vp, NFSPROC_READDIR, uiop->uio_td, nfs_vpcred(vp, ND_READ));
2210 		if (v3) {
2211 			nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK);
2212 			if (!error) {
2213 				nfsm_dissect(tl, u_int32_t *,
2214 				    2 * NFSX_UNSIGNED);
2215 				dnp->n_cookieverf.nfsuquad[0] = *tl++;
2216 				dnp->n_cookieverf.nfsuquad[1] = *tl;
2217 			} else {
2218 				m_freem(mrep);
2219 				goto nfsmout;
2220 			}
2221 		}
2222 		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2223 		more_dirs = fxdr_unsigned(int, *tl);
2224 
2225 		/* loop thru the dir entries, converting them to std form */
2226 		while (more_dirs && bigenough) {
2227 			if (v3) {
2228 				nfsm_dissect(tl, u_int32_t *,
2229 				    3 * NFSX_UNSIGNED);
2230 				fileno = fxdr_hyper(tl);
2231 				len = fxdr_unsigned(int, *(tl + 2));
2232 			} else {
2233 				nfsm_dissect(tl, u_int32_t *,
2234 				    2 * NFSX_UNSIGNED);
2235 				fileno = fxdr_unsigned(u_quad_t, *tl++);
2236 				len = fxdr_unsigned(int, *tl);
2237 			}
2238 			if (len <= 0 || len > NFS_MAXNAMLEN) {
2239 				error = EBADRPC;
2240 				m_freem(mrep);
2241 				goto nfsmout;
2242 			}
2243 
2244 			/*
2245 			 * len is the number of bytes in the path element
2246 			 * name, not including the \0 termination.
2247 			 *
2248 			 * tlen is the number of bytes w have to reserve for
2249 			 * the path element name.
2250 			 */
2251 			tlen = nfsm_rndup(len);
2252 			if (tlen == len)
2253 				tlen += 4;	/* To ensure null termination */
2254 
2255 			/*
2256 			 * If the entry would cross a DIRBLKSIZ boundary,
2257 			 * extend the previous nfs_dirent to cover the
2258 			 * remaining space.
2259 			 */
2260 			left = DIRBLKSIZ - blksiz;
2261 			if ((tlen + sizeof(struct nfs_dirent)) > left) {
2262 				dp->nfs_reclen += left;
2263 				uiop->uio_iov->iov_base += left;
2264 				uiop->uio_iov->iov_len -= left;
2265 				uiop->uio_offset += left;
2266 				uiop->uio_resid -= left;
2267 				blksiz = 0;
2268 			}
2269 			if ((tlen + sizeof(struct nfs_dirent)) > uiop->uio_resid)
2270 				bigenough = 0;
2271 			if (bigenough) {
2272 				dp = (struct nfs_dirent *)uiop->uio_iov->iov_base;
2273 				dp->nfs_ino = fileno;
2274 				dp->nfs_namlen = len;
2275 				dp->nfs_reclen = tlen + sizeof(struct nfs_dirent);
2276 				dp->nfs_type = DT_UNKNOWN;
2277 				blksiz += dp->nfs_reclen;
2278 				if (blksiz == DIRBLKSIZ)
2279 					blksiz = 0;
2280 				uiop->uio_offset += sizeof(struct nfs_dirent);
2281 				uiop->uio_resid -= sizeof(struct nfs_dirent);
2282 				uiop->uio_iov->iov_base += sizeof(struct nfs_dirent);
2283 				uiop->uio_iov->iov_len -= sizeof(struct nfs_dirent);
2284 				nfsm_mtouio(uiop, len);
2285 
2286 				/*
2287 				 * The uiop has advanced by nfs_dirent + len
2288 				 * but really needs to advance by
2289 				 * nfs_dirent + tlen
2290 				 */
2291 				cp = uiop->uio_iov->iov_base;
2292 				tlen -= len;
2293 				*cp = '\0';	/* null terminate */
2294 				uiop->uio_iov->iov_base += tlen;
2295 				uiop->uio_iov->iov_len -= tlen;
2296 				uiop->uio_offset += tlen;
2297 				uiop->uio_resid -= tlen;
2298 			} else {
2299 				/*
2300 				 * NFS strings must be rounded up (nfsm_myouio
2301 				 * handled that in the bigenough case).
2302 				 */
2303 				nfsm_adv(nfsm_rndup(len));
2304 			}
2305 			if (v3) {
2306 				nfsm_dissect(tl, u_int32_t *,
2307 				    3 * NFSX_UNSIGNED);
2308 			} else {
2309 				nfsm_dissect(tl, u_int32_t *,
2310 				    2 * NFSX_UNSIGNED);
2311 			}
2312 
2313 			/*
2314 			 * If we were able to accomodate the last entry,
2315 			 * get the cookie for the next one.  Otherwise
2316 			 * hold-over the cookie for the one we were not
2317 			 * able to accomodate.
2318 			 */
2319 			if (bigenough) {
2320 				cookie.nfsuquad[0] = *tl++;
2321 				if (v3)
2322 					cookie.nfsuquad[1] = *tl++;
2323 			} else if (v3) {
2324 				tl += 2;
2325 			} else {
2326 				tl++;
2327 			}
2328 			more_dirs = fxdr_unsigned(int, *tl);
2329 		}
2330 		/*
2331 		 * If at end of rpc data, get the eof boolean
2332 		 */
2333 		if (!more_dirs) {
2334 			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2335 			more_dirs = (fxdr_unsigned(int, *tl) == 0);
2336 		}
2337 		m_freem(mrep);
2338 	}
2339 	/*
2340 	 * Fill last record, iff any, out to a multiple of DIRBLKSIZ
2341 	 * by increasing d_reclen for the last record.
2342 	 */
2343 	if (blksiz > 0) {
2344 		left = DIRBLKSIZ - blksiz;
2345 		dp->nfs_reclen += left;
2346 		uiop->uio_iov->iov_base += left;
2347 		uiop->uio_iov->iov_len -= left;
2348 		uiop->uio_offset += left;
2349 		uiop->uio_resid -= left;
2350 	}
2351 
2352 	if (bigenough) {
2353 		/*
2354 		 * We hit the end of the directory, update direofoffset.
2355 		 */
2356 		dnp->n_direofoffset = uiop->uio_offset;
2357 	} else {
2358 		/*
2359 		 * There is more to go, insert the link cookie so the
2360 		 * next block can be read.
2361 		 */
2362 		if (uiop->uio_resid > 0)
2363 			printf("EEK! readdirrpc resid > 0\n");
2364 		cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1);
2365 		*cookiep = cookie;
2366 	}
2367 nfsmout:
2368 	return (error);
2369 }
2370 
2371 /*
2372  * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc().
2373  */
2374 int
2375 nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop)
2376 {
2377 	int len, left;
2378 	struct nfs_dirent *dp;
2379 	u_int32_t *tl;
2380 	caddr_t cp;
2381 	int32_t t1, t2;
2382 	struct vnode *newvp;
2383 	nfsuint64 *cookiep;
2384 	caddr_t bpos, dpos, cp2, dpossav1, dpossav2;
2385 	struct mbuf *mreq, *mrep, *md, *mb, *mb2, *mdsav1, *mdsav2;
2386 	nfsuint64 cookie;
2387 	struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2388 	struct nfsnode *dnp = VTONFS(vp), *np;
2389 	nfsfh_t *fhp;
2390 	u_quad_t fileno;
2391 	int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i;
2392 	int attrflag, fhsize;
2393 	struct namecache *ncp;
2394 	struct namecache *dncp;
2395 	struct nlcomponent nlc;
2396 
2397 #ifndef nolint
2398 	dp = NULL;
2399 #endif
2400 #ifndef DIAGNOSTIC
2401 	if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) ||
2402 		(uiop->uio_resid & (DIRBLKSIZ - 1)))
2403 		panic("nfs readdirplusrpc bad uio");
2404 #endif
2405 	/*
2406 	 * Obtain the namecache record for the directory so we have something
2407 	 * to use as a basis for creating the entries.  This function will
2408 	 * return a held (but not locked) ncp.  The ncp may be disconnected
2409 	 * from the tree and cannot be used for upward traversals, and the
2410 	 * ncp may be unnamed.  Note that other unrelated operations may
2411 	 * cause the ncp to be named at any time.
2412 	 */
2413 	dncp = cache_fromdvp(vp, NULL, 0);
2414 	bzero(&nlc, sizeof(nlc));
2415 	newvp = NULLVP;
2416 
2417 	/*
2418 	 * If there is no cookie, assume directory was stale.
2419 	 */
2420 	cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0);
2421 	if (cookiep)
2422 		cookie = *cookiep;
2423 	else
2424 		return (NFSERR_BAD_COOKIE);
2425 	/*
2426 	 * Loop around doing readdir rpc's of size nm_readdirsize
2427 	 * truncated to a multiple of DIRBLKSIZ.
2428 	 * The stopping criteria is EOF or buffer full.
2429 	 */
2430 	while (more_dirs && bigenough) {
2431 		nfsstats.rpccnt[NFSPROC_READDIRPLUS]++;
2432 		nfsm_reqhead(vp, NFSPROC_READDIRPLUS,
2433 			NFSX_FH(1) + 6 * NFSX_UNSIGNED);
2434 		nfsm_fhtom(vp, 1);
2435  		nfsm_build(tl, u_int32_t *, 6 * NFSX_UNSIGNED);
2436 		*tl++ = cookie.nfsuquad[0];
2437 		*tl++ = cookie.nfsuquad[1];
2438 		*tl++ = dnp->n_cookieverf.nfsuquad[0];
2439 		*tl++ = dnp->n_cookieverf.nfsuquad[1];
2440 		*tl++ = txdr_unsigned(nmp->nm_readdirsize);
2441 		*tl = txdr_unsigned(nmp->nm_rsize);
2442 		nfsm_request(vp, NFSPROC_READDIRPLUS, uiop->uio_td, nfs_vpcred(vp, ND_READ));
2443 		nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK);
2444 		if (error) {
2445 			m_freem(mrep);
2446 			goto nfsmout;
2447 		}
2448 		nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
2449 		dnp->n_cookieverf.nfsuquad[0] = *tl++;
2450 		dnp->n_cookieverf.nfsuquad[1] = *tl++;
2451 		more_dirs = fxdr_unsigned(int, *tl);
2452 
2453 		/* loop thru the dir entries, doctoring them to 4bsd form */
2454 		while (more_dirs && bigenough) {
2455 			nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
2456 			fileno = fxdr_hyper(tl);
2457 			len = fxdr_unsigned(int, *(tl + 2));
2458 			if (len <= 0 || len > NFS_MAXNAMLEN) {
2459 				error = EBADRPC;
2460 				m_freem(mrep);
2461 				goto nfsmout;
2462 			}
2463 			tlen = nfsm_rndup(len);
2464 			if (tlen == len)
2465 				tlen += 4;	/* To ensure null termination*/
2466 			left = DIRBLKSIZ - blksiz;
2467 			if ((tlen + sizeof(struct nfs_dirent)) > left) {
2468 				dp->nfs_reclen += left;
2469 				uiop->uio_iov->iov_base += left;
2470 				uiop->uio_iov->iov_len -= left;
2471 				uiop->uio_offset += left;
2472 				uiop->uio_resid -= left;
2473 				blksiz = 0;
2474 			}
2475 			if ((tlen + sizeof(struct nfs_dirent)) > uiop->uio_resid)
2476 				bigenough = 0;
2477 			if (bigenough) {
2478 				dp = (struct nfs_dirent *)uiop->uio_iov->iov_base;
2479 				dp->nfs_ino = fileno;
2480 				dp->nfs_namlen = len;
2481 				dp->nfs_reclen = tlen + sizeof(struct nfs_dirent);
2482 				dp->nfs_type = DT_UNKNOWN;
2483 				blksiz += dp->nfs_reclen;
2484 				if (blksiz == DIRBLKSIZ)
2485 					blksiz = 0;
2486 				uiop->uio_offset += sizeof(struct nfs_dirent);
2487 				uiop->uio_resid -= sizeof(struct nfs_dirent);
2488 				uiop->uio_iov->iov_base += sizeof(struct nfs_dirent);
2489 				uiop->uio_iov->iov_len -= sizeof(struct nfs_dirent);
2490 				nlc.nlc_nameptr = uiop->uio_iov->iov_base;
2491 				nlc.nlc_namelen = len;
2492 				nfsm_mtouio(uiop, len);
2493 				cp = uiop->uio_iov->iov_base;
2494 				tlen -= len;
2495 				*cp = '\0';
2496 				uiop->uio_iov->iov_base += tlen;
2497 				uiop->uio_iov->iov_len -= tlen;
2498 				uiop->uio_offset += tlen;
2499 				uiop->uio_resid -= tlen;
2500 			} else
2501 				nfsm_adv(nfsm_rndup(len));
2502 			nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
2503 			if (bigenough) {
2504 				cookie.nfsuquad[0] = *tl++;
2505 				cookie.nfsuquad[1] = *tl++;
2506 			} else
2507 				tl += 2;
2508 
2509 			/*
2510 			 * Since the attributes are before the file handle
2511 			 * (sigh), we must skip over the attributes and then
2512 			 * come back and get them.
2513 			 */
2514 			attrflag = fxdr_unsigned(int, *tl);
2515 			if (attrflag) {
2516 			    dpossav1 = dpos;
2517 			    mdsav1 = md;
2518 			    nfsm_adv(NFSX_V3FATTR);
2519 			    nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2520 			    doit = fxdr_unsigned(int, *tl);
2521 			    if (doit) {
2522 				nfsm_getfh(fhp, fhsize, 1);
2523 				if (NFS_CMPFH(dnp, fhp, fhsize)) {
2524 				    vref(vp);
2525 				    newvp = vp;
2526 				    np = dnp;
2527 				} else {
2528 				    error = nfs_nget(vp->v_mount, fhp,
2529 					fhsize, &np);
2530 				    if (error)
2531 					doit = 0;
2532 				    else
2533 					newvp = NFSTOV(np);
2534 				}
2535 			    }
2536 			    if (doit && bigenough) {
2537 				dpossav2 = dpos;
2538 				dpos = dpossav1;
2539 				mdsav2 = md;
2540 				md = mdsav1;
2541 				nfsm_loadattr(newvp, (struct vattr *)0);
2542 				dpos = dpossav2;
2543 				md = mdsav2;
2544 				dp->nfs_type =
2545 				    IFTODT(VTTOIF(np->n_vattr.va_type));
2546 				if (dncp) {
2547 				    printf("NFS/READDIRPLUS, ENTER %*.*s\n",
2548 					nlc.nlc_namelen, nlc.nlc_namelen,
2549 					nlc.nlc_nameptr);
2550 				    ncp = cache_nlookup(dncp, &nlc);
2551 				    cache_setunresolved(ncp);
2552 				    cache_setvp(ncp, newvp);
2553 				    cache_put(ncp);
2554 				} else {
2555 				    printf("NFS/READDIRPLUS, UNABLE TO ENTER"
2556 					" %*.*s\n",
2557 					nlc.nlc_namelen, nlc.nlc_namelen,
2558 					nlc.nlc_nameptr);
2559 				}
2560 			    }
2561 			} else {
2562 			    /* Just skip over the file handle */
2563 			    nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2564 			    i = fxdr_unsigned(int, *tl);
2565 			    nfsm_adv(nfsm_rndup(i));
2566 			}
2567 			if (newvp != NULLVP) {
2568 			    if (newvp == vp)
2569 				vrele(newvp);
2570 			    else
2571 				vput(newvp);
2572 			    newvp = NULLVP;
2573 			}
2574 			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2575 			more_dirs = fxdr_unsigned(int, *tl);
2576 		}
2577 		/*
2578 		 * If at end of rpc data, get the eof boolean
2579 		 */
2580 		if (!more_dirs) {
2581 			nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
2582 			more_dirs = (fxdr_unsigned(int, *tl) == 0);
2583 		}
2584 		m_freem(mrep);
2585 	}
2586 	/*
2587 	 * Fill last record, iff any, out to a multiple of DIRBLKSIZ
2588 	 * by increasing d_reclen for the last record.
2589 	 */
2590 	if (blksiz > 0) {
2591 		left = DIRBLKSIZ - blksiz;
2592 		dp->nfs_reclen += left;
2593 		uiop->uio_iov->iov_base += left;
2594 		uiop->uio_iov->iov_len -= left;
2595 		uiop->uio_offset += left;
2596 		uiop->uio_resid -= left;
2597 	}
2598 
2599 	/*
2600 	 * We are now either at the end of the directory or have filled the
2601 	 * block.
2602 	 */
2603 	if (bigenough)
2604 		dnp->n_direofoffset = uiop->uio_offset;
2605 	else {
2606 		if (uiop->uio_resid > 0)
2607 			printf("EEK! readdirplusrpc resid > 0\n");
2608 		cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1);
2609 		*cookiep = cookie;
2610 	}
2611 nfsmout:
2612 	if (newvp != NULLVP) {
2613 	        if (newvp == vp)
2614 			vrele(newvp);
2615 		else
2616 			vput(newvp);
2617 		newvp = NULLVP;
2618 	}
2619 	if (dncp)
2620 		cache_drop(dncp);
2621 	return (error);
2622 }
2623 
2624 /*
2625  * Silly rename. To make the NFS filesystem that is stateless look a little
2626  * more like the "ufs" a remove of an active vnode is translated to a rename
2627  * to a funny looking filename that is removed by nfs_inactive on the
2628  * nfsnode. There is the potential for another process on a different client
2629  * to create the same funny name between the nfs_lookitup() fails and the
2630  * nfs_rename() completes, but...
2631  */
2632 static int
2633 nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
2634 {
2635 	struct sillyrename *sp;
2636 	struct nfsnode *np;
2637 	int error;
2638 
2639 	/*
2640 	 * We previously purged dvp instead of vp.  I don't know why, it
2641 	 * completely destroys performance.  We can't do it anyway with the
2642 	 * new VFS API since we would be breaking the namecache topology.
2643 	 */
2644 	cache_purge(vp);	/* XXX */
2645 	np = VTONFS(vp);
2646 #ifndef DIAGNOSTIC
2647 	if (vp->v_type == VDIR)
2648 		panic("nfs: sillyrename dir");
2649 #endif
2650 	MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename),
2651 		M_NFSREQ, M_WAITOK);
2652 	sp->s_cred = crdup(cnp->cn_cred);
2653 	sp->s_dvp = dvp;
2654 	vref(dvp);
2655 
2656 	/* Fudge together a funny name */
2657 	sp->s_namlen = sprintf(sp->s_name, ".nfsA%08x4.4", (int)cnp->cn_td);
2658 
2659 	/* Try lookitups until we get one that isn't there */
2660 	while (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
2661 		cnp->cn_td, (struct nfsnode **)0) == 0) {
2662 		sp->s_name[4]++;
2663 		if (sp->s_name[4] > 'z') {
2664 			error = EINVAL;
2665 			goto bad;
2666 		}
2667 	}
2668 	error = nfs_renameit(dvp, cnp, sp);
2669 	if (error)
2670 		goto bad;
2671 	error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
2672 		cnp->cn_td, &np);
2673 	np->n_sillyrename = sp;
2674 	return (0);
2675 bad:
2676 	vrele(sp->s_dvp);
2677 	crfree(sp->s_cred);
2678 	free((caddr_t)sp, M_NFSREQ);
2679 	return (error);
2680 }
2681 
2682 /*
2683  * Look up a file name and optionally either update the file handle or
2684  * allocate an nfsnode, depending on the value of npp.
2685  * npp == NULL	--> just do the lookup
2686  * *npp == NULL --> allocate a new nfsnode and make sure attributes are
2687  *			handled too
2688  * *npp != NULL --> update the file handle in the vnode
2689  */
2690 static int
2691 nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred,
2692 	     struct thread *td, struct nfsnode **npp)
2693 {
2694 	u_int32_t *tl;
2695 	caddr_t cp;
2696 	int32_t t1, t2;
2697 	struct vnode *newvp = (struct vnode *)0;
2698 	struct nfsnode *np, *dnp = VTONFS(dvp);
2699 	caddr_t bpos, dpos, cp2;
2700 	int error = 0, fhlen, attrflag;
2701 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
2702 	nfsfh_t *nfhp;
2703 	int v3 = NFS_ISV3(dvp);
2704 
2705 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
2706 	nfsm_reqhead(dvp, NFSPROC_LOOKUP,
2707 		NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len));
2708 	nfsm_fhtom(dvp, v3);
2709 	nfsm_strtom(name, len, NFS_MAXNAMLEN);
2710 	nfsm_request(dvp, NFSPROC_LOOKUP, td, cred);
2711 	if (npp && !error) {
2712 		nfsm_getfh(nfhp, fhlen, v3);
2713 		if (*npp) {
2714 		    np = *npp;
2715 		    if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) {
2716 			free((caddr_t)np->n_fhp, M_NFSBIGFH);
2717 			np->n_fhp = &np->n_fh;
2718 		    } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH)
2719 			np->n_fhp =(nfsfh_t *)malloc(fhlen,M_NFSBIGFH,M_WAITOK);
2720 		    bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen);
2721 		    np->n_fhsize = fhlen;
2722 		    newvp = NFSTOV(np);
2723 		} else if (NFS_CMPFH(dnp, nfhp, fhlen)) {
2724 		    vref(dvp);
2725 		    newvp = dvp;
2726 		} else {
2727 		    error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np);
2728 		    if (error) {
2729 			m_freem(mrep);
2730 			return (error);
2731 		    }
2732 		    newvp = NFSTOV(np);
2733 		}
2734 		if (v3) {
2735 			nfsm_postop_attr(newvp, attrflag, NFS_LATTR_NOSHRINK);
2736 			if (!attrflag && *npp == NULL) {
2737 				m_freem(mrep);
2738 				if (newvp == dvp)
2739 					vrele(newvp);
2740 				else
2741 					vput(newvp);
2742 				return (ENOENT);
2743 			}
2744 		} else
2745 			nfsm_loadattr(newvp, (struct vattr *)0);
2746 	}
2747 	m_freem(mrep);
2748 nfsmout:
2749 	if (npp && *npp == NULL) {
2750 		if (error) {
2751 			if (newvp) {
2752 				if (newvp == dvp)
2753 					vrele(newvp);
2754 				else
2755 					vput(newvp);
2756 			}
2757 		} else
2758 			*npp = np;
2759 	}
2760 	return (error);
2761 }
2762 
2763 /*
2764  * Nfs Version 3 commit rpc
2765  */
2766 int
2767 nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct thread *td)
2768 {
2769 	caddr_t cp;
2770 	u_int32_t *tl;
2771 	int32_t t1, t2;
2772 	struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2773 	caddr_t bpos, dpos, cp2;
2774 	int error = 0, wccflag = NFSV3_WCCRATTR;
2775 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
2776 
2777 	if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0)
2778 		return (0);
2779 	nfsstats.rpccnt[NFSPROC_COMMIT]++;
2780 	nfsm_reqhead(vp, NFSPROC_COMMIT, NFSX_FH(1));
2781 	nfsm_fhtom(vp, 1);
2782 	nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
2783 	txdr_hyper(offset, tl);
2784 	tl += 2;
2785 	*tl = txdr_unsigned(cnt);
2786 	nfsm_request(vp, NFSPROC_COMMIT, td, nfs_vpcred(vp, ND_WRITE));
2787 	nfsm_wcc_data(vp, wccflag);
2788 	if (!error) {
2789 		nfsm_dissect(tl, u_int32_t *, NFSX_V3WRITEVERF);
2790 		if (bcmp((caddr_t)nmp->nm_verf, (caddr_t)tl,
2791 			NFSX_V3WRITEVERF)) {
2792 			bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
2793 				NFSX_V3WRITEVERF);
2794 			error = NFSERR_STALEWRITEVERF;
2795 		}
2796 	}
2797 	m_freem(mrep);
2798 nfsmout:
2799 	return (error);
2800 }
2801 
2802 /*
2803  * Kludge City..
2804  * - make nfs_bmap() essentially a no-op that does no translation
2805  * - do nfs_strategy() by doing I/O with nfs_readrpc/nfs_writerpc
2806  *   (Maybe I could use the process's page mapping, but I was concerned that
2807  *    Kernel Write might not be enabled and also figured copyout() would do
2808  *    a lot more work than bcopy() and also it currently happens in the
2809  *    context of the swapper process (2).
2810  *
2811  * nfs_bmap(struct vnode *a_vp, off_t a_loffset, struct vnode **a_vpp,
2812  *	    off_t *a_doffsetp, int *a_runp, int *a_runb)
2813  */
2814 static int
2815 nfs_bmap(struct vop_bmap_args *ap)
2816 {
2817 	struct vnode *vp = ap->a_vp;
2818 
2819 	if (ap->a_vpp != NULL)
2820 		*ap->a_vpp = vp;
2821 	if (ap->a_doffsetp != NULL)
2822 		*ap->a_doffsetp = ap->a_loffset;
2823 	if (ap->a_runp != NULL)
2824 		*ap->a_runp = 0;
2825 	if (ap->a_runb != NULL)
2826 		*ap->a_runb = 0;
2827 	return (0);
2828 }
2829 
2830 /*
2831  * Strategy routine.
2832  *
2833  * For async requests when nfsiod(s) are running, queue the request by
2834  * calling nfs_asyncio(), otherwise just all nfs_doio() to do the
2835  * request.
2836  */
2837 static int
2838 nfs_strategy(struct vop_strategy_args *ap)
2839 {
2840 	struct bio *bio = ap->a_bio;
2841 	struct bio *nbio;
2842 	struct buf *bp = bio->bio_buf;
2843 	struct thread *td;
2844 	int error = 0;
2845 
2846 	KASSERT(!(bp->b_flags & B_DONE),
2847 		("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp));
2848 	KASSERT(BUF_REFCNT(bp) > 0,
2849 		("nfs_strategy: buffer %p not locked", bp));
2850 
2851 	if (bp->b_flags & B_PHYS)
2852 		panic("nfs physio");
2853 
2854 	if (bp->b_flags & B_ASYNC)
2855 		td = NULL;
2856 	else
2857 		td = curthread;	/* XXX */
2858 
2859         /*
2860 	 * We probably don't need to push an nbio any more since no
2861 	 * block conversion is required due to the use of 64 bit byte
2862 	 * offsets, but do it anyway.
2863          */
2864 	nbio = push_bio(bio);
2865 	nbio->bio_offset = bio->bio_offset;
2866 
2867 	/*
2868 	 * If the op is asynchronous and an i/o daemon is waiting
2869 	 * queue the request, wake it up and wait for completion
2870 	 * otherwise just do it ourselves.
2871 	 */
2872 	if ((bp->b_flags & B_ASYNC) == 0 || nfs_asyncio(ap->a_vp, nbio, td))
2873 		error = nfs_doio(ap->a_vp, nbio, td);
2874 	return (error);
2875 }
2876 
2877 /*
2878  * Mmap a file
2879  *
2880  * NB Currently unsupported.
2881  *
2882  * nfs_mmap(struct vnode *a_vp, int a_fflags, struct ucred *a_cred,
2883  *	    struct thread *a_td)
2884  */
2885 /* ARGSUSED */
2886 static int
2887 nfs_mmap(struct vop_mmap_args *ap)
2888 {
2889 	return (EINVAL);
2890 }
2891 
2892 /*
2893  * fsync vnode op. Just call nfs_flush() with commit == 1.
2894  *
2895  * nfs_fsync(struct vnodeop_desc *a_desc, struct vnode *a_vp,
2896  *	     struct ucred * a_cred, int a_waitfor, struct thread *a_td)
2897  */
2898 /* ARGSUSED */
2899 static int
2900 nfs_fsync(struct vop_fsync_args *ap)
2901 {
2902 	return (nfs_flush(ap->a_vp, ap->a_waitfor, ap->a_td, 1));
2903 }
2904 
2905 /*
2906  * Flush all the blocks associated with a vnode.   Dirty NFS buffers may be
2907  * in one of two states:  If B_NEEDCOMMIT is clear then the buffer contains
2908  * new NFS data which needs to be written to the server.  If B_NEEDCOMMIT is
2909  * set the buffer contains data that has already been written to the server
2910  * and which now needs a commit RPC.
2911  *
2912  * If commit is 0 we only take one pass and only flush buffers containing new
2913  * dirty data.
2914  *
2915  * If commit is 1 we take two passes, issuing a commit RPC in the second
2916  * pass.
2917  *
2918  * If waitfor is MNT_WAIT and commit is 1, we loop as many times as required
2919  * to completely flush all pending data.
2920  *
2921  * Note that the RB_SCAN code properly handles the case where the
2922  * callback might block and directly or indirectly (another thread) cause
2923  * the RB tree to change.
2924  */
2925 
2926 #ifndef NFS_COMMITBVECSIZ
2927 #define NFS_COMMITBVECSIZ	16
2928 #endif
2929 
2930 struct nfs_flush_info {
2931 	enum { NFI_FLUSHNEW, NFI_COMMIT } mode;
2932 	struct thread *td;
2933 	struct vnode *vp;
2934 	int waitfor;
2935 	int slpflag;
2936 	int slptimeo;
2937 	int loops;
2938 	struct buf *bvary[NFS_COMMITBVECSIZ];
2939 	int bvsize;
2940 	off_t beg_off;
2941 	off_t end_off;
2942 };
2943 
2944 static int nfs_flush_bp(struct buf *bp, void *data);
2945 static int nfs_flush_docommit(struct nfs_flush_info *info, int error);
2946 
2947 int
2948 nfs_flush(struct vnode *vp, int waitfor, struct thread *td, int commit)
2949 {
2950 	struct nfsnode *np = VTONFS(vp);
2951 	struct nfsmount *nmp = VFSTONFS(vp->v_mount);
2952 	struct nfs_flush_info info;
2953 	int error;
2954 
2955 	bzero(&info, sizeof(info));
2956 	info.td = td;
2957 	info.vp = vp;
2958 	info.waitfor = waitfor;
2959 	info.slpflag = (nmp->nm_flag & NFSMNT_INT) ? PCATCH : 0;
2960 	info.loops = 0;
2961 
2962 	do {
2963 		/*
2964 		 * Flush mode
2965 		 */
2966 		info.mode = NFI_FLUSHNEW;
2967 		error = RB_SCAN(buf_rb_tree, &vp->v_rbdirty_tree, NULL,
2968 				nfs_flush_bp, &info);
2969 
2970 		/*
2971 		 * Take a second pass if committing and no error occured.
2972 		 * Clean up any left over collection (whether an error
2973 		 * occurs or not).
2974 		 */
2975 		if (commit && error == 0) {
2976 			info.mode = NFI_COMMIT;
2977 			error = RB_SCAN(buf_rb_tree, &vp->v_rbdirty_tree, NULL,
2978 					nfs_flush_bp, &info);
2979 			if (info.bvsize)
2980 				error = nfs_flush_docommit(&info, error);
2981 		}
2982 
2983 		/*
2984 		 * Wait for pending I/O to complete before checking whether
2985 		 * any further dirty buffers exist.
2986 		 */
2987 		while (waitfor == MNT_WAIT && vp->v_track_write.bk_active) {
2988 			vp->v_track_write.bk_waitflag = 1;
2989 			error = tsleep(&vp->v_track_write,
2990 				info.slpflag, "nfsfsync", info.slptimeo);
2991 			if (error) {
2992 				/*
2993 				 * We have to be able to break out if this
2994 				 * is an 'intr' mount.
2995 				 */
2996 				if (nfs_sigintr(nmp, (struct nfsreq *)0, td)) {
2997 					error = -EINTR;
2998 					break;
2999 				}
3000 
3001 				/*
3002 				 * Since we do not process pending signals,
3003 				 * once we get a PCATCH our tsleep() will no
3004 				 * longer sleep, switch to a fixed timeout
3005 				 * instead.
3006 				 */
3007 				if (info.slpflag == PCATCH) {
3008 					info.slpflag = 0;
3009 					info.slptimeo = 2 * hz;
3010 				}
3011 				error = 0;
3012 			}
3013 		}
3014 		++info.loops;
3015 		/*
3016 		 * Loop if we are flushing synchronous as well as committing,
3017 		 * and dirty buffers are still present.  Otherwise we might livelock.
3018 		 */
3019 	} while (waitfor == MNT_WAIT && commit &&
3020 		 error == 0 && !RB_EMPTY(&vp->v_rbdirty_tree));
3021 
3022 	/*
3023 	 * The callbacks have to return a negative error to terminate the
3024 	 * RB scan.
3025 	 */
3026 	if (error < 0)
3027 		error = -error;
3028 
3029 	/*
3030 	 * Deal with any error collection
3031 	 */
3032 	if (np->n_flag & NWRITEERR) {
3033 		error = np->n_error;
3034 		np->n_flag &= ~NWRITEERR;
3035 	}
3036 	return (error);
3037 }
3038 
3039 
3040 static
3041 int
3042 nfs_flush_bp(struct buf *bp, void *data)
3043 {
3044 	struct nfs_flush_info *info = data;
3045 	off_t toff;
3046 	int error;
3047 
3048 	error = 0;
3049 	switch(info->mode) {
3050 	case NFI_FLUSHNEW:
3051 		crit_enter();
3052 		if (info->loops && info->waitfor == MNT_WAIT) {
3053 			error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT);
3054 			if (error) {
3055 				int lkflags = LK_EXCLUSIVE | LK_SLEEPFAIL;
3056 				if (info->slpflag & PCATCH)
3057 					lkflags |= LK_PCATCH;
3058 				error = BUF_TIMELOCK(bp, lkflags, "nfsfsync",
3059 						     info->slptimeo);
3060 			}
3061 		} else {
3062 			error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT);
3063 		}
3064 		if (error == 0) {
3065 			KKASSERT(bp->b_vp == info->vp);
3066 
3067 			if ((bp->b_flags & B_DELWRI) == 0)
3068 				panic("nfs_fsync: not dirty");
3069 			if (bp->b_flags & B_NEEDCOMMIT) {
3070 				BUF_UNLOCK(bp);
3071 				crit_exit();
3072 				break;
3073 			}
3074 			bremfree(bp);
3075 
3076 			bp->b_flags |= B_ASYNC;
3077 			crit_exit();
3078 			VOP_BWRITE(bp->b_vp, bp);
3079 		} else {
3080 			crit_exit();
3081 			error = 0;
3082 		}
3083 		break;
3084 	case NFI_COMMIT:
3085 		/*
3086 		 * Only process buffers in need of a commit which we can
3087 		 * immediately lock.  This may prevent a buffer from being
3088 		 * committed, but the normal flush loop will block on the
3089 		 * same buffer so we shouldn't get into an endless loop.
3090 		 */
3091 		crit_enter();
3092 		if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) !=
3093 		    (B_DELWRI | B_NEEDCOMMIT) ||
3094 		    BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) != 0) {
3095 			crit_exit();
3096 			break;
3097 		}
3098 
3099 		KKASSERT(bp->b_vp == info->vp);
3100 		bremfree(bp);
3101 
3102 		/*
3103 		 * NOTE: we are not clearing B_DONE here, so we have
3104 		 * to do it later on in this routine if we intend to
3105 		 * initiate I/O on the bp.
3106 		 *
3107 		 * Note: to avoid loopback deadlocks, we do not
3108 		 * assign b_runningbufspace.
3109 		 */
3110 		vfs_busy_pages(bp, 1);
3111 
3112 		info->bvary[info->bvsize] = bp;
3113 		toff = bp->b_bio2.bio_offset + bp->b_dirtyoff;
3114 		if (info->bvsize == 0 || toff < info->beg_off)
3115 			info->beg_off = toff;
3116 		toff += (off_t)(bp->b_dirtyend - bp->b_dirtyoff);
3117 		if (info->bvsize == 0 || toff > info->end_off)
3118 			info->end_off = toff;
3119 		++info->bvsize;
3120 		if (info->bvsize == NFS_COMMITBVECSIZ) {
3121 			error = nfs_flush_docommit(info, 0);
3122 			KKASSERT(info->bvsize == 0);
3123 		}
3124 		crit_exit();
3125 	}
3126 	return (error);
3127 }
3128 
3129 static
3130 int
3131 nfs_flush_docommit(struct nfs_flush_info *info, int error)
3132 {
3133 	struct vnode *vp;
3134 	struct buf *bp;
3135 	off_t bytes;
3136 	int retv;
3137 	int i;
3138 
3139 	vp = info->vp;
3140 
3141 	if (info->bvsize > 0) {
3142 		/*
3143 		 * Commit data on the server, as required.  Note that
3144 		 * nfs_commit will use the vnode's cred for the commit.
3145 		 * The NFSv3 commit RPC is limited to a 32 bit byte count.
3146 		 */
3147 		bytes = info->end_off - info->beg_off;
3148 		if (bytes > 0x40000000)
3149 			bytes = 0x40000000;
3150 		if (error) {
3151 			retv = -error;
3152 		} else {
3153 			retv = nfs_commit(vp, info->beg_off,
3154 					    (int)bytes, info->td);
3155 			if (retv == NFSERR_STALEWRITEVERF)
3156 				nfs_clearcommit(vp->v_mount);
3157 		}
3158 
3159 		/*
3160 		 * Now, either mark the blocks I/O done or mark the
3161 		 * blocks dirty, depending on whether the commit
3162 		 * succeeded.
3163 		 */
3164 		for (i = 0; i < info->bvsize; ++i) {
3165 			bp = info->bvary[i];
3166 			bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
3167 			if (retv) {
3168 				/*
3169 				 * Error, leave B_DELWRI intact
3170 				 */
3171 				vfs_unbusy_pages(bp);
3172 				brelse(bp);
3173 			} else {
3174 				/*
3175 				 * Success, remove B_DELWRI ( bundirty() ).
3176 				 *
3177 				 * b_dirtyoff/b_dirtyend seem to be NFS
3178 				 * specific.  We should probably move that
3179 				 * into bundirty(). XXX
3180 				 *
3181 				 * We are faking an I/O write, we have to
3182 				 * start the transaction in order to
3183 				 * immediately biodone() it.
3184 				 */
3185 				crit_enter();
3186 				bp->b_flags |= B_ASYNC;
3187 				bundirty(bp);
3188 				bp->b_flags &= ~(B_READ|B_DONE|B_ERROR);
3189 				bp->b_dirtyoff = bp->b_dirtyend = 0;
3190 				crit_exit();
3191 				biodone(&bp->b_bio1);
3192 			}
3193 		}
3194 		info->bvsize = 0;
3195 	}
3196 	return (error);
3197 }
3198 
3199 /*
3200  * NFS advisory byte-level locks.
3201  * Currently unsupported.
3202  *
3203  * nfs_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl,
3204  *		int a_flags)
3205  */
3206 static int
3207 nfs_advlock(struct vop_advlock_args *ap)
3208 {
3209 	struct nfsnode *np = VTONFS(ap->a_vp);
3210 
3211 	/*
3212 	 * The following kludge is to allow diskless support to work
3213 	 * until a real NFS lockd is implemented. Basically, just pretend
3214 	 * that this is a local lock.
3215 	 */
3216 	return (lf_advlock(ap, &(np->n_lockf), np->n_size));
3217 }
3218 
3219 /*
3220  * Print out the contents of an nfsnode.
3221  *
3222  * nfs_print(struct vnode *a_vp)
3223  */
3224 static int
3225 nfs_print(struct vop_print_args *ap)
3226 {
3227 	struct vnode *vp = ap->a_vp;
3228 	struct nfsnode *np = VTONFS(vp);
3229 
3230 	printf("tag VT_NFS, fileid %ld fsid 0x%x",
3231 		np->n_vattr.va_fileid, np->n_vattr.va_fsid);
3232 	if (vp->v_type == VFIFO)
3233 		fifo_printinfo(vp);
3234 	printf("\n");
3235 	return (0);
3236 }
3237 
3238 /*
3239  * Just call nfs_writebp() with the force argument set to 1.
3240  *
3241  * NOTE: B_DONE may or may not be set in a_bp on call.
3242  *
3243  * nfs_bwrite(struct vnode *a_bp)
3244  */
3245 static int
3246 nfs_bwrite(struct vop_bwrite_args *ap)
3247 {
3248 	return (nfs_writebp(ap->a_bp, 1, curthread));
3249 }
3250 
3251 /*
3252  * This is a clone of vn_bwrite(), except that it also handles the
3253  * B_NEEDCOMMIT flag.  We set B_CACHE if this is a VMIO buffer.
3254  */
3255 int
3256 nfs_writebp(struct buf *bp, int force, struct thread *td)
3257 {
3258 	int error;
3259 
3260 	if (BUF_REFCNT(bp) == 0)
3261 		panic("bwrite: buffer is not locked???");
3262 
3263 	if (bp->b_flags & B_INVAL) {
3264 		brelse(bp);
3265 		return(0);
3266 	}
3267 
3268 	bp->b_flags |= B_CACHE;
3269 
3270 	/*
3271 	 * Undirty the bp.  We will redirty it later if the I/O fails.
3272 	 */
3273 	crit_enter();
3274 	bundirty(bp);
3275 	bp->b_flags &= ~(B_READ|B_DONE|B_ERROR);
3276 	crit_exit();
3277 
3278 	/*
3279 	 * Note: to avoid loopback deadlocks, we do not
3280 	 * assign b_runningbufspace.
3281 	 */
3282 	vfs_busy_pages(bp, 1);
3283 	BUF_KERNPROC(bp);
3284 
3285 	if (bp->b_flags & B_ASYNC) {
3286 		vn_strategy(bp->b_vp, &bp->b_bio1);
3287 		error = 0;
3288 	} else {
3289 		vn_strategy(bp->b_vp, &bp->b_bio1);
3290 		error = biowait(bp);
3291 		brelse(bp);
3292 	}
3293 	return (error);
3294 }
3295 
3296 /*
3297  * nfs special file access vnode op.
3298  * Essentially just get vattr and then imitate iaccess() since the device is
3299  * local to the client.
3300  *
3301  * nfsspec_access(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
3302  *		  struct thread *a_td)
3303  */
3304 static int
3305 nfsspec_access(struct vop_access_args *ap)
3306 {
3307 	struct vattr *vap;
3308 	gid_t *gp;
3309 	struct ucred *cred = ap->a_cred;
3310 	struct vnode *vp = ap->a_vp;
3311 	mode_t mode = ap->a_mode;
3312 	struct vattr vattr;
3313 	int i;
3314 	int error;
3315 
3316 	/*
3317 	 * Disallow write attempts on filesystems mounted read-only;
3318 	 * unless the file is a socket, fifo, or a block or character
3319 	 * device resident on the filesystem.
3320 	 */
3321 	if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
3322 		switch (vp->v_type) {
3323 		case VREG:
3324 		case VDIR:
3325 		case VLNK:
3326 			return (EROFS);
3327 		default:
3328 			break;
3329 		}
3330 	}
3331 	/*
3332 	 * If you're the super-user,
3333 	 * you always get access.
3334 	 */
3335 	if (cred->cr_uid == 0)
3336 		return (0);
3337 	vap = &vattr;
3338 	error = VOP_GETATTR(vp, vap, ap->a_td);
3339 	if (error)
3340 		return (error);
3341 	/*
3342 	 * Access check is based on only one of owner, group, public.
3343 	 * If not owner, then check group. If not a member of the
3344 	 * group, then check public access.
3345 	 */
3346 	if (cred->cr_uid != vap->va_uid) {
3347 		mode >>= 3;
3348 		gp = cred->cr_groups;
3349 		for (i = 0; i < cred->cr_ngroups; i++, gp++)
3350 			if (vap->va_gid == *gp)
3351 				goto found;
3352 		mode >>= 3;
3353 found:
3354 		;
3355 	}
3356 	error = (vap->va_mode & mode) == mode ? 0 : EACCES;
3357 	return (error);
3358 }
3359 
3360 /*
3361  * Read wrapper for special devices.
3362  *
3363  * nfsspec_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
3364  *		struct ucred *a_cred)
3365  */
3366 static int
3367 nfsspec_read(struct vop_read_args *ap)
3368 {
3369 	struct nfsnode *np = VTONFS(ap->a_vp);
3370 
3371 	/*
3372 	 * Set access flag.
3373 	 */
3374 	np->n_flag |= NACC;
3375 	getnanotime(&np->n_atim);
3376 	return (VOCALL(spec_vnode_vops, &ap->a_head));
3377 }
3378 
3379 /*
3380  * Write wrapper for special devices.
3381  *
3382  * nfsspec_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
3383  *		 struct ucred *a_cred)
3384  */
3385 static int
3386 nfsspec_write(struct vop_write_args *ap)
3387 {
3388 	struct nfsnode *np = VTONFS(ap->a_vp);
3389 
3390 	/*
3391 	 * Set update flag.
3392 	 */
3393 	np->n_flag |= NUPD;
3394 	getnanotime(&np->n_mtim);
3395 	return (VOCALL(spec_vnode_vops, &ap->a_head));
3396 }
3397 
3398 /*
3399  * Close wrapper for special devices.
3400  *
3401  * Update the times on the nfsnode then do device close.
3402  *
3403  * nfsspec_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred,
3404  *		 struct thread *a_td)
3405  */
3406 static int
3407 nfsspec_close(struct vop_close_args *ap)
3408 {
3409 	struct vnode *vp = ap->a_vp;
3410 	struct nfsnode *np = VTONFS(vp);
3411 	struct vattr vattr;
3412 
3413 	if (np->n_flag & (NACC | NUPD)) {
3414 		np->n_flag |= NCHG;
3415 		if (vp->v_usecount == 1 &&
3416 		    (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
3417 			VATTR_NULL(&vattr);
3418 			if (np->n_flag & NACC)
3419 				vattr.va_atime = np->n_atim;
3420 			if (np->n_flag & NUPD)
3421 				vattr.va_mtime = np->n_mtim;
3422 			(void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE), ap->a_td);
3423 		}
3424 	}
3425 	return (VOCALL(spec_vnode_vops, &ap->a_head));
3426 }
3427 
3428 /*
3429  * Read wrapper for fifos.
3430  *
3431  * nfsfifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
3432  *		struct ucred *a_cred)
3433  */
3434 static int
3435 nfsfifo_read(struct vop_read_args *ap)
3436 {
3437 	struct nfsnode *np = VTONFS(ap->a_vp);
3438 
3439 	/*
3440 	 * Set access flag.
3441 	 */
3442 	np->n_flag |= NACC;
3443 	getnanotime(&np->n_atim);
3444 	return (VOCALL(fifo_vnode_vops, &ap->a_head));
3445 }
3446 
3447 /*
3448  * Write wrapper for fifos.
3449  *
3450  * nfsfifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
3451  *		 struct ucred *a_cred)
3452  */
3453 static int
3454 nfsfifo_write(struct vop_write_args *ap)
3455 {
3456 	struct nfsnode *np = VTONFS(ap->a_vp);
3457 
3458 	/*
3459 	 * Set update flag.
3460 	 */
3461 	np->n_flag |= NUPD;
3462 	getnanotime(&np->n_mtim);
3463 	return (VOCALL(fifo_vnode_vops, &ap->a_head));
3464 }
3465 
3466 /*
3467  * Close wrapper for fifos.
3468  *
3469  * Update the times on the nfsnode then do fifo close.
3470  *
3471  * nfsfifo_close(struct vnode *a_vp, int a_fflag, struct thread *a_td)
3472  */
3473 static int
3474 nfsfifo_close(struct vop_close_args *ap)
3475 {
3476 	struct vnode *vp = ap->a_vp;
3477 	struct nfsnode *np = VTONFS(vp);
3478 	struct vattr vattr;
3479 	struct timespec ts;
3480 
3481 	if (np->n_flag & (NACC | NUPD)) {
3482 		getnanotime(&ts);
3483 		if (np->n_flag & NACC)
3484 			np->n_atim = ts;
3485 		if (np->n_flag & NUPD)
3486 			np->n_mtim = ts;
3487 		np->n_flag |= NCHG;
3488 		if (vp->v_usecount == 1 &&
3489 		    (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
3490 			VATTR_NULL(&vattr);
3491 			if (np->n_flag & NACC)
3492 				vattr.va_atime = np->n_atim;
3493 			if (np->n_flag & NUPD)
3494 				vattr.va_mtime = np->n_mtim;
3495 			(void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE), ap->a_td);
3496 		}
3497 	}
3498 	return (VOCALL(fifo_vnode_vops, &ap->a_head));
3499 }
3500 
3501