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