xref: /csrg-svn/sys/nfs/nfs_vnops.c (revision 53805)
1 /*
2  * Copyright (c) 1989 The Regents of the University of California.
3  * 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  * %sccs.include.redist.c%
9  *
10  *	@(#)nfs_vnops.c	7.79 (Berkeley) 06/02/92
11  */
12 
13 /*
14  * vnode op calls for sun nfs version 2
15  */
16 
17 #include <sys/param.h>
18 #include <sys/proc.h>
19 #include <sys/kernel.h>
20 #include <sys/systm.h>
21 #include <sys/mount.h>
22 #include <sys/buf.h>
23 #include <sys/malloc.h>
24 #include <sys/mbuf.h>
25 #include <sys/conf.h>
26 #include <sys/namei.h>
27 #include <sys/vnode.h>
28 #include <sys/specdev.h>
29 #include <sys/fifo.h>
30 #include <sys/map.h>
31 
32 #include <vm/vm.h>
33 
34 #include <nfs/rpcv2.h>
35 #include <nfs/nfsv2.h>
36 #include <nfs/nfs.h>
37 #include <nfs/nfsnode.h>
38 #include <nfs/nfsmount.h>
39 #include <nfs/xdr_subs.h>
40 #include <nfs/nfsm_subs.h>
41 #include <nfs/nqnfs.h>
42 
43 /* Defs */
44 #define	TRUE	1
45 #define	FALSE	0
46 
47 /*
48  * Global vfs data structures for nfs
49  */
50 int (**nfsv2_vnodeop_p)();
51 struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = {
52 	{ &vop_default_desc, vn_default_error },
53 	{ &vop_lookup_desc, nfs_lookup },		/* lookup */
54 	{ &vop_create_desc, nfs_create },		/* create */
55 	{ &vop_mknod_desc, nfs_mknod },		/* mknod */
56 	{ &vop_open_desc, nfs_open },		/* open */
57 	{ &vop_close_desc, nfs_close },		/* close */
58 	{ &vop_access_desc, nfs_access },		/* access */
59 	{ &vop_getattr_desc, nfs_getattr },		/* getattr */
60 	{ &vop_setattr_desc, nfs_setattr },		/* setattr */
61 	{ &vop_read_desc, nfs_read },		/* read */
62 	{ &vop_write_desc, nfs_write },		/* write */
63 	{ &vop_ioctl_desc, nfs_ioctl },		/* ioctl */
64 	{ &vop_select_desc, nfs_select },		/* select */
65 	{ &vop_mmap_desc, nfs_mmap },		/* mmap */
66 	{ &vop_fsync_desc, nfs_fsync },		/* fsync */
67 	{ &vop_seek_desc, nfs_seek },		/* seek */
68 	{ &vop_remove_desc, nfs_remove },		/* remove */
69 	{ &vop_link_desc, nfs_link },		/* link */
70 	{ &vop_rename_desc, nfs_rename },		/* rename */
71 	{ &vop_mkdir_desc, nfs_mkdir },		/* mkdir */
72 	{ &vop_rmdir_desc, nfs_rmdir },		/* rmdir */
73 	{ &vop_symlink_desc, nfs_symlink },		/* symlink */
74 	{ &vop_readdir_desc, nfs_readdir },		/* readdir */
75 	{ &vop_readlink_desc, nfs_readlink },		/* readlink */
76 	{ &vop_abortop_desc, nfs_abortop },		/* abortop */
77 	{ &vop_inactive_desc, nfs_inactive },		/* inactive */
78 	{ &vop_reclaim_desc, nfs_reclaim },		/* reclaim */
79 	{ &vop_lock_desc, nfs_lock },		/* lock */
80 	{ &vop_unlock_desc, nfs_unlock },		/* unlock */
81 	{ &vop_bmap_desc, nfs_bmap },		/* bmap */
82 	{ &vop_strategy_desc, nfs_strategy },		/* strategy */
83 	{ &vop_print_desc, nfs_print },		/* print */
84 	{ &vop_islocked_desc, nfs_islocked },		/* islocked */
85 	{ &vop_advlock_desc, nfs_advlock },		/* advlock */
86 	{ &vop_blkatoff_desc, nfs_blkatoff },		/* blkatoff */
87 	{ &vop_vget_desc, nfs_vget },		/* vget */
88 	{ &vop_valloc_desc, nfs_valloc },		/* valloc */
89 	{ &vop_vfree_desc, nfs_vfree },		/* vfree */
90 	{ &vop_truncate_desc, nfs_truncate },		/* truncate */
91 	{ &vop_update_desc, nfs_update },		/* update */
92 	{ &vop_bwrite_desc, vn_bwrite },
93 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
94 };
95 struct vnodeopv_desc nfsv2_vnodeop_opv_desc =
96 	{ &nfsv2_vnodeop_p, nfsv2_vnodeop_entries };
97 
98 /*
99  * Special device vnode ops
100  */
101 int (**spec_nfsv2nodeop_p)();
102 struct vnodeopv_entry_desc spec_nfsv2nodeop_entries[] = {
103 	{ &vop_default_desc, vn_default_error },
104 	{ &vop_lookup_desc, spec_lookup },		/* lookup */
105 	{ &vop_create_desc, spec_create },		/* create */
106 	{ &vop_mknod_desc, spec_mknod },		/* mknod */
107 	{ &vop_open_desc, spec_open },		/* open */
108 	{ &vop_close_desc, nfsspec_close },		/* close */
109 	{ &vop_access_desc, nfs_access },		/* access */
110 	{ &vop_getattr_desc, nfs_getattr },		/* getattr */
111 	{ &vop_setattr_desc, nfs_setattr },		/* setattr */
112 	{ &vop_read_desc, nfsspec_read },		/* read */
113 	{ &vop_write_desc, nfsspec_write },		/* write */
114 	{ &vop_ioctl_desc, spec_ioctl },		/* ioctl */
115 	{ &vop_select_desc, spec_select },		/* select */
116 	{ &vop_mmap_desc, spec_mmap },		/* mmap */
117 	{ &vop_fsync_desc, spec_fsync },		/* fsync */
118 	{ &vop_seek_desc, spec_seek },		/* seek */
119 	{ &vop_remove_desc, spec_remove },		/* remove */
120 	{ &vop_link_desc, spec_link },		/* link */
121 	{ &vop_rename_desc, spec_rename },		/* rename */
122 	{ &vop_mkdir_desc, spec_mkdir },		/* mkdir */
123 	{ &vop_rmdir_desc, spec_rmdir },		/* rmdir */
124 	{ &vop_symlink_desc, spec_symlink },		/* symlink */
125 	{ &vop_readdir_desc, spec_readdir },		/* readdir */
126 	{ &vop_readlink_desc, spec_readlink },		/* readlink */
127 	{ &vop_abortop_desc, spec_abortop },		/* abortop */
128 	{ &vop_inactive_desc, nfs_inactive },		/* inactive */
129 	{ &vop_reclaim_desc, nfs_reclaim },		/* reclaim */
130 	{ &vop_lock_desc, nfs_lock },		/* lock */
131 	{ &vop_unlock_desc, nfs_unlock },		/* unlock */
132 	{ &vop_bmap_desc, spec_bmap },		/* bmap */
133 	{ &vop_strategy_desc, spec_strategy },		/* strategy */
134 	{ &vop_print_desc, nfs_print },		/* print */
135 	{ &vop_islocked_desc, nfs_islocked },		/* islocked */
136 	{ &vop_advlock_desc, spec_advlock },		/* advlock */
137 	{ &vop_blkatoff_desc, spec_blkatoff },		/* blkatoff */
138 	{ &vop_vget_desc, spec_vget },		/* vget */
139 	{ &vop_valloc_desc, spec_valloc },		/* valloc */
140 	{ &vop_vfree_desc, spec_vfree },		/* vfree */
141 	{ &vop_truncate_desc, spec_truncate },		/* truncate */
142 	{ &vop_update_desc, nfs_update },		/* update */
143 	{ &vop_bwrite_desc, vn_bwrite },
144 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
145 };
146 struct vnodeopv_desc spec_nfsv2nodeop_opv_desc =
147 	{ &spec_nfsv2nodeop_p, spec_nfsv2nodeop_entries };
148 
149 #ifdef FIFO
150 int (**fifo_nfsv2nodeop_p)();
151 struct vnodeopv_entry_desc fifo_nfsv2nodeop_entries[] = {
152 	{ &vop_default_desc, vn_default_error },
153 	{ &vop_lookup_desc, fifo_lookup },		/* lookup */
154 	{ &vop_create_desc, fifo_create },		/* create */
155 	{ &vop_mknod_desc, fifo_mknod },		/* mknod */
156 	{ &vop_open_desc, fifo_open },		/* open */
157 	{ &vop_close_desc, nfsfifo_close },		/* close */
158 	{ &vop_access_desc, nfs_access },		/* access */
159 	{ &vop_getattr_desc, nfs_getattr },		/* getattr */
160 	{ &vop_setattr_desc, nfs_setattr },		/* setattr */
161 	{ &vop_read_desc, nfsfifo_read },		/* read */
162 	{ &vop_write_desc, nfsfifo_write },		/* write */
163 	{ &vop_ioctl_desc, fifo_ioctl },		/* ioctl */
164 	{ &vop_select_desc, fifo_select },		/* select */
165 	{ &vop_mmap_desc, fifo_mmap },		/* mmap */
166 	{ &vop_fsync_desc, fifo_fsync },		/* fsync */
167 	{ &vop_seek_desc, fifo_seek },		/* seek */
168 	{ &vop_remove_desc, fifo_remove },		/* remove */
169 	{ &vop_link_desc, fifo_link },		/* link */
170 	{ &vop_rename_desc, fifo_rename },		/* rename */
171 	{ &vop_mkdir_desc, fifo_mkdir },		/* mkdir */
172 	{ &vop_rmdir_desc, fifo_rmdir },		/* rmdir */
173 	{ &vop_symlink_desc, fifo_symlink },		/* symlink */
174 	{ &vop_readdir_desc, fifo_readdir },		/* readdir */
175 	{ &vop_readlink_desc, fifo_readlink },		/* readlink */
176 	{ &vop_abortop_desc, fifo_abortop },		/* abortop */
177 	{ &vop_inactive_desc, nfs_inactive },		/* inactive */
178 	{ &vop_reclaim_desc, nfs_reclaim },		/* reclaim */
179 	{ &vop_lock_desc, nfs_lock },		/* lock */
180 	{ &vop_unlock_desc, nfs_unlock },		/* unlock */
181 	{ &vop_bmap_desc, fifo_bmap },		/* bmap */
182 	{ &vop_strategy_desc, fifo_badop },		/* strategy */
183 	{ &vop_print_desc, nfs_print },		/* print */
184 	{ &vop_islocked_desc, nfs_islocked },		/* islocked */
185 	{ &vop_advlock_desc, fifo_advlock },		/* advlock */
186 	{ &vop_blkatoff_desc, fifo_blkatoff },		/* blkatoff */
187 	{ &vop_vget_desc, fifo_vget },		/* vget */
188 	{ &vop_valloc_desc, fifo_valloc },		/* valloc */
189 	{ &vop_vfree_desc, fifo_vfree },		/* vfree */
190 	{ &vop_truncate_desc, fifo_truncate },		/* truncate */
191 	{ &vop_update_desc, nfs_update },		/* update */
192 	{ &vop_bwrite_desc, vn_bwrite },
193 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
194 };
195 struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc =
196 	{ &fifo_nfsv2nodeop_p, fifo_nfsv2nodeop_entries };
197 #endif /* FIFO */
198 
199 /*
200  * Global variables
201  */
202 extern u_long nfs_procids[NFS_NPROCS];
203 extern u_long nfs_prog, nfs_vers;
204 extern char nfsiobuf[MAXPHYS+NBPG];
205 struct buf nfs_bqueue;		/* Queue head for nfsiod's */
206 struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON];
207 int nfs_numasync = 0;
208 #define	DIRHDSIZ	(sizeof (struct readdir) - (MAXNAMLEN + 1))
209 
210 /*
211  * nfs null call from vfs.
212  */
213 int
214 nfs_null(vp, cred, procp)
215 	struct vnode *vp;
216 	struct ucred *cred;
217 	struct proc *procp;
218 {
219 	caddr_t bpos, dpos;
220 	int error = 0;
221 	struct mbuf *mreq, *mrep, *md, *mb;
222 
223 	nfsm_reqhead(vp, NFSPROC_NULL, 0);
224 	nfsm_request(vp, NFSPROC_NULL, procp, cred);
225 	nfsm_reqdone;
226 	return (error);
227 }
228 
229 /*
230  * nfs access vnode op.
231  * Essentially just get vattr and then imitate iaccess()
232  */
233 int
234 nfs_access (ap)
235 	struct vop_access_args *ap;
236 {
237 	USES_VOP_GETATTR;
238 	register struct vattr *vap;
239 	register gid_t *gp;
240 	struct vattr vattr;
241 	register int i;
242 	int error;
243 
244 	/*
245 	 * If you're the super-user,
246 	 * you always get access.
247 	 */
248 	if (ap->a_cred->cr_uid == 0)
249 		return (0);
250 	vap = &vattr;
251 	if (error = VOP_GETATTR(ap->a_vp, vap, ap->a_cred, ap->a_p))
252 		return (error);
253 	/*
254 	 * Access check is based on only one of owner, group, public.
255 	 * If not owner, then check group. If not a member of the
256 	 * group, then check public access.
257 	 */
258 	if (ap->a_cred->cr_uid != vap->va_uid) {
259 		ap->a_mode >>= 3;
260 		gp = ap->a_cred->cr_groups;
261 		for (i = 0; i < ap->a_cred->cr_ngroups; i++, gp++)
262 			if (vap->va_gid == *gp)
263 				goto found;
264 		ap->a_mode >>= 3;
265 found:
266 		;
267 	}
268 	if ((vap->va_mode & ap->a_mode) != 0)
269 		return (0);
270 	return (EACCES);
271 }
272 
273 /*
274  * nfs open vnode op
275  * Just check to see if the type is ok
276  * and that deletion is not in progress.
277  */
278 /* ARGSUSED */
279 int
280 nfs_open (ap)
281 	struct vop_open_args *ap;
282 {
283 
284 	if (ap->a_vp->v_type != VREG && ap->a_vp->v_type != VDIR && ap->a_vp->v_type != VLNK)
285 		return (EACCES);
286 	if ((VFSTONFS(ap->a_vp->v_mount)->nm_flag & NFSMNT_NQNFS) == 0)
287 		VTONFS(ap->a_vp)->n_attrstamp = 0; /* For Open/Close consistency */
288 	return (0);
289 }
290 
291 /*
292  * nfs close vnode op
293  * For reg files, invalidate any buffer cache entries.
294  */
295 /* ARGSUSED */
296 int
297 nfs_close (ap)
298 	struct vop_close_args *ap;
299 {
300 	register struct nfsnode *np = VTONFS(ap->a_vp);
301 	int error = 0;
302 
303 	if (ap->a_vp->v_type == VREG) {
304 	    if ((VFSTONFS(ap->a_vp->v_mount)->nm_flag & NFSMNT_NQNFS) == 0 &&
305 		(np->n_flag & NMODIFIED)) {
306 		np->n_flag &= ~NMODIFIED;
307 		vinvalbuf(ap->a_vp, TRUE);
308 		np->n_attrstamp = 0;
309 	    }
310 	    if (np->n_flag & NWRITEERR) {
311 		np->n_flag &= ~NWRITEERR;
312 		error = np->n_error;
313 	    }
314 	}
315 	return (error);
316 }
317 
318 /*
319  * nfs getattr call from vfs.
320  */
321 int
322 nfs_getattr(ap)
323 	struct vop_getattr_args *ap;
324 {
325 	register struct vnode *vp = ap->a_vp;
326 	register struct nfsnode *np = VTONFS(vp);
327 	register caddr_t cp;
328 	caddr_t bpos, dpos;
329 	int error = 0;
330 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
331 
332 	/*
333 	 * Update local times for special files.
334 	 */
335 	if (np->n_flag & (NACC | NUPD)) {
336 		if (np->n_flag & NACC)
337 			np->n_atim = time;
338 		if (np->n_flag & NUPD)
339 			np->n_mtim = time;
340 		np->n_flag |= NCHG;
341 	}
342 	/*
343 	 * First look in the cache.
344 	 */
345 	if (nfs_getattrcache(vp, ap->a_vap) == 0)
346 		return (0);
347 	nfsstats.rpccnt[NFSPROC_GETATTR]++;
348 	nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH);
349 	nfsm_fhtom(vp);
350 	nfsm_request(vp, NFSPROC_GETATTR, ap->a_p, ap->a_cred);
351 	nfsm_loadattr(vp, ap->a_vap);
352 	nfsm_reqdone;
353 	return (error);
354 }
355 
356 /*
357  * nfs setattr call.
358  */
359 int
360 nfs_setattr (ap)
361 	struct vop_setattr_args *ap;
362 {
363 	register struct nfsv2_sattr *sp;
364 	register caddr_t cp;
365 	register long t1;
366 	caddr_t bpos, dpos, cp2;
367 	u_long *tl;
368 	int error = 0;
369 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
370 	struct nfsnode *np = VTONFS(ap->a_vp);
371 	u_quad_t frev;
372 
373 	nfsstats.rpccnt[NFSPROC_SETATTR]++;
374 	nfsm_reqhead(ap->a_vp, NFSPROC_SETATTR, NFSX_FH+NFSX_SATTR);
375 	nfsm_fhtom(ap->a_vp);
376 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
377 	if (ap->a_vap->va_mode == 0xffff)
378 		sp->sa_mode = VNOVAL;
379 	else
380 		sp->sa_mode = vtonfs_mode(ap->a_vp->v_type, ap->a_vap->va_mode);
381 	if (ap->a_vap->va_uid == 0xffff)
382 		sp->sa_uid = VNOVAL;
383 	else
384 		sp->sa_uid = txdr_unsigned(ap->a_vap->va_uid);
385 	if (ap->a_vap->va_gid == 0xffff)
386 		sp->sa_gid = VNOVAL;
387 	else
388 		sp->sa_gid = txdr_unsigned(ap->a_vap->va_gid);
389 	sp->sa_size = txdr_unsigned(ap->a_vap->va_size);
390 	sp->sa_atime.tv_sec = txdr_unsigned(ap->a_vap->va_atime.tv_sec);
391 	sp->sa_atime.tv_usec = txdr_unsigned(ap->a_vap->va_flags);
392 	txdr_time(&ap->a_vap->va_mtime, &sp->sa_mtime);
393 	if (ap->a_vap->va_size != VNOVAL || ap->a_vap->va_mtime.tv_sec != VNOVAL ||
394 	    ap->a_vap->va_atime.tv_sec != VNOVAL) {
395 		if (np->n_flag & NMODIFIED) {
396 			np->n_flag &= ~NMODIFIED;
397 			if (ap->a_vap->va_size == 0)
398 				vinvalbuf(ap->a_vp, FALSE);
399 			else
400 				vinvalbuf(ap->a_vp, TRUE);
401 		}
402 	}
403 	nfsm_request(ap->a_vp, NFSPROC_SETATTR, ap->a_p, ap->a_cred);
404 	nfsm_loadattr(ap->a_vp, (struct vattr *)0);
405 	if ((VFSTONFS(ap->a_vp->v_mount)->nm_flag & NFSMNT_NQNFS) &&
406 	    NQNFS_CKCACHABLE(ap->a_vp, NQL_WRITE)) {
407 		nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED);
408 		fxdr_hyper(tl, &frev);
409 		if (QUADGT(frev, np->n_brev))
410 			np->n_brev = frev;
411 	}
412 	nfsm_reqdone;
413 	return (error);
414 }
415 
416 /*
417  * nfs lookup call, one step at a time...
418  * First look in cache
419  * If not found, unlock the directory nfsnode and do the rpc
420  */
421 int
422 nfs_lookup (ap)
423 	struct vop_lookup_args *ap;
424 {
425 	USES_VOP_GETATTR;
426 	register struct vnode *vdp;
427 	register u_long *tl;
428 	register caddr_t cp;
429 	register long t1, t2;
430 	struct nfsmount *nmp;
431 	struct nfsnode *tp;
432 	caddr_t bpos, dpos, cp2;
433 	time_t reqtime;
434 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
435 	struct vnode *newvp;
436 	long len;
437 	nfsv2fh_t *fhp;
438 	struct nfsnode *np;
439 	int lockparent, wantparent, error = 0;
440 	int nqlflag, cachable;
441 	u_quad_t frev;
442 
443 	*ap->a_vpp = NULL;
444 	if (ap->a_dvp->v_type != VDIR)
445 		return (ENOTDIR);
446 	lockparent = ap->a_cnp->cn_flags & LOCKPARENT;
447 	wantparent = ap->a_cnp->cn_flags & (LOCKPARENT|WANTPARENT);
448 	nmp = VFSTONFS(ap->a_dvp->v_mount);
449 	np = VTONFS(ap->a_dvp);
450 	if ((error = cache_lookup(ap->a_dvp, ap->a_vpp, ap->a_cnp)) && error != ENOENT) {
451 		struct vattr vattr;
452 		int vpid;
453 
454 		vdp = *ap->a_vpp;
455 		vpid = vdp->v_id;
456 		/*
457 		 * See the comment starting `Step through' in ufs/ufs_lookup.c
458 		 * for an explanation of the locking protocol
459 		 */
460 		if (ap->a_dvp == vdp) {
461 			VREF(vdp);
462 			error = 0;
463 		} else
464 			error = vget(vdp);
465 		if (!error) {
466 			if (vpid == vdp->v_id) {
467 			   if (nmp->nm_flag & NFSMNT_NQNFS) {
468 			        if (NQNFS_CKCACHABLE(ap->a_dvp, NQL_READ)) {
469 					if (QUADNE(np->n_lrev, np->n_brev) ||
470 					    (np->n_flag & NMODIFIED)) {
471 						np->n_direofoffset = 0;
472 						cache_purge(ap->a_dvp);
473 						np->n_flag &= ~NMODIFIED;
474 						vinvalbuf(ap->a_dvp, FALSE);
475 						np->n_brev = np->n_lrev;
476 					} else {
477 						nfsstats.lookupcache_hits++;
478 						if (ap->a_cnp->cn_nameiop != LOOKUP &&
479 						    (ap->a_cnp->cn_flags&ISLASTCN))
480 						    ap->a_cnp->cn_flags |= SAVENAME;
481 						return (0);
482 					}
483 				}
484 			   } else if (!VOP_GETATTR(vdp, &vattr, ap->a_cnp->cn_cred, ap->a_cnp->cn_proc) &&
485 			       vattr.va_ctime.tv_sec == VTONFS(vdp)->n_ctime) {
486 				nfsstats.lookupcache_hits++;
487 				if (ap->a_cnp->cn_nameiop != LOOKUP && (ap->a_cnp->cn_flags&ISLASTCN))
488 					ap->a_cnp->cn_flags |= SAVENAME;
489 				return (0);
490 			   }
491 			   cache_purge(vdp);
492 			}
493 			vrele(vdp);
494 		}
495 		*ap->a_vpp = NULLVP;
496 	}
497 	error = 0;
498 	nfsstats.lookupcache_misses++;
499 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
500 	len = ap->a_cnp->cn_namelen;
501 	nfsm_reqhead(ap->a_dvp, NFSPROC_LOOKUP, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
502 
503 	/*
504 	 * For nqnfs optionally piggyback a getlease request for the name
505 	 * being looked up.
506 	 */
507 	if (nmp->nm_flag & NFSMNT_NQNFS) {
508 		if ((nmp->nm_flag & NFSMNT_NQLOOKLEASE) &&
509 		    ((ap->a_cnp->cn_flags&MAKEENTRY) && (ap->a_cnp->cn_nameiop != DELETE || !(ap->a_cnp->cn_flags&ISLASTCN)))) {
510 			nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED);
511 			*tl++ = txdr_unsigned(NQL_READ);
512 			*tl = txdr_unsigned(nmp->nm_leaseterm);
513 		} else {
514 			nfsm_build(tl, u_long *, NFSX_UNSIGNED);
515 			*tl = 0;
516 		}
517 	}
518 	nfsm_fhtom(ap->a_dvp);
519 	nfsm_strtom(ap->a_cnp->cn_nameptr, len, NFS_MAXNAMLEN);
520 	reqtime = time.tv_sec;
521 	nfsm_request(ap->a_dvp, NFSPROC_LOOKUP, ap->a_cnp->cn_proc, ap->a_cnp->cn_cred);
522 nfsmout:
523 	if (error) {
524 		if ((ap->a_cnp->cn_nameiop == CREATE || ap->a_cnp->cn_nameiop == RENAME) &&
525 		    (ap->a_cnp->cn_flags & ISLASTCN) && error == ENOENT)
526 			error = EJUSTRETURN;
527 		if (ap->a_cnp->cn_nameiop != LOOKUP && (ap->a_cnp->cn_flags&ISLASTCN))
528 			ap->a_cnp->cn_flags |= SAVENAME;
529 		return (error);
530 	}
531 	if (nmp->nm_flag & NFSMNT_NQNFS) {
532 		nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
533 		if (*tl) {
534 			nqlflag = fxdr_unsigned(int, *tl);
535 			nfsm_dissect(tl, u_long *, 4*NFSX_UNSIGNED);
536 			cachable = fxdr_unsigned(int, *tl++);
537 			reqtime += fxdr_unsigned(int, *tl++);
538 			fxdr_hyper(tl, &frev);
539 		} else
540 			nqlflag = 0;
541 	}
542 	nfsm_dissect(fhp, nfsv2fh_t *, NFSX_FH);
543 
544 	/*
545 	 * Handle RENAME case...
546 	 */
547 	if (ap->a_cnp->cn_nameiop == RENAME && wantparent && (ap->a_cnp->cn_flags&ISLASTCN)) {
548 		if (!bcmp(np->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) {
549 			m_freem(mrep);
550 			return (EISDIR);
551 		}
552 		if (error = nfs_nget(ap->a_dvp->v_mount, fhp, &np)) {
553 			m_freem(mrep);
554 			return (error);
555 		}
556 		newvp = NFSTOV(np);
557 		if (error =
558 		    nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) {
559 			vrele(newvp);
560 			m_freem(mrep);
561 			return (error);
562 		}
563 		*ap->a_vpp = newvp;
564 		m_freem(mrep);
565 		ap->a_cnp->cn_flags |= SAVENAME;
566 		return (0);
567 	}
568 
569 	if (!bcmp(np->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) {
570 		VREF(ap->a_dvp);
571 		newvp = ap->a_dvp;
572 	} else {
573 		if (error = nfs_nget(ap->a_dvp->v_mount, fhp, &np)) {
574 			m_freem(mrep);
575 			return (error);
576 		}
577 		newvp = NFSTOV(np);
578 	}
579 	if (error = nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) {
580 		vrele(newvp);
581 		m_freem(mrep);
582 		return (error);
583 	}
584 	m_freem(mrep);
585 	*ap->a_vpp = newvp;
586 	if (ap->a_cnp->cn_nameiop != LOOKUP && (ap->a_cnp->cn_flags&ISLASTCN))
587 		ap->a_cnp->cn_flags |= SAVENAME;
588 	if ((ap->a_cnp->cn_flags&MAKEENTRY) && (ap->a_cnp->cn_nameiop != DELETE || !(ap->a_cnp->cn_flags&ISLASTCN))) {
589 		if ((nmp->nm_flag & NFSMNT_NQNFS) == 0)
590 			np->n_ctime = np->n_vattr.va_ctime.tv_sec;
591 		else if (nqlflag && reqtime > time.tv_sec) {
592 			if (np->n_tnext) {
593 				if (np->n_tnext == (struct nfsnode *)nmp)
594 					nmp->nm_tprev = np->n_tprev;
595 				else
596 					np->n_tnext->n_tprev = np->n_tprev;
597 				if (np->n_tprev == (struct nfsnode *)nmp)
598 					nmp->nm_tnext = np->n_tnext;
599 				else
600 					np->n_tprev->n_tnext = np->n_tnext;
601 				if (nqlflag == NQL_WRITE)
602 					np->n_flag |= NQNFSWRITE;
603 			} else if (nqlflag == NQL_READ)
604 				np->n_flag &= ~NQNFSWRITE;
605 			else
606 				np->n_flag |= NQNFSWRITE;
607 			if (cachable)
608 				np->n_flag &= ~NQNFSNONCACHE;
609 			else
610 				np->n_flag |= NQNFSNONCACHE;
611 			np->n_expiry = reqtime;
612 			np->n_lrev = frev;
613 			tp = nmp->nm_tprev;
614 			while (tp != (struct nfsnode *)nmp && tp->n_expiry > np->n_expiry)
615 				tp = tp->n_tprev;
616 			if (tp == (struct nfsnode *)nmp) {
617 				np->n_tnext = nmp->nm_tnext;
618 				nmp->nm_tnext = np;
619 			} else {
620 				np->n_tnext = tp->n_tnext;
621 				tp->n_tnext = np;
622 			}
623 			np->n_tprev = tp;
624 			if (np->n_tnext == (struct nfsnode *)nmp)
625 				nmp->nm_tprev = np;
626 			else
627 				np->n_tnext->n_tprev = np;
628 		}
629 		cache_enter(ap->a_dvp, *ap->a_vpp, ap->a_cnp);
630 	}
631 	return (0);
632 }
633 
634 /*
635  * nfs read call.
636  * Just call nfs_bioread() to do the work.
637  */
638 int
639 nfs_read (ap)
640 	struct vop_read_args *ap;
641 {
642 	if (ap->a_vp->v_type != VREG)
643 		return (EPERM);
644 	return (nfs_bioread(ap->a_vp, ap->a_uio, ap->a_ioflag, ap->a_cred));
645 }
646 
647 /*
648  * nfs readlink call
649  */
650 int
651 nfs_readlink (ap)
652 	struct vop_readlink_args *ap;
653 {
654 	if (ap->a_vp->v_type != VLNK)
655 		return (EPERM);
656 	return (nfs_bioread(ap->a_vp, ap->a_uio, 0, ap->a_cred));
657 }
658 
659 /*
660  * Do a readlink rpc.
661  * Called by nfs_doio() from below the buffer cache.
662  */
663 int
664 nfs_readlinkrpc(vp, uiop, cred)
665 	register struct vnode *vp;
666 	struct uio *uiop;
667 	struct ucred *cred;
668 {
669 	register u_long *tl;
670 	register caddr_t cp;
671 	register long t1;
672 	caddr_t bpos, dpos, cp2;
673 	int error = 0;
674 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
675 	long len;
676 
677 	nfsstats.rpccnt[NFSPROC_READLINK]++;
678 	nfsm_reqhead(vp, NFSPROC_READLINK, NFSX_FH);
679 	nfsm_fhtom(vp);
680 	nfsm_request(vp, NFSPROC_READLINK, uiop->uio_procp, cred);
681 	nfsm_strsiz(len, NFS_MAXPATHLEN);
682 	nfsm_mtouio(uiop, len);
683 	nfsm_reqdone;
684 	return (error);
685 }
686 
687 /*
688  * nfs read rpc call
689  * Ditto above
690  */
691 int
692 nfs_readrpc(vp, uiop, cred)
693 	register struct vnode *vp;
694 	struct uio *uiop;
695 	struct ucred *cred;
696 {
697 	register u_long *tl;
698 	register caddr_t cp;
699 	register long t1;
700 	caddr_t bpos, dpos, cp2;
701 	int error = 0;
702 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
703 	struct nfsmount *nmp;
704 	long len, retlen, tsiz;
705 
706 	nmp = VFSTONFS(vp->v_mount);
707 	tsiz = uiop->uio_resid;
708 	while (tsiz > 0) {
709 		nfsstats.rpccnt[NFSPROC_READ]++;
710 		len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
711 		nfsm_reqhead(vp, NFSPROC_READ, NFSX_FH+NFSX_UNSIGNED*3);
712 		nfsm_fhtom(vp);
713 		nfsm_build(tl, u_long *, NFSX_UNSIGNED*3);
714 		*tl++ = txdr_unsigned(uiop->uio_offset);
715 		*tl++ = txdr_unsigned(len);
716 		*tl = 0;
717 		nfsm_request(vp, NFSPROC_READ, uiop->uio_procp, cred);
718 		nfsm_loadattr(vp, (struct vattr *)0);
719 		nfsm_strsiz(retlen, nmp->nm_rsize);
720 		nfsm_mtouio(uiop, retlen);
721 		m_freem(mrep);
722 		if (retlen < len)
723 			tsiz = 0;
724 		else
725 			tsiz -= len;
726 	}
727 nfsmout:
728 	return (error);
729 }
730 
731 /*
732  * nfs write call
733  */
734 int
735 nfs_writerpc(vp, uiop, cred)
736 	register struct vnode *vp;
737 	struct uio *uiop;
738 	struct ucred *cred;
739 {
740 	register u_long *tl;
741 	register caddr_t cp;
742 	register long t1;
743 	caddr_t bpos, dpos, cp2;
744 	int error = 0;
745 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
746 	struct nfsmount *nmp;
747 	struct nfsnode *np = VTONFS(vp);
748 	u_quad_t frev;
749 	long len, tsiz;
750 
751 	nmp = VFSTONFS(vp->v_mount);
752 	tsiz = uiop->uio_resid;
753 	while (tsiz > 0) {
754 		nfsstats.rpccnt[NFSPROC_WRITE]++;
755 		len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz;
756 		nfsm_reqhead(vp, NFSPROC_WRITE,
757 			NFSX_FH+NFSX_UNSIGNED*4+nfsm_rndup(len));
758 		nfsm_fhtom(vp);
759 		nfsm_build(tl, u_long *, NFSX_UNSIGNED*4);
760 		*(tl+1) = txdr_unsigned(uiop->uio_offset);
761 		*(tl+3) = txdr_unsigned(len);
762 		nfsm_uiotom(uiop, len);
763 		nfsm_request(vp, NFSPROC_WRITE, uiop->uio_procp, cred);
764 		nfsm_loadattr(vp, (struct vattr *)0);
765 		if (nmp->nm_flag & NFSMNT_MYWRITE)
766 			VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime.tv_sec;
767 		else if ((nmp->nm_flag & NFSMNT_NQNFS) &&
768 			 NQNFS_CKCACHABLE(vp, NQL_WRITE)) {
769 			nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED);
770 			fxdr_hyper(tl, &frev);
771 			if (QUADGT(frev, np->n_brev))
772 				np->n_brev = frev;
773 		}
774 		m_freem(mrep);
775 		tsiz -= len;
776 	}
777 nfsmout:
778 	if (error)
779 		uiop->uio_resid = tsiz;
780 	return (error);
781 }
782 
783 /*
784  * nfs mknod call
785  * This is a kludge. Use a create rpc but with the IFMT bits of the mode
786  * set to specify the file type and the size field for rdev.
787  */
788 /* ARGSUSED */
789 int
790 nfs_mknod (ap)
791 	struct vop_mknod_args *ap;
792 {
793 	USES_VOP_ABORTOP;
794 	register struct nfsv2_sattr *sp;
795 	register u_long *tl;
796 	register caddr_t cp;
797 	register long t2;
798 	caddr_t bpos, dpos;
799 	int error = 0;
800 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
801 	u_long rdev;
802 
803 	if (ap->a_vap->va_type == VCHR || ap->a_vap->va_type == VBLK)
804 		rdev = txdr_unsigned(ap->a_vap->va_rdev);
805 #ifdef FIFO
806 	else if (ap->a_vap->va_type == VFIFO)
807 		rdev = 0xffffffff;
808 #endif /* FIFO */
809 	else {
810 		VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
811 		vput(ap->a_dvp);
812 		return (EOPNOTSUPP);
813 	}
814 	nfsstats.rpccnt[NFSPROC_CREATE]++;
815 	nfsm_reqhead(ap->a_dvp, NFSPROC_CREATE,
816 	  NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ap->a_cnp->cn_namelen)+NFSX_SATTR);
817 	nfsm_fhtom(ap->a_dvp);
818 	nfsm_strtom(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen, NFS_MAXNAMLEN);
819 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
820 	sp->sa_mode = vtonfs_mode(ap->a_vap->va_type, ap->a_vap->va_mode);
821 	sp->sa_uid = txdr_unsigned(ap->a_cnp->cn_cred->cr_uid);
822 	sp->sa_gid = txdr_unsigned(ap->a_cnp->cn_cred->cr_gid);
823 	sp->sa_size = rdev;
824 	/* or should these be VNOVAL ?? */
825 	txdr_time(&ap->a_vap->va_atime, &sp->sa_atime);
826 	txdr_time(&ap->a_vap->va_mtime, &sp->sa_mtime);
827 	nfsm_request(ap->a_dvp, NFSPROC_CREATE, ap->a_cnp->cn_proc, ap->a_cnp->cn_cred);
828 	nfsm_reqdone;
829 	FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
830 	VTONFS(ap->a_dvp)->n_flag |= NMODIFIED;
831 	vrele(ap->a_dvp);
832 	return (error);
833 }
834 
835 /*
836  * nfs file create call
837  */
838 int
839 nfs_create (ap)
840 	struct vop_create_args *ap;
841 {
842 	register struct nfsv2_sattr *sp;
843 	register u_long *tl;
844 	register caddr_t cp;
845 	register long t1, t2;
846 	caddr_t bpos, dpos, cp2;
847 	int error = 0;
848 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
849 
850 	nfsstats.rpccnt[NFSPROC_CREATE]++;
851 	nfsm_reqhead(ap->a_dvp, NFSPROC_CREATE,
852 	  NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ap->a_cnp->cn_namelen)+NFSX_SATTR);
853 	nfsm_fhtom(ap->a_dvp);
854 	nfsm_strtom(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen, NFS_MAXNAMLEN);
855 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
856 	sp->sa_mode = vtonfs_mode(ap->a_vap->va_type, ap->a_vap->va_mode);
857 	sp->sa_uid = txdr_unsigned(ap->a_cnp->cn_cred->cr_uid);
858 	sp->sa_gid = txdr_unsigned(ap->a_cnp->cn_cred->cr_gid);
859 	sp->sa_size = txdr_unsigned(0);
860 	/* or should these be VNOVAL ?? */
861 	txdr_time(&ap->a_vap->va_atime, &sp->sa_atime);
862 	txdr_time(&ap->a_vap->va_mtime, &sp->sa_mtime);
863 	nfsm_request(ap->a_dvp, NFSPROC_CREATE, ap->a_cnp->cn_proc, ap->a_cnp->cn_cred);
864 	nfsm_mtofh(ap->a_dvp, *ap->a_vpp);
865 	nfsm_reqdone;
866 	FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
867 	VTONFS(ap->a_dvp)->n_flag |= NMODIFIED;
868 	vrele(ap->a_dvp);
869 	return (error);
870 }
871 
872 /*
873  * nfs file remove call
874  * To try and make nfs semantics closer to ufs semantics, a file that has
875  * other processes using the vnode is renamed instead of removed and then
876  * removed later on the last close.
877  * - If v_usecount > 1
878  *	  If a rename is not already in the works
879  *	     call nfs_sillyrename() to set it up
880  *     else
881  *	  do the remove rpc
882  */
883 int
884 nfs_remove (ap)
885 	struct vop_remove_args *ap;
886 {
887 	register struct nfsnode *np = VTONFS(ap->a_vp);
888 	register u_long *tl;
889 	register caddr_t cp;
890 	register long t2;
891 	caddr_t bpos, dpos;
892 	int error = 0;
893 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
894 
895 	if (ap->a_vp->v_usecount > 1) {
896 		if (!np->n_sillyrename)
897 			error = nfs_sillyrename(ap->a_dvp, ap->a_vp, ap->a_cnp);
898 	} else {
899 		/*
900 		 * Purge the name cache so that the chance of a lookup for
901 		 * the name succeeding while the remove is in progress is
902 		 * minimized. Without node locking it can still happen, such
903 		 * that an I/O op returns ESTALE, but since you get this if
904 		 * another host removes the file..
905 		 */
906 		cache_purge(ap->a_vp);
907 		/*
908 		 * Throw away biocache buffers. Mainly to avoid
909 		 * unnecessary delayed writes.
910 		 */
911 		vinvalbuf(ap->a_vp, FALSE);
912 		/* Do the rpc */
913 		nfsstats.rpccnt[NFSPROC_REMOVE]++;
914 		nfsm_reqhead(ap->a_dvp, NFSPROC_REMOVE,
915 			NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ap->a_cnp->cn_namelen));
916 		nfsm_fhtom(ap->a_dvp);
917 		nfsm_strtom(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen, NFS_MAXNAMLEN);
918 		nfsm_request(ap->a_dvp, NFSPROC_REMOVE, ap->a_cnp->cn_proc, ap->a_cnp->cn_cred);
919 		nfsm_reqdone;
920 		FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
921 		VTONFS(ap->a_dvp)->n_flag |= NMODIFIED;
922 		/*
923 		 * Kludge City: If the first reply to the remove rpc is lost..
924 		 *   the reply to the retransmitted request will be ENOENT
925 		 *   since the file was in fact removed
926 		 *   Therefore, we cheat and return success.
927 		 */
928 		if (error == ENOENT)
929 			error = 0;
930 	}
931 	np->n_attrstamp = 0;
932 	vrele(ap->a_dvp);
933 	vrele(ap->a_vp);
934 	return (error);
935 }
936 
937 /*
938  * nfs file remove rpc called from nfs_inactive
939  */
940 int
941 nfs_removeit(sp, procp)
942 	register struct sillyrename *sp;
943 	struct proc *procp;
944 {
945 	register u_long *tl;
946 	register caddr_t cp;
947 	register long t2;
948 	caddr_t bpos, dpos;
949 	int error = 0;
950 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
951 
952 	nfsstats.rpccnt[NFSPROC_REMOVE]++;
953 	nfsm_reqhead(sp->s_dvp, NFSPROC_REMOVE,
954 		NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(sp->s_namlen));
955 	nfsm_fhtom(sp->s_dvp);
956 	nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN);
957 	nfsm_request(sp->s_dvp, NFSPROC_REMOVE, procp, sp->s_cred);
958 	nfsm_reqdone;
959 	VTONFS(sp->s_dvp)->n_flag |= NMODIFIED;
960 	return (error);
961 }
962 
963 /*
964  * nfs file rename call
965  */
966 int
967 nfs_rename (ap)
968 	struct vop_rename_args *ap;
969 {
970 	register u_long *tl;
971 	register caddr_t cp;
972 	register long t2;
973 	caddr_t bpos, dpos;
974 	int error = 0;
975 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
976 
977 	/* Check for cross-device rename */
978 	if ((ap->a_fvp->v_mount != ap->a_tdvp->v_mount) ||
979 	    (ap->a_tvp && (ap->a_fvp->v_mount != ap->a_tvp->v_mount))) {
980 		error = EXDEV;
981 		goto out;
982 	}
983 
984 
985 	nfsstats.rpccnt[NFSPROC_RENAME]++;
986 	nfsm_reqhead(ap->a_fdvp, NFSPROC_RENAME,
987 		(NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(ap->a_fcnp->cn_namelen)+
988 		nfsm_rndup(ap->a_fcnp->cn_namelen)); /* or ap->a_fcnp->cn_cred?*/
989 	nfsm_fhtom(ap->a_fdvp);
990 	nfsm_strtom(ap->a_fcnp->cn_nameptr, ap->a_fcnp->cn_namelen, NFS_MAXNAMLEN);
991 	nfsm_fhtom(ap->a_tdvp);
992 	nfsm_strtom(ap->a_tcnp->cn_nameptr, ap->a_tcnp->cn_namelen, NFS_MAXNAMLEN);
993 	nfsm_request(ap->a_fdvp, NFSPROC_RENAME, ap->a_tcnp->cn_proc, ap->a_tcnp->cn_cred);
994 	nfsm_reqdone;
995 	VTONFS(ap->a_fdvp)->n_flag |= NMODIFIED;
996 	VTONFS(ap->a_tdvp)->n_flag |= NMODIFIED;
997 	if (ap->a_fvp->v_type == VDIR) {
998 		if (ap->a_tvp != NULL && ap->a_tvp->v_type == VDIR)
999 			cache_purge(ap->a_tdvp);
1000 		cache_purge(ap->a_fdvp);
1001 	}
1002 out:
1003 	if (ap->a_tdvp == ap->a_tvp)
1004 		vrele(ap->a_tdvp);
1005 	else
1006 		vput(ap->a_tdvp);
1007 	if (ap->a_tvp)
1008 		vput(ap->a_tvp);
1009 	vrele(ap->a_fdvp);
1010 	vrele(ap->a_fvp);
1011 	/*
1012 	 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
1013 	 */
1014 	if (error == ENOENT)
1015 		error = 0;
1016 	return (error);
1017 }
1018 
1019 /*
1020  * nfs file rename rpc called from nfs_remove() above
1021  */
1022 int
1023 nfs_renameit(sdvp, scnp, sp)
1024 	struct vnode *sdvp;
1025 	struct componentname *scnp;
1026 	register struct sillyrename *sp;
1027 {
1028 	register u_long *tl;
1029 	register caddr_t cp;
1030 	register long t2;
1031 	caddr_t bpos, dpos;
1032 	int error = 0;
1033 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1034 
1035 	nfsstats.rpccnt[NFSPROC_RENAME]++;
1036 	nfsm_reqhead(sdvp, NFSPROC_RENAME,
1037 		(NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(scnp->cn_namelen)+
1038 		nfsm_rndup(sp->s_namlen));
1039 	nfsm_fhtom(sdvp);
1040 	nfsm_strtom(scnp->cn_nameptr, scnp->cn_namelen, NFS_MAXNAMLEN);
1041 	nfsm_fhtom(sdvp);
1042 	nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN);
1043 	nfsm_request(sdvp, NFSPROC_RENAME, scnp->cn_proc, scnp->cn_cred);
1044 	nfsm_reqdone;
1045 	FREE(scnp->cn_pnbuf, M_NAMEI);
1046 	VTONFS(sdvp)->n_flag |= NMODIFIED;
1047 	return (error);
1048 }
1049 
1050 /*
1051  * nfs hard link create call
1052  */
1053 int
1054 nfs_link (ap)
1055 	struct vop_link_args *ap;
1056 {
1057 	register u_long *tl;
1058 	register caddr_t cp;
1059 	register long t2;
1060 	caddr_t bpos, dpos;
1061 	int error = 0;
1062 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1063 
1064 	if (ap->a_vp->v_mount != ap->a_tdvp->v_mount) {
1065 		/*VOP_ABORTOP(ap->a_vp, ap->a_cnp);*/
1066 		if (ap->a_tdvp == ap->a_vp)
1067 			vrele(ap->a_vp);
1068 		else
1069 			vput(ap->a_vp);
1070 		vrele(ap->a_tdvp);
1071 		return (EXDEV);
1072 	}
1073 
1074 	nfsstats.rpccnt[NFSPROC_LINK]++;
1075 	nfsm_reqhead(ap->a_tdvp, NFSPROC_LINK,
1076 		NFSX_FH*2+NFSX_UNSIGNED+nfsm_rndup(ap->a_cnp->cn_namelen));
1077 	nfsm_fhtom(ap->a_tdvp);
1078 	nfsm_fhtom(ap->a_vp);
1079 	nfsm_strtom(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen, NFS_MAXNAMLEN);
1080 	nfsm_request(ap->a_tdvp, NFSPROC_LINK, ap->a_cnp->cn_proc, ap->a_cnp->cn_cred);
1081 	nfsm_reqdone;
1082 	FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
1083 	VTONFS(ap->a_tdvp)->n_attrstamp = 0;
1084 	VTONFS(ap->a_vp)->n_flag |= NMODIFIED;
1085 	vrele(ap->a_vp);
1086 	/*
1087 	 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
1088 	 */
1089 	if (error == EEXIST)
1090 		error = 0;
1091 	return (error);
1092 }
1093 
1094 /*
1095  * nfs symbolic link create call
1096  */
1097 /* start here */
1098 int
1099 nfs_symlink (ap)
1100 	struct vop_symlink_args *ap;
1101 {
1102 	register struct nfsv2_sattr *sp;
1103 	register u_long *tl;
1104 	register caddr_t cp;
1105 	register long t2;
1106 	caddr_t bpos, dpos;
1107 	int slen, error = 0;
1108 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1109 
1110 	nfsstats.rpccnt[NFSPROC_SYMLINK]++;
1111 	slen = strlen(ap->a_target);
1112 	nfsm_reqhead(ap->a_dvp, NFSPROC_SYMLINK,
1113 	 NFSX_FH+2*NFSX_UNSIGNED+nfsm_rndup(ap->a_cnp->cn_namelen)+nfsm_rndup(slen)+NFSX_SATTR);
1114 	nfsm_fhtom(ap->a_dvp);
1115 	nfsm_strtom(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen, NFS_MAXNAMLEN);
1116 	nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN);
1117 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
1118 	sp->sa_mode = vtonfs_mode(VLNK, ap->a_vap->va_mode);
1119 	sp->sa_uid = txdr_unsigned(ap->a_cnp->cn_cred->cr_uid);
1120 	sp->sa_gid = txdr_unsigned(ap->a_cnp->cn_cred->cr_gid);
1121 	sp->sa_size = txdr_unsigned(VNOVAL);
1122 	txdr_time(&ap->a_vap->va_atime, &sp->sa_atime);	/* or VNOVAL ?? */
1123 	txdr_time(&ap->a_vap->va_mtime, &sp->sa_mtime);	/* or VNOVAL ?? */
1124 	nfsm_request(ap->a_dvp, NFSPROC_SYMLINK, ap->a_cnp->cn_proc, ap->a_cnp->cn_cred);
1125 	nfsm_reqdone;
1126 	FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
1127 	VTONFS(ap->a_dvp)->n_flag |= NMODIFIED;
1128 	vrele(ap->a_dvp);
1129 	/*
1130 	 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
1131 	 */
1132 	if (error == EEXIST)
1133 		error = 0;
1134 	return (error);
1135 }
1136 
1137 /*
1138  * nfs make dir call
1139  */
1140 int
1141 nfs_mkdir (ap)
1142 	struct vop_mkdir_args *ap;
1143 {
1144 	register struct nfsv2_sattr *sp;
1145 	register u_long *tl;
1146 	register caddr_t cp;
1147 	register long t1, t2;
1148 	register int len;
1149 	caddr_t bpos, dpos, cp2;
1150 	int error = 0, firsttry = 1;
1151 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1152 
1153 	len = ap->a_cnp->cn_namelen;
1154 	nfsstats.rpccnt[NFSPROC_MKDIR]++;
1155 	nfsm_reqhead(ap->a_dvp, NFSPROC_MKDIR,
1156 	  NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)+NFSX_SATTR);
1157 	nfsm_fhtom(ap->a_dvp);
1158 	nfsm_strtom(ap->a_cnp->cn_nameptr, len, NFS_MAXNAMLEN);
1159 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
1160 	sp->sa_mode = vtonfs_mode(VDIR, ap->a_vap->va_mode);
1161 	sp->sa_uid = txdr_unsigned(ap->a_cnp->cn_cred->cr_uid);
1162 	sp->sa_gid = txdr_unsigned(ap->a_cnp->cn_cred->cr_gid);
1163 	sp->sa_size = txdr_unsigned(VNOVAL);
1164 	txdr_time(&ap->a_vap->va_atime, &sp->sa_atime);	/* or VNOVAL ?? */
1165 	txdr_time(&ap->a_vap->va_mtime, &sp->sa_mtime);	/* or VNOVAL ?? */
1166 	nfsm_request(ap->a_dvp, NFSPROC_MKDIR, ap->a_cnp->cn_proc, ap->a_cnp->cn_cred);
1167 	nfsm_mtofh(ap->a_dvp, *ap->a_vpp);
1168 	nfsm_reqdone;
1169 	VTONFS(ap->a_dvp)->n_flag |= NMODIFIED;
1170 	/*
1171 	 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry
1172 	 * if we can succeed in looking up the directory.
1173 	 * "firsttry" is necessary since the macros may "goto nfsmout" which
1174 	 * is above the if on errors. (Ugh)
1175 	 */
1176 	if (error == EEXIST && firsttry) {
1177 		firsttry = 0;
1178 		error = 0;
1179 		nfsstats.rpccnt[NFSPROC_LOOKUP]++;
1180 		*ap->a_vpp = NULL;
1181 		nfsm_reqhead(ap->a_dvp, NFSPROC_LOOKUP,
1182 		    NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
1183 		nfsm_fhtom(ap->a_dvp);
1184 		nfsm_strtom(ap->a_cnp->cn_nameptr, len, NFS_MAXNAMLEN);
1185 		nfsm_request(ap->a_dvp, NFSPROC_LOOKUP, ap->a_cnp->cn_proc, ap->a_cnp->cn_cred);
1186 		nfsm_mtofh(ap->a_dvp, *ap->a_vpp);
1187 		if ((*ap->a_vpp)->v_type != VDIR) {
1188 			vput(*ap->a_vpp);
1189 			error = EEXIST;
1190 		}
1191 		m_freem(mrep);
1192 	}
1193 	FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
1194 	vrele(ap->a_dvp);
1195 	return (error);
1196 }
1197 
1198 /*
1199  * nfs remove directory call
1200  */
1201 int
1202 nfs_rmdir (ap)
1203 	struct vop_rmdir_args *ap;
1204 {
1205 	register u_long *tl;
1206 	register caddr_t cp;
1207 	register long t2;
1208 	caddr_t bpos, dpos;
1209 	int error = 0;
1210 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1211 
1212 	if (ap->a_dvp == ap->a_vp) {
1213 		vrele(ap->a_dvp);
1214 		vrele(ap->a_dvp);
1215 		FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
1216 		return (EINVAL);
1217 	}
1218 	nfsstats.rpccnt[NFSPROC_RMDIR]++;
1219 	nfsm_reqhead(ap->a_dvp, NFSPROC_RMDIR,
1220 		NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ap->a_cnp->cn_namelen));
1221 	nfsm_fhtom(ap->a_dvp);
1222 	nfsm_strtom(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen, NFS_MAXNAMLEN);
1223 	nfsm_request(ap->a_dvp, NFSPROC_RMDIR, ap->a_cnp->cn_proc, ap->a_cnp->cn_cred);
1224 	nfsm_reqdone;
1225 	FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
1226 	VTONFS(ap->a_dvp)->n_flag |= NMODIFIED;
1227 	cache_purge(ap->a_dvp);
1228 	cache_purge(ap->a_vp);
1229 	vrele(ap->a_vp);
1230 	vrele(ap->a_dvp);
1231 	/*
1232 	 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
1233 	 */
1234 	if (error == ENOENT)
1235 		error = 0;
1236 	return (error);
1237 }
1238 
1239 /*
1240  * nfs readdir call
1241  * Although cookie is defined as opaque, I translate it to/from net byte
1242  * order so that it looks more sensible. This appears consistent with the
1243  * Ultrix implementation of NFS.
1244  */
1245 int
1246 nfs_readdir (ap)
1247 	struct vop_readdir_args *ap;
1248 {
1249 	USES_VOP_GETATTR;
1250 	register struct nfsnode *np = VTONFS(ap->a_vp);
1251 	int tresid, error;
1252 	struct vattr vattr;
1253 
1254 	if (ap->a_vp->v_type != VDIR)
1255 		return (EPERM);
1256 	/*
1257 	 * First, check for hit on the EOF offset cache
1258 	 */
1259 	if (ap->a_uio->uio_offset != 0 && ap->a_uio->uio_offset == np->n_direofoffset &&
1260 	    (np->n_flag & NMODIFIED) == 0) {
1261 		if (VFSTONFS(ap->a_vp->v_mount)->nm_flag & NFSMNT_NQNFS) {
1262 			if (NQNFS_CKCACHABLE(ap->a_vp, NQL_READ)) {
1263 				*ap->a_eofflagp = 1;
1264 				nfsstats.direofcache_hits++;
1265 				return (0);
1266 			}
1267 		} else if (VOP_GETATTR(ap->a_vp, &vattr, ap->a_cred, ap->a_uio->uio_procp) == 0 &&
1268 			np->n_mtime == vattr.va_mtime.tv_sec) {
1269 			*ap->a_eofflagp = 1;
1270 			nfsstats.direofcache_hits++;
1271 			return (0);
1272 		}
1273 	}
1274 
1275 	/*
1276 	 * Call nfs_bioread() to do the real work.
1277 	 */
1278 	tresid = ap->a_uio->uio_resid;
1279 	error = nfs_bioread(ap->a_vp, ap->a_uio, 0, ap->a_cred);
1280 
1281 	if (!error && ap->a_uio->uio_resid == tresid) {
1282 		*ap->a_eofflagp = 1;
1283 		nfsstats.direofcache_misses++;
1284 	} else
1285 		*ap->a_eofflagp = 0;
1286 	return (error);
1287 }
1288 
1289 /*
1290  * Readdir rpc call.
1291  * Called from below the buffer cache by nfs_doio().
1292  */
1293 int
1294 nfs_readdirrpc(vp, uiop, cred)
1295 	register struct vnode *vp;
1296 	struct uio *uiop;
1297 	struct ucred *cred;
1298 {
1299 	register long len;
1300 	register struct readdir *dp;
1301 	register u_long *tl;
1302 	register caddr_t cp;
1303 	register long t1;
1304 	long tlen, lastlen;
1305 	caddr_t bpos, dpos, cp2;
1306 	int error = 0;
1307 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1308 	struct mbuf *md2;
1309 	caddr_t dpos2;
1310 	int siz;
1311 	int more_dirs = 1;
1312 	off_t off, savoff;
1313 	struct readdir *savdp;
1314 	struct nfsmount *nmp;
1315 	struct nfsnode *np = VTONFS(vp);
1316 	long tresid;
1317 
1318 	nmp = VFSTONFS(vp->v_mount);
1319 	tresid = uiop->uio_resid;
1320 	/*
1321 	 * Loop around doing readdir rpc's of size uio_resid or nm_rsize,
1322 	 * whichever is smaller, truncated to a multiple of NFS_DIRBLKSIZ.
1323 	 * The stopping criteria is EOF or buffer full.
1324 	 */
1325 	while (more_dirs && uiop->uio_resid >= NFS_DIRBLKSIZ) {
1326 		nfsstats.rpccnt[NFSPROC_READDIR]++;
1327 		nfsm_reqhead(vp, NFSPROC_READDIR,
1328 			NFSX_FH+2*NFSX_UNSIGNED);
1329 		nfsm_fhtom(vp);
1330 		nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED);
1331 		*tl++ = txdr_unsigned(uiop->uio_offset);
1332 		*tl = txdr_unsigned(((uiop->uio_resid > nmp->nm_rsize) ?
1333 			nmp->nm_rsize : uiop->uio_resid) & ~(NFS_DIRBLKSIZ-1));
1334 		nfsm_request(vp, NFSPROC_READDIR, uiop->uio_procp, cred);
1335 		siz = 0;
1336 		nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
1337 		more_dirs = fxdr_unsigned(int, *tl);
1338 
1339 		/* Save the position so that we can do nfsm_mtouio() later */
1340 		dpos2 = dpos;
1341 		md2 = md;
1342 
1343 		/* loop thru the dir entries, doctoring them to 4bsd form */
1344 		off = uiop->uio_offset;
1345 #ifdef lint
1346 		dp = (struct readdir *)0;
1347 #endif /* lint */
1348 		while (more_dirs && siz < uiop->uio_resid) {
1349 			savoff = off;		/* Hold onto offset and dp */
1350 			savdp = dp;
1351 			nfsm_dissecton(tl, u_long *, 2*NFSX_UNSIGNED);
1352 			dp = (struct readdir *)tl;
1353 			dp->d_ino = fxdr_unsigned(u_long, *tl++);
1354 			len = fxdr_unsigned(int, *tl);
1355 			if (len <= 0 || len > NFS_MAXNAMLEN) {
1356 				error = EBADRPC;
1357 				m_freem(mrep);
1358 				goto nfsmout;
1359 			}
1360 			dp->d_namlen = (u_short)len;
1361 			nfsm_adv(len);		/* Point past name */
1362 			tlen = nfsm_rndup(len);
1363 			/*
1364 			 * This should not be necessary, but some servers have
1365 			 * broken XDR such that these bytes are not null filled.
1366 			 */
1367 			if (tlen != len) {
1368 				*dpos = '\0';	/* Null-terminate */
1369 				nfsm_adv(tlen - len);
1370 				len = tlen;
1371 			}
1372 			nfsm_dissecton(tl, u_long *, 2*NFSX_UNSIGNED);
1373 			off = fxdr_unsigned(off_t, *tl);
1374 			*tl++ = 0;	/* Ensures null termination of name */
1375 			more_dirs = fxdr_unsigned(int, *tl);
1376 			dp->d_reclen = len+4*NFSX_UNSIGNED;
1377 			siz += dp->d_reclen;
1378 		}
1379 		/*
1380 		 * If at end of rpc data, get the eof boolean
1381 		 */
1382 		if (!more_dirs) {
1383 			nfsm_dissecton(tl, u_long *, NFSX_UNSIGNED);
1384 			more_dirs = (fxdr_unsigned(int, *tl) == 0);
1385 
1386 			/*
1387 			 * If at EOF, cache directory offset
1388 			 */
1389 			if (!more_dirs)
1390 				np->n_direofoffset = off;
1391 		}
1392 		/*
1393 		 * If there is too much to fit in the data buffer, use savoff and
1394 		 * savdp to trim off the last record.
1395 		 * --> we are not at eof
1396 		 */
1397 		if (siz > uiop->uio_resid) {
1398 			off = savoff;
1399 			siz -= dp->d_reclen;
1400 			dp = savdp;
1401 			more_dirs = 0;	/* Paranoia */
1402 		}
1403 		if (siz > 0) {
1404 			lastlen = dp->d_reclen;
1405 			md = md2;
1406 			dpos = dpos2;
1407 			nfsm_mtouio(uiop, siz);
1408 			uiop->uio_offset = off;
1409 		} else
1410 			more_dirs = 0;	/* Ugh, never happens, but in case.. */
1411 		m_freem(mrep);
1412 	}
1413 	/*
1414 	 * Fill last record, iff any, out to a multiple of NFS_DIRBLKSIZ
1415 	 * by increasing d_reclen for the last record.
1416 	 */
1417 	if (uiop->uio_resid < tresid) {
1418 		len = uiop->uio_resid & (NFS_DIRBLKSIZ - 1);
1419 		if (len > 0) {
1420 			dp = (struct readdir *)
1421 				(uiop->uio_iov->iov_base - lastlen);
1422 			dp->d_reclen += len;
1423 			uiop->uio_iov->iov_base += len;
1424 			uiop->uio_iov->iov_len -= len;
1425 			uiop->uio_resid -= len;
1426 		}
1427 	}
1428 nfsmout:
1429 	return (error);
1430 }
1431 
1432 /*
1433  * Nqnfs readdir_and_lookup RPC. Used in place of nfs_readdirrpc() when
1434  * the "rdirlook" mount option is specified.
1435  */
1436 int
1437 nfs_readdirlookrpc(vp, uiop, cred)
1438 	struct vnode *vp;
1439 	register struct uio *uiop;
1440 	struct ucred *cred;
1441 {
1442 	register int len;
1443 	register struct readdir *dp;
1444 	register u_long *tl;
1445 	register caddr_t cp;
1446 	register long t1;
1447 	caddr_t bpos, dpos, cp2;
1448 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1449 	struct nameidata nami, *ndp = &nami;
1450 	struct componentname *cnp = &ndp->ni_cnd;
1451 	off_t off, endoff;
1452 	time_t reqtime, ltime;
1453 	struct nfsmount *nmp;
1454 	struct nfsnode *np, *tp;
1455 	struct vnode *newvp;
1456 	nfsv2fh_t *fhp;
1457 	u_long fileno;
1458 	u_quad_t frev;
1459 	int error = 0, tlen, more_dirs = 1, tresid, doit, bigenough, i;
1460 	int cachable;
1461 
1462 	if (uiop->uio_iovcnt != 1)
1463 		panic("nfs rdirlook");
1464 	nmp = VFSTONFS(vp->v_mount);
1465 	tresid = uiop->uio_resid;
1466 	ndp->ni_dvp = vp;
1467 	newvp = NULLVP;
1468 	/*
1469 	 * Loop around doing readdir rpc's of size uio_resid or nm_rsize,
1470 	 * whichever is smaller, truncated to a multiple of NFS_DIRBLKSIZ.
1471 	 * The stopping criteria is EOF or buffer full.
1472 	 */
1473 	while (more_dirs && uiop->uio_resid >= NFS_DIRBLKSIZ) {
1474 		nfsstats.rpccnt[NQNFSPROC_READDIRLOOK]++;
1475 		nfsm_reqhead(vp, NQNFSPROC_READDIRLOOK,
1476 			NFSX_FH+3*NFSX_UNSIGNED);
1477 		nfsm_fhtom(vp);
1478 		nfsm_build(tl, u_long *, 3*NFSX_UNSIGNED);
1479 		*tl++ = txdr_unsigned(uiop->uio_offset);
1480 		*tl++ = txdr_unsigned(((uiop->uio_resid > nmp->nm_rsize) ?
1481 			nmp->nm_rsize : uiop->uio_resid) & ~(NFS_DIRBLKSIZ-1));
1482 		*tl = txdr_unsigned(nmp->nm_leaseterm);
1483 		reqtime = time.tv_sec;
1484 		nfsm_request(vp, NQNFSPROC_READDIRLOOK, uiop->uio_procp, cred);
1485 		nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
1486 		more_dirs = fxdr_unsigned(int, *tl);
1487 
1488 		/* loop thru the dir entries, doctoring them to 4bsd form */
1489 		off = uiop->uio_offset;
1490 		bigenough = 1;
1491 		while (more_dirs && bigenough) {
1492 			doit = 1;
1493 			nfsm_dissect(tl, u_long *, 4*NFSX_UNSIGNED);
1494 			cachable = fxdr_unsigned(int, *tl++);
1495 			ltime = reqtime + fxdr_unsigned(int, *tl++);
1496 			fxdr_hyper(tl, &frev);
1497 			nfsm_dissect(fhp, nfsv2fh_t *, NFSX_FH);
1498 			if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) {
1499 				VREF(vp);
1500 				newvp = vp;
1501 				np = VTONFS(vp);
1502 			} else {
1503 				if (error = nfs_nget(vp->v_mount, fhp, &np))
1504 					doit = 0;
1505 				newvp = NFSTOV(np);
1506 			}
1507 			if (error = nfs_loadattrcache(&newvp, &md, &dpos,
1508 				(struct vattr *)0))
1509 				doit = 0;
1510 			nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED);
1511 			fileno = fxdr_unsigned(u_long, *tl++);
1512 			len = fxdr_unsigned(int, *tl);
1513 			if (len <= 0 || len > NFS_MAXNAMLEN) {
1514 				error = EBADRPC;
1515 				m_freem(mrep);
1516 				goto nfsmout;
1517 			}
1518 			tlen = (len + 4) & ~0x3;
1519 			if ((tlen + DIRHDSIZ) > uiop->uio_resid)
1520 				bigenough = 0;
1521 			if (bigenough && doit) {
1522 				dp = (struct readdir *)uiop->uio_iov->iov_base;
1523 				dp->d_ino = fileno;
1524 				dp->d_namlen = len;
1525 				dp->d_reclen = tlen + DIRHDSIZ;
1526 				uiop->uio_resid -= DIRHDSIZ;
1527 				uiop->uio_iov->iov_base += DIRHDSIZ;
1528 				uiop->uio_iov->iov_len -= DIRHDSIZ;
1529 				cnp->cn_nameptr = uiop->uio_iov->iov_base;
1530 				cnp->cn_namelen = len;
1531 				ndp->ni_vp = newvp;
1532 				nfsm_mtouio(uiop, len);
1533 				cp = uiop->uio_iov->iov_base;
1534 				tlen -= len;
1535 				for (i = 0; i < tlen; i++)
1536 					*cp++ = '\0';
1537 				uiop->uio_iov->iov_base += tlen;
1538 				uiop->uio_iov->iov_len -= tlen;
1539 				uiop->uio_resid -= tlen;
1540 				cnp->cn_hash = 0;
1541 				for (cp = cnp->cn_nameptr, i = 1; i <= len; i++, cp++)
1542 					cnp->cn_hash += (unsigned char)*cp * i;
1543 				if (ltime > time.tv_sec) {
1544 					if (np->n_tnext) {
1545 						if (np->n_tnext == (struct nfsnode *)nmp)
1546 							nmp->nm_tprev = np->n_tprev;
1547 						else
1548 							np->n_tnext->n_tprev = np->n_tprev;
1549 						if (np->n_tprev == (struct nfsnode *)nmp)
1550 							nmp->nm_tnext = np->n_tnext;
1551 						else
1552 							np->n_tprev->n_tnext = np->n_tnext;
1553 					} else
1554 						np->n_flag &= ~NQNFSWRITE;
1555 					if (cachable)
1556 						np->n_flag &= ~NQNFSNONCACHE;
1557 					else
1558 						np->n_flag |= NQNFSNONCACHE;
1559 					np->n_expiry = ltime;
1560 					np->n_lrev = frev;
1561 					tp = nmp->nm_tprev;
1562 					while (tp != (struct nfsnode *)nmp && tp->n_expiry > np->n_expiry)
1563 						tp = tp->n_tprev;
1564 					if (tp == (struct nfsnode *)nmp) {
1565 						np->n_tnext = nmp->nm_tnext;
1566 						nmp->nm_tnext = np;
1567 					} else {
1568 						np->n_tnext = tp->n_tnext;
1569 						tp->n_tnext = np;
1570 					}
1571 					np->n_tprev = tp;
1572 					if (np->n_tnext == (struct nfsnode *)nmp)
1573 						nmp->nm_tprev = np;
1574 					else
1575 						np->n_tnext->n_tprev = np;
1576 					cache_enter(ndp->ni_dvp, ndp->ni_vp, cnp);
1577 				}
1578 			} else {
1579 				nfsm_adv(nfsm_rndup(len));
1580 			}
1581 			if (newvp != NULLVP) {
1582 				vrele(newvp);
1583 				newvp = NULLVP;
1584 			}
1585 			nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED);
1586 			if (bigenough)
1587 				endoff = off = fxdr_unsigned(off_t, *tl++);
1588 			else
1589 				endoff = fxdr_unsigned(off_t, *tl++);
1590 			more_dirs = fxdr_unsigned(int, *tl);
1591 		}
1592 		/*
1593 		 * If at end of rpc data, get the eof boolean
1594 		 */
1595 		if (!more_dirs) {
1596 			nfsm_dissect(tl, u_long *, NFSX_UNSIGNED);
1597 			more_dirs = (fxdr_unsigned(int, *tl) == 0);
1598 
1599 			/*
1600 			 * If at EOF, cache directory offset
1601 			 */
1602 			if (!more_dirs)
1603 				VTONFS(vp)->n_direofoffset = endoff;
1604 		}
1605 		if (uiop->uio_resid < tresid)
1606 			uiop->uio_offset = off;
1607 		else
1608 			more_dirs = 0;
1609 		m_freem(mrep);
1610 	}
1611 	/*
1612 	 * Fill last record, iff any, out to a multiple of NFS_DIRBLKSIZ
1613 	 * by increasing d_reclen for the last record.
1614 	 */
1615 	if (uiop->uio_resid < tresid) {
1616 		len = uiop->uio_resid & (NFS_DIRBLKSIZ - 1);
1617 		if (len > 0) {
1618 			dp->d_reclen += len;
1619 			uiop->uio_iov->iov_base += len;
1620 			uiop->uio_iov->iov_len -= len;
1621 			uiop->uio_resid -= len;
1622 		}
1623 	}
1624 nfsmout:
1625 	if (newvp != NULLVP)
1626 		vrele(newvp);
1627 	return (error);
1628 }
1629 static char hextoasc[] = "0123456789abcdef";
1630 
1631 /*
1632  * Silly rename. To make the NFS filesystem that is stateless look a little
1633  * more like the "ufs" a remove of an active vnode is translated to a rename
1634  * to a funny looking filename that is removed by nfs_inactive on the
1635  * nfsnode. There is the potential for another process on a different client
1636  * to create the same funny name between the nfs_lookitup() fails and the
1637  * nfs_rename() completes, but...
1638  */
1639 int
1640 nfs_sillyrename(dvp, vp, cnp)
1641 	struct vnode *dvp, *vp;
1642 	struct componentname *cnp;
1643 {
1644 	register struct nfsnode *np;
1645 	register struct sillyrename *sp;
1646 	int error;
1647 	short pid;
1648 
1649 	cache_purge(dvp);
1650 	np = VTONFS(vp);
1651 #ifdef SILLYSEPARATE
1652 	MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename),
1653 		M_NFSREQ, M_WAITOK);
1654 #else
1655 	sp = &np->n_silly;
1656 #endif
1657 	sp->s_cred = crdup(cnp->cn_cred);
1658 	sp->s_dvp = dvp;
1659 	VREF(dvp);
1660 
1661 	/* Fudge together a funny name */
1662 	pid = cnp->cn_proc->p_pid;
1663 	bcopy(".nfsAxxxx4.4", sp->s_name, 13);
1664 	sp->s_namlen = 12;
1665 	sp->s_name[8] = hextoasc[pid & 0xf];
1666 	sp->s_name[7] = hextoasc[(pid >> 4) & 0xf];
1667 	sp->s_name[6] = hextoasc[(pid >> 8) & 0xf];
1668 	sp->s_name[5] = hextoasc[(pid >> 12) & 0xf];
1669 
1670 	/* Try lookitups until we get one that isn't there */
1671 	while (nfs_lookitup(sp, (nfsv2fh_t *)0, cnp->cn_proc) == 0) {
1672 		sp->s_name[4]++;
1673 		if (sp->s_name[4] > 'z') {
1674 			error = EINVAL;
1675 			goto bad;
1676 		}
1677 	}
1678 	if (error = nfs_renameit(dvp, cnp, sp))
1679 		goto bad;
1680 	nfs_lookitup(sp, &np->n_fh, cnp->cn_proc);
1681 	np->n_sillyrename = sp;
1682 	return (0);
1683 bad:
1684 	vrele(sp->s_dvp);
1685 	crfree(sp->s_cred);
1686 #ifdef SILLYSEPARATE
1687 	free((caddr_t)sp, M_NFSREQ);
1688 #endif
1689 	return (error);
1690 }
1691 
1692 /*
1693  * Look up a file name for silly rename stuff.
1694  * Just like nfs_lookup() except that it doesn't load returned values
1695  * into the nfsnode table.
1696  * If fhp != NULL it copies the returned file handle out
1697  */
1698 int
1699 nfs_lookitup(sp, fhp, procp)
1700 	register struct sillyrename *sp;
1701 	nfsv2fh_t *fhp;
1702 	struct proc *procp;
1703 {
1704 	register struct vnode *vp = sp->s_dvp;
1705 	register u_long *tl;
1706 	register caddr_t cp;
1707 	register long t1, t2;
1708 	caddr_t bpos, dpos, cp2;
1709 	u_long xid;
1710 	int error = 0;
1711 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1712 	long len;
1713 
1714 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
1715 	len = sp->s_namlen;
1716 	nfsm_reqhead(vp, NFSPROC_LOOKUP, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
1717 	nfsm_fhtom(vp);
1718 	nfsm_strtom(sp->s_name, len, NFS_MAXNAMLEN);
1719 	nfsm_request(vp, NFSPROC_LOOKUP, procp, sp->s_cred);
1720 	if (fhp != NULL) {
1721 		nfsm_dissect(cp, caddr_t, NFSX_FH);
1722 		bcopy(cp, (caddr_t)fhp, NFSX_FH);
1723 	}
1724 	nfsm_reqdone;
1725 	return (error);
1726 }
1727 
1728 /*
1729  * Kludge City..
1730  * - make nfs_bmap() essentially a no-op that does no translation
1731  * - do nfs_strategy() by faking physical I/O with nfs_readrpc/nfs_writerpc
1732  *   after mapping the physical addresses into Kernel Virtual space in the
1733  *   nfsiobuf area.
1734  *   (Maybe I could use the process's page mapping, but I was concerned that
1735  *    Kernel Write might not be enabled and also figured copyout() would do
1736  *    a lot more work than bcopy() and also it currently happens in the
1737  *    context of the swapper process (2).
1738  */
1739 int
1740 nfs_bmap (ap)
1741 	struct vop_bmap_args *ap;
1742 {
1743 	if (ap->a_vpp != NULL)
1744 		*ap->a_vpp = ap->a_vp;
1745 	if (ap->a_bnp != NULL)
1746 		*ap->a_bnp = ap->a_bn * btodb(ap->a_vp->v_mount->mnt_stat.f_iosize);
1747 	return (0);
1748 }
1749 
1750 /*
1751  * Strategy routine for phys. i/o
1752  * If the biod's are running, queue a request
1753  * otherwise just call nfs_doio() to get it done
1754  */
1755 int
1756 nfs_strategy (ap)
1757 	struct vop_strategy_args *ap;
1758 {
1759 	register struct buf *dp;
1760 	register int i;
1761 	int error = 0;
1762 	int fnd = 0;
1763 
1764 	/*
1765 	 * Set b_proc. It seems a bit silly to do it here, but since bread()
1766 	 * doesn't set it, I will.
1767 	 * Set b_proc == NULL for asynchronous ops, since these may still
1768 	 * be hanging about after the process terminates.
1769 	 */
1770 	if ((ap->a_bp->b_flags & B_PHYS) == 0) {
1771 		if (ap->a_bp->b_flags & B_ASYNC)
1772 			ap->a_bp->b_proc = (struct proc *)0;
1773 		else
1774 			ap->a_bp->b_proc = curproc;
1775 	}
1776 	/*
1777 	 * If the op is asynchronous and an i/o daemon is waiting
1778 	 * queue the request, wake it up and wait for completion
1779 	 * otherwise just do it ourselves.
1780 	 */
1781 	if ((ap->a_bp->b_flags & B_ASYNC) == 0 || nfs_numasync == 0)
1782 		return (nfs_doio(ap->a_bp));
1783 	for (i = 0; i < NFS_MAXASYNCDAEMON; i++) {
1784 		if (nfs_iodwant[i]) {
1785 			dp = &nfs_bqueue;
1786 			if (dp->b_actf == NULL) {
1787 				dp->b_actl = ap->a_bp;
1788 				ap->a_bp->b_actf = dp;
1789 			} else {
1790 				dp->b_actf->b_actl = ap->a_bp;
1791 				ap->a_bp->b_actf = dp->b_actf;
1792 			}
1793 			dp->b_actf = ap->a_bp;
1794 			ap->a_bp->b_actl = dp;
1795 			fnd++;
1796 			wakeup((caddr_t)&nfs_iodwant[i]);
1797 			break;
1798 		}
1799 	}
1800 	if (!fnd)
1801 		error = nfs_doio(ap->a_bp);
1802 	return (error);
1803 }
1804 
1805 /*
1806  * Fun and games with i/o
1807  * Essentially play ubasetup() and disk interrupt service routine by
1808  * mapping the data buffer into kernel virtual space and doing the
1809  * nfs read or write rpc's from it.
1810  * If the nfsiod's are not running, this is just called from nfs_strategy(),
1811  * otherwise it is called by the nfsiods to do what would normally be
1812  * partially disk interrupt driven.
1813  */
1814 int
1815 nfs_doio(bp)
1816 	register struct buf *bp;
1817 {
1818 	register struct uio *uiop;
1819 	register struct vnode *vp;
1820 	struct nfsnode *np;
1821 	struct ucred *cr;
1822 	int error;
1823 	struct uio uio;
1824 	struct iovec io;
1825 
1826 	vp = bp->b_vp;
1827 	np = VTONFS(vp);
1828 	uiop = &uio;
1829 	uiop->uio_iov = &io;
1830 	uiop->uio_iovcnt = 1;
1831 	uiop->uio_segflg = UIO_SYSSPACE;
1832 	uiop->uio_procp = bp->b_proc;
1833 
1834 	/*
1835 	 * For phys i/o, map the b_addr into kernel virtual space using
1836 	 * the Nfsiomap pte's
1837 	 * Also, add a temporary b_rcred for reading using the process's uid
1838 	 * and a guess at a group
1839 	 */
1840 	if (bp->b_flags & B_PHYS) {
1841 		if (bp->b_flags & B_DIRTY)
1842 			uiop->uio_procp = pageproc;
1843 		cr = crcopy(uiop->uio_procp->p_ucred);
1844 		/* mapping was already done by vmapbuf */
1845 		io.iov_base = bp->b_un.b_addr;
1846 
1847 		/*
1848 		 * And do the i/o rpc
1849 		 */
1850 		io.iov_len = uiop->uio_resid = bp->b_bcount;
1851 		uiop->uio_offset = bp->b_blkno * DEV_BSIZE;
1852 		if (bp->b_flags & B_READ) {
1853 			uiop->uio_rw = UIO_READ;
1854 			nfsstats.read_physios++;
1855 			bp->b_error = error = nfs_readrpc(vp, uiop, cr);
1856 			(void) vnode_pager_uncache(vp);
1857 		} else {
1858 			uiop->uio_rw = UIO_WRITE;
1859 			nfsstats.write_physios++;
1860 			bp->b_error = error = nfs_writerpc(vp, uiop, cr);
1861 		}
1862 
1863 		/*
1864 		 * Finally, release pte's used by physical i/o
1865 		 */
1866 		crfree(cr);
1867 	} else {
1868 		if (bp->b_flags & B_READ) {
1869 			io.iov_len = uiop->uio_resid = bp->b_bcount;
1870 			io.iov_base = bp->b_un.b_addr;
1871 			uiop->uio_rw = UIO_READ;
1872 			switch (vp->v_type) {
1873 			case VREG:
1874 				uiop->uio_offset = bp->b_blkno * DEV_BSIZE;
1875 				nfsstats.read_bios++;
1876 				error = nfs_readrpc(vp, uiop, bp->b_rcred);
1877 				break;
1878 			case VLNK:
1879 				uiop->uio_offset = 0;
1880 				nfsstats.readlink_bios++;
1881 				error = nfs_readlinkrpc(vp, uiop, bp->b_rcred);
1882 				break;
1883 			case VDIR:
1884 				uiop->uio_offset = bp->b_lblkno;
1885 				nfsstats.readdir_bios++;
1886 				if (VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_RDIRALOOK)
1887 				    error = nfs_readdirlookrpc(vp, uiop, bp->b_rcred);
1888 				else
1889 				    error = nfs_readdirrpc(vp, uiop, bp->b_rcred);
1890 				/*
1891 				 * Save offset cookie in b_blkno.
1892 				 */
1893 				bp->b_blkno = uiop->uio_offset;
1894 				break;
1895 			};
1896 			bp->b_error = error;
1897 		} else {
1898 			io.iov_len = uiop->uio_resid = bp->b_dirtyend
1899 				- bp->b_dirtyoff;
1900 			uiop->uio_offset = (bp->b_blkno * DEV_BSIZE)
1901 				+ bp->b_dirtyoff;
1902 			io.iov_base = bp->b_un.b_addr + bp->b_dirtyoff;
1903 			uiop->uio_rw = UIO_WRITE;
1904 			nfsstats.write_bios++;
1905 			bp->b_error = error = nfs_writerpc(vp, uiop,
1906 				bp->b_wcred);
1907 			if (error) {
1908 				np->n_error = error;
1909 				np->n_flag |= NWRITEERR;
1910 			}
1911 			bp->b_dirtyoff = bp->b_dirtyend = 0;
1912 		}
1913 	}
1914 	if (error)
1915 		bp->b_flags |= B_ERROR;
1916 	bp->b_resid = uiop->uio_resid;
1917 	biodone(bp);
1918 	return (error);
1919 }
1920 
1921 /*
1922  * Mmap a file
1923  *
1924  * NB Currently unsupported.
1925  */
1926 /* ARGSUSED */
1927 int
1928 nfs_mmap (ap)
1929 	struct vop_mmap_args *ap;
1930 {
1931 
1932 	return (EINVAL);
1933 }
1934 
1935 /*
1936  * Flush all the blocks associated with a vnode.
1937  * 	Walk through the buffer pool and push any dirty pages
1938  *	associated with the vnode.
1939  */
1940 /* ARGSUSED */
1941 int
1942 nfs_fsync (ap)
1943 	struct vop_fsync_args *ap;
1944 {
1945 	register struct nfsnode *np = VTONFS(ap->a_vp);
1946 	int error = 0;
1947 
1948 	if (np->n_flag & NMODIFIED) {
1949 		np->n_flag &= ~NMODIFIED;
1950 		vflushbuf(ap->a_vp, ap->a_waitfor == MNT_WAIT ? B_SYNC : 0);
1951 	}
1952 	if (np->n_flag & NWRITEERR) {
1953 		error = np->n_error;
1954 		np->n_flag &= ~NWRITEERR;
1955 	}
1956 	return (error);
1957 }
1958 
1959 /*
1960  * NFS advisory byte-level locks.
1961  * Currently unsupported.
1962  */
1963 int
1964 nfs_advlock (ap)
1965 	struct vop_advlock_args *ap;
1966 {
1967 
1968 	return (EOPNOTSUPP);
1969 }
1970 
1971 /*
1972  * Print out the contents of an nfsnode.
1973  */
1974 int
1975 nfs_print (ap)
1976 	struct vop_print_args *ap;
1977 {
1978 	register struct nfsnode *np = VTONFS(ap->a_vp);
1979 
1980 	printf("tag VT_NFS, fileid %d fsid 0x%x",
1981 		np->n_vattr.va_fileid, np->n_vattr.va_fsid);
1982 #ifdef FIFO
1983 	if (ap->a_vp->v_type == VFIFO)
1984 		fifo_printinfo(ap->a_vp);
1985 #endif /* FIFO */
1986 	printf("\n");
1987 }
1988 
1989 /*
1990  * NFS directory offset lookup.
1991  * Currently unsupported.
1992  */
1993 int
1994 nfs_blkatoff (ap)
1995 	struct vop_blkatoff_args *ap;
1996 {
1997 
1998 	return (EOPNOTSUPP);
1999 }
2000 
2001 /*
2002  * NFS flat namespace lookup.
2003  * Currently unsupported.
2004  */
2005 int
2006 nfs_vget (ap)
2007 	struct vop_vget_args *ap;
2008 {
2009 
2010 	return (EOPNOTSUPP);
2011 }
2012 
2013 /*
2014  * NFS flat namespace allocation.
2015  * Currently unsupported.
2016  */
2017 int
2018 nfs_valloc (ap)
2019 	struct vop_valloc_args *ap;
2020 {
2021 
2022 	return (EOPNOTSUPP);
2023 }
2024 
2025 /*
2026  * NFS flat namespace free.
2027  * Currently unsupported.
2028  */
2029 int
2030 nfs_vfree (ap)
2031 	struct vop_vfree_args *ap;
2032 {
2033 
2034 	return (EOPNOTSUPP);
2035 }
2036 
2037 /*
2038  * NFS file truncation.
2039  */
2040 int
2041 nfs_truncate (ap)
2042 	struct vop_truncate_args *ap;
2043 {
2044 
2045 	/* Use nfs_setattr */
2046 	printf("nfs_truncate: need to implement!!");
2047 	return (EOPNOTSUPP);
2048 }
2049 
2050 /*
2051  * NFS update.
2052  */
2053 int
2054 nfs_update (ap)
2055 	struct vop_update_args *ap;
2056 {
2057 
2058 	/* Use nfs_setattr */
2059 	printf("nfs_update: need to implement!!");
2060 	return (EOPNOTSUPP);
2061 }
2062 
2063 /*
2064  * Read wrapper for special devices.
2065  */
2066 int
2067 nfsspec_read(ap)
2068 	struct vop_read_args *ap;
2069 {
2070 	extern int (**spec_vnodeop_p)();
2071 
2072 	/*
2073 	 * Set access flag.
2074 	 */
2075 	VTONFS(ap->a_vp)->n_flag |= NACC;
2076 	return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap));
2077 }
2078 
2079 /*
2080  * Write wrapper for special devices.
2081  */
2082 int
2083 nfsspec_write(ap)
2084 	struct vop_write_args *ap;
2085 {
2086 	extern int (**spec_vnodeop_p)();
2087 
2088 	/*
2089 	 * Set update flags.
2090 	 */
2091 	VTONFS(ap->a_vp)->n_flag |= NUPD;
2092 	return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap));
2093 }
2094 
2095 /*
2096  * Close wrapper for special devices.
2097  *
2098  * Update the times on the nfsnode then do device close.
2099  */
2100 int
2101 nfsspec_close(ap)
2102 	struct vop_close_args *ap;
2103 {
2104 	USES_VOP_SETATTR;
2105 	register struct nfsnode *np = VTONFS(ap->a_vp);
2106 	struct vattr vattr;
2107 	extern int (**spec_vnodeop_p)();
2108 
2109 	if (np->n_flag & (NACC | NUPD)) {
2110 		if (np->n_flag & NACC)
2111 			np->n_atim = time;
2112 		if (np->n_flag & NUPD)
2113 			np->n_mtim = time;
2114 		np->n_flag |= NCHG;
2115 		if (ap->a_vp->v_usecount == 1 &&
2116 		    (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
2117 			VATTR_NULL(&vattr);
2118 			if (np->n_flag & NACC)
2119 				vattr.va_atime = np->n_atim;
2120 			if (np->n_flag & NUPD)
2121 				vattr.va_mtime = np->n_mtim;
2122 			(void)VOP_SETATTR(ap->a_vp, &vattr, ap->a_cred,
2123 			    ap->a_p);
2124 		}
2125 	}
2126 	return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap));
2127 }
2128 
2129 #ifdef FIFO
2130 /*
2131  * Read wrapper for fifos.
2132  */
2133 int
2134 nfsfifo_read(ap)
2135 	struct vop_read_args *ap;
2136 {
2137 	extern int (**fifo_vnodeop_p)();
2138 
2139 	/*
2140 	 * Set access flag.
2141 	 */
2142 	VTONFS(ap->a_vp)->n_flag |= NACC;
2143 	return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap));
2144 }
2145 
2146 /*
2147  * Write wrapper for fifos.
2148  */
2149 int
2150 nfsfifo_write(ap)
2151 	struct vop_write_args *ap;
2152 {
2153 	extern int (**fifo_vnodeop_p)();
2154 
2155 	/*
2156 	 * Set update flag.
2157 	 */
2158 	VTONFS(ap->a_vp)->n_flag |= NUPD;
2159 	return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap));
2160 }
2161 
2162 /*
2163  * Close wrapper for fifos.
2164  *
2165  * Update the times on the nfsnode then do fifo close.
2166  */
2167 int
2168 nfsfifo_close(ap)
2169 	struct vop_close_args *ap;
2170 {
2171 	USES_VOP_SETATTR;
2172 	register struct nfsnode *np = VTONFS(ap->a_vp);
2173 	struct vattr vattr;
2174 	extern int (**fifo_vnodeop_p)();
2175 
2176 	if (np->n_flag & (NACC | NUPD)) {
2177 		if (np->n_flag & NACC)
2178 			np->n_atim = time;
2179 		if (np->n_flag & NUPD)
2180 			np->n_mtim = time;
2181 		np->n_flag |= NCHG;
2182 		if (ap->a_vp->v_usecount == 1 &&
2183 		    (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
2184 			VATTR_NULL(&vattr);
2185 			if (np->n_flag & NACC)
2186 				vattr.va_atime = np->n_atim;
2187 			if (np->n_flag & NUPD)
2188 				vattr.va_mtime = np->n_mtim;
2189 			(void)VOP_SETATTR(ap->a_vp, &vattr, ap->a_cred,
2190 			    ap->a_p);
2191 		}
2192 	}
2193 	return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap));
2194 }
2195 #endif /* FIFO */
2196