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