xref: /original-bsd/sys/nfs/nfs_vnops.c (revision e59fb703)
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.64 (Berkeley) 12/16/91
11  */
12 
13 /*
14  * vnode op calls for sun nfs version 2
15  */
16 
17 #include "param.h"
18 #include "proc.h"
19 #include "kernel.h"
20 #include "systm.h"
21 #include "mount.h"
22 #include "buf.h"
23 #include "malloc.h"
24 #include "mbuf.h"
25 #include "conf.h"
26 #include "namei.h"
27 #include "vnode.h"
28 #include "specdev.h"
29 #include "fifo.h"
30 #include "map.h"
31 
32 #include "ufs/ufs/quota.h"
33 #include "ufs/ufs/inode.h"
34 #include "ufs/ufs/dir.h"
35 
36 #include "nfsv2.h"
37 #include "nfs.h"
38 #include "nfsnode.h"
39 #include "nfsmount.h"
40 #include "xdr_subs.h"
41 #include "nfsm_subs.h"
42 #include "nfsiom.h"
43 
44 /* Defs */
45 #define	TRUE	1
46 #define	FALSE	0
47 
48 /*
49  * Global vfs data structures for nfs
50  */
51 struct vnodeops nfsv2_vnodeops = {
52 	nfs_lookup,		/* lookup */
53 	nfs_create,		/* create */
54 	nfs_mknod,		/* mknod */
55 	nfs_open,		/* open */
56 	nfs_close,		/* close */
57 	nfs_access,		/* access */
58 	nfs_getattr,		/* getattr */
59 	nfs_setattr,		/* setattr */
60 	nfs_read,		/* read */
61 	nfs_write,		/* write */
62 	nfs_ioctl,		/* ioctl */
63 	nfs_select,		/* select */
64 	nfs_mmap,		/* mmap */
65 	nfs_fsync,		/* fsync */
66 	nfs_seek,		/* seek */
67 	nfs_remove,		/* remove */
68 	nfs_link,		/* link */
69 	nfs_rename,		/* rename */
70 	nfs_mkdir,		/* mkdir */
71 	nfs_rmdir,		/* rmdir */
72 	nfs_symlink,		/* symlink */
73 	nfs_readdir,		/* readdir */
74 	nfs_readlink,		/* readlink */
75 	nfs_abortop,		/* abortop */
76 	nfs_inactive,		/* inactive */
77 	nfs_reclaim,		/* reclaim */
78 	nfs_lock,		/* lock */
79 	nfs_unlock,		/* unlock */
80 	nfs_bmap,		/* bmap */
81 	nfs_strategy,		/* strategy */
82 	nfs_print,		/* print */
83 	nfs_islocked,		/* islocked */
84 	nfs_advlock,		/* advlock */
85 	nfs_blkatoff,		/* blkatoff */
86 	nfs_vget,		/* vget */
87 	nfs_valloc,		/* valloc */
88 	nfs_vfree,		/* vfree */
89 	nfs_truncate,		/* truncate */
90 	nfs_update,		/* update */
91 	bwrite,			/* bwrite */
92 };
93 
94 /*
95  * Special device vnode ops
96  */
97 struct vnodeops spec_nfsv2nodeops = {
98 	spec_lookup,		/* lookup */
99 	spec_create,		/* create */
100 	spec_mknod,		/* mknod */
101 	spec_open,		/* open */
102 	spec_close,		/* close */
103 	nfs_access,		/* access */
104 	nfs_getattr,		/* getattr */
105 	nfs_setattr,		/* setattr */
106 	spec_read,		/* read */
107 	spec_write,		/* write */
108 	spec_ioctl,		/* ioctl */
109 	spec_select,		/* select */
110 	spec_mmap,		/* mmap */
111 	spec_fsync,		/* fsync */
112 	spec_seek,		/* seek */
113 	spec_remove,		/* remove */
114 	spec_link,		/* link */
115 	spec_rename,		/* rename */
116 	spec_mkdir,		/* mkdir */
117 	spec_rmdir,		/* rmdir */
118 	spec_symlink,		/* symlink */
119 	spec_readdir,		/* readdir */
120 	spec_readlink,		/* readlink */
121 	spec_abortop,		/* abortop */
122 	nfs_inactive,		/* inactive */
123 	nfs_reclaim,		/* reclaim */
124 	nfs_lock,		/* lock */
125 	nfs_unlock,		/* unlock */
126 	spec_bmap,		/* bmap */
127 	spec_strategy,		/* strategy */
128 	nfs_print,		/* print */
129 	nfs_islocked,		/* islocked */
130 	spec_advlock,		/* advlock */
131 	spec_blkatoff,		/* blkatoff */
132 	spec_vget,		/* vget */
133 	spec_valloc,		/* valloc */
134 	spec_vfree,		/* vfree */
135 	spec_truncate,		/* truncate */
136 	nfs_update,		/* update */
137 	bwrite,			/* bwrite */
138 };
139 
140 #ifdef FIFO
141 struct vnodeops fifo_nfsv2nodeops = {
142 	fifo_lookup,		/* lookup */
143 	fifo_create,		/* create */
144 	fifo_mknod,		/* mknod */
145 	fifo_open,		/* open */
146 	fifo_close,		/* close */
147 	nfs_access,		/* access */
148 	nfs_getattr,		/* getattr */
149 	nfs_setattr,		/* setattr */
150 	fifo_read,		/* read */
151 	fifo_write,		/* write */
152 	fifo_ioctl,		/* ioctl */
153 	fifo_select,		/* select */
154 	fifo_mmap,		/* mmap */
155 	fifo_fsync,		/* fsync */
156 	fifo_seek,		/* seek */
157 	fifo_remove,		/* remove */
158 	fifo_link,		/* link */
159 	fifo_rename,		/* rename */
160 	fifo_mkdir,		/* mkdir */
161 	fifo_rmdir,		/* rmdir */
162 	fifo_symlink,		/* symlink */
163 	fifo_readdir,		/* readdir */
164 	fifo_readlink,		/* readlink */
165 	fifo_abortop,		/* abortop */
166 	nfs_inactive,		/* inactive */
167 	nfs_reclaim,		/* reclaim */
168 	nfs_lock,		/* lock */
169 	nfs_unlock,		/* unlock */
170 	fifo_bmap,		/* bmap */
171 	fifo_badop,		/* strategy */
172 	nfs_print,		/* print */
173 	nfs_islocked,		/* islocked */
174 	fifo_advlock,		/* advlock */
175 	fifo_blkatoff,		/* blkatoff */
176 	fifo_vget,		/* vget */
177 	fifo_valloc,		/* valloc */
178 	fifo_vfree,		/* vfree */
179 	fifo_truncate,		/* truncate */
180 	nfs_update,		/* update */
181 	bwrite,			/* bwrite */
182 };
183 #endif /* FIFO */
184 
185 /*
186  * Global vars
187  */
188 extern u_long nfs_procids[NFS_NPROCS];
189 extern u_long nfs_prog, nfs_vers;
190 extern char nfsiobuf[MAXPHYS+NBPG];
191 struct map nfsmap[NFS_MSIZ];
192 struct buf nfs_bqueue;		/* Queue head for nfsiod's */
193 struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON];
194 int nfs_numasync = 0;
195 static int nfsmap_want = 0;
196 
197 /*
198  * nfs null call from vfs.
199  */
200 nfs_null(vp, cred, p)
201 	struct vnode *vp;
202 	struct ucred *cred;
203 	struct proc *p;
204 {
205 	caddr_t bpos, dpos;
206 	u_long xid;
207 	int error = 0;
208 	struct mbuf *mreq, *mrep, *md, *mb;
209 
210 	nfsm_reqhead(nfs_procids[NFSPROC_NULL], cred, 0);
211 	nfsm_request(vp, NFSPROC_NULL, p, 0);
212 	nfsm_reqdone;
213 	return (error);
214 }
215 
216 /*
217  * nfs access vnode op.
218  * Essentially just get vattr and then imitate iaccess()
219  */
220 nfs_access(vp, mode, cred, p)
221 	struct vnode *vp;
222 	int mode;
223 	register struct ucred *cred;
224 	struct proc *p;
225 {
226 	register struct vattr *vap;
227 	register gid_t *gp;
228 	struct vattr vattr;
229 	register int i;
230 	int error;
231 
232 	/*
233 	 * If you're the super-user,
234 	 * you always get access.
235 	 */
236 	if (cred->cr_uid == 0)
237 		return (0);
238 	vap = &vattr;
239 	if (error = nfs_dogetattr(vp, vap, cred, 0, p))
240 		return (error);
241 	/*
242 	 * Access check is based on only one of owner, group, public.
243 	 * If not owner, then check group. If not a member of the
244 	 * group, then check public access.
245 	 */
246 	if (cred->cr_uid != vap->va_uid) {
247 		mode >>= 3;
248 		gp = cred->cr_groups;
249 		for (i = 0; i < cred->cr_ngroups; i++, gp++)
250 			if (vap->va_gid == *gp)
251 				goto found;
252 		mode >>= 3;
253 found:
254 		;
255 	}
256 	if ((vap->va_mode & mode) != 0)
257 		return (0);
258 	return (EACCES);
259 }
260 
261 /*
262  * nfs open vnode op
263  * Just check to see if the type is ok
264  */
265 /* ARGSUSED */
266 nfs_open(vp, mode, cred, p)
267 	struct vnode *vp;
268 	int mode;
269 	struct ucred *cred;
270 	struct proc *p;
271 {
272 	register enum vtype vtyp;
273 
274 	vtyp = vp->v_type;
275 	if (vtyp == VREG || vtyp == VDIR || vtyp == VLNK)
276 		return (0);
277 	else
278 		return (EACCES);
279 }
280 
281 /*
282  * nfs close vnode op
283  * For reg files, invalidate any buffer cache entries.
284  */
285 /* ARGSUSED */
286 nfs_close(vp, fflags, cred, p)
287 	register struct vnode *vp;
288 	int fflags;
289 	struct ucred *cred;
290 	struct proc *p;
291 {
292 	register struct nfsnode *np = VTONFS(vp);
293 	int error = 0;
294 
295 	if (vp->v_type == VREG && (np->n_flag & NMODIFIED)) {
296 		nfs_lock(vp);
297 		np->n_flag &= ~NMODIFIED;
298 		vinvalbuf(vp, TRUE);
299 		np->n_attrstamp = 0;
300 		if (np->n_flag & NWRITEERR) {
301 			np->n_flag &= ~NWRITEERR;
302 			error = np->n_error;
303 		}
304 		nfs_unlock(vp);
305 	}
306 	return (error);
307 }
308 
309 /*
310  * nfs getattr call from vfs.
311  */
312 nfs_getattr(vp, vap, cred, p)
313 	register struct vnode *vp;
314 	struct vattr *vap;
315 	struct ucred *cred;
316 	struct proc *p;
317 {
318 	return (nfs_dogetattr(vp, vap, cred, 0, p));
319 }
320 
321 nfs_dogetattr(vp, vap, cred, tryhard, p)
322 	register struct vnode *vp;
323 	struct vattr *vap;
324 	struct ucred *cred;
325 	int tryhard;
326 	struct proc *p;
327 {
328 	register caddr_t cp;
329 	register long t1;
330 	caddr_t bpos, dpos;
331 	u_long xid;
332 	int error = 0;
333 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
334 
335 	/* First look in the cache.. */
336 	if (nfs_getattrcache(vp, vap) == 0)
337 		return (0);
338 	nfsstats.rpccnt[NFSPROC_GETATTR]++;
339 	nfsm_reqhead(nfs_procids[NFSPROC_GETATTR], cred, NFSX_FH);
340 	nfsm_fhtom(vp);
341 	nfsm_request(vp, NFSPROC_GETATTR, p, tryhard);
342 	nfsm_loadattr(vp, vap);
343 	nfsm_reqdone;
344 	return (error);
345 }
346 
347 /*
348  * nfs setattr call.
349  */
350 nfs_setattr(vp, vap, cred, p)
351 	register struct vnode *vp;
352 	register struct vattr *vap;
353 	struct ucred *cred;
354 	struct proc *p;
355 {
356 	register struct nfsv2_sattr *sp;
357 	register caddr_t cp;
358 	register long t1;
359 	caddr_t bpos, dpos;
360 	u_long xid;
361 	int error = 0;
362 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
363 	struct nfsnode *np;
364 
365 	nfsstats.rpccnt[NFSPROC_SETATTR]++;
366 	nfsm_reqhead(nfs_procids[NFSPROC_SETATTR], cred, NFSX_FH+NFSX_SATTR);
367 	nfsm_fhtom(vp);
368 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
369 	if (vap->va_mode == 0xffff)
370 		sp->sa_mode = VNOVAL;
371 	else
372 		sp->sa_mode = vtonfs_mode(vp->v_type, vap->va_mode);
373 	if (vap->va_uid == 0xffff)
374 		sp->sa_uid = VNOVAL;
375 	else
376 		sp->sa_uid = txdr_unsigned(vap->va_uid);
377 	if (vap->va_gid == 0xffff)
378 		sp->sa_gid = VNOVAL;
379 	else
380 		sp->sa_gid = txdr_unsigned(vap->va_gid);
381 	sp->sa_size = txdr_unsigned(vap->va_size);
382 	sp->sa_atime.tv_sec = txdr_unsigned(vap->va_atime.tv_sec);
383 	sp->sa_atime.tv_usec = txdr_unsigned(vap->va_flags);
384 	txdr_time(&vap->va_mtime, &sp->sa_mtime);
385 	if (vap->va_size != VNOVAL || vap->va_mtime.tv_sec != VNOVAL ||
386 	    vap->va_atime.tv_sec != VNOVAL) {
387 		np = VTONFS(vp);
388 		if (np->n_flag & NMODIFIED) {
389 			np->n_flag &= ~NMODIFIED;
390 			if (vap->va_size == 0)
391 				vinvalbuf(vp, FALSE);
392 			else
393 				vinvalbuf(vp, TRUE);
394 			np->n_attrstamp = 0;
395 		}
396 	}
397 	nfsm_request(vp, NFSPROC_SETATTR, p, 1);
398 	nfsm_loadattr(vp, (struct vattr *)0);
399 	/* should we fill in any vap fields ?? */
400 	nfsm_reqdone;
401 	return (error);
402 }
403 
404 /*
405  * nfs lookup call, one step at a time...
406  * First look in cache
407  * If not found, unlock the directory nfsnode and do the rpc
408  */
409 nfs_lookup(vp, ndp, p)
410 	register struct vnode *vp;
411 	register struct nameidata *ndp;
412 	struct proc *p;
413 {
414 	register struct vnode *vdp;
415 	register u_long *tl;
416 	register caddr_t cp;
417 	register long t1, t2;
418 	caddr_t bpos, dpos, cp2;
419 	u_long xid;
420 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
421 	struct vnode *newvp;
422 	long len;
423 	nfsv2fh_t *fhp;
424 	struct nfsnode *np;
425 	int lockparent, wantparent, flag, error = 0;
426 
427 	ndp->ni_dvp = vp;
428 	ndp->ni_vp = NULL;
429 	if (vp->v_type != VDIR)
430 		return (ENOTDIR);
431 	lockparent = ndp->ni_nameiop & LOCKPARENT;
432 	flag = ndp->ni_nameiop & OPMASK;
433 	wantparent = ndp->ni_nameiop & (LOCKPARENT|WANTPARENT);
434 	if ((error = cache_lookup(ndp)) && error != ENOENT) {
435 		struct vattr vattr;
436 		int vpid;
437 
438 		vdp = ndp->ni_vp;
439 		vpid = vdp->v_id;
440 		/*
441 		 * See the comment starting `Step through' in ufs/ufs_lookup.c
442 		 * for an explanation of the locking protocol
443 		 */
444 		if (vp == vdp) {
445 			VREF(vdp);
446 			error = 0;
447 		} else if (ndp->ni_isdotdot) {
448 			nfs_unlock(vp);
449 			error = vget(vdp);
450 			if (!error && lockparent && *ndp->ni_next == '\0')
451 				nfs_lock(vp);
452 		} else {
453 			error = vget(vdp);
454 			if (!lockparent || error || *ndp->ni_next != '\0')
455 				nfs_unlock(vp);
456 		}
457 		if (!error) {
458 			if (vpid == vdp->v_id) {
459 			   if (!nfs_dogetattr(vdp, &vattr, ndp->ni_cred, 0, p)&&
460 			       vattr.va_ctime.tv_sec == VTONFS(vdp)->n_ctime) {
461 				nfsstats.lookupcache_hits++;
462 				if (flag != LOOKUP && *ndp->ni_next == 0)
463 					ndp->ni_nameiop |= SAVENAME;
464 				return (0);
465 			   }
466 			   cache_purge(vdp);
467 			}
468 			nfs_nput(vdp);
469 			if (lockparent && vdp != vp && *ndp->ni_next == '\0')
470 				nfs_unlock(vp);
471 		}
472 		ndp->ni_vp = NULLVP;
473 	} else
474 		nfs_unlock(vp);
475 	error = 0;
476 	nfsstats.lookupcache_misses++;
477 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
478 	len = ndp->ni_namelen;
479 	nfsm_reqhead(nfs_procids[NFSPROC_LOOKUP], ndp->ni_cred, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
480 	nfsm_fhtom(vp);
481 	nfsm_strtom(ndp->ni_ptr, len, NFS_MAXNAMLEN);
482 	nfsm_request(vp, NFSPROC_LOOKUP, p, 0);
483 nfsmout:
484 	if (error) {
485 		if (lockparent || (flag != CREATE && flag != RENAME) ||
486 		    *ndp->ni_next != 0)
487 			nfs_lock(vp);
488 		if (flag != LOOKUP && *ndp->ni_next == 0)
489 			ndp->ni_nameiop |= SAVENAME;
490 		return (error);
491 	}
492 	nfsm_disect(fhp,nfsv2fh_t *,NFSX_FH);
493 
494 	/*
495 	 * Handle DELETE and RENAME cases...
496 	 */
497 	if (flag == DELETE && *ndp->ni_next == 0) {
498 		if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) {
499 			VREF(vp);
500 			newvp = vp;
501 			np = VTONFS(vp);
502 		} else {
503 			if (error = nfs_nget(vp->v_mount, fhp, &np)) {
504 				nfs_lock(vp);
505 				m_freem(mrep);
506 				return (error);
507 			}
508 			newvp = NFSTOV(np);
509 		}
510 		if (error =
511 		    nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) {
512 			nfs_lock(vp);
513 			if (newvp != vp)
514 				nfs_nput(newvp);
515 			else
516 				vrele(vp);
517 			m_freem(mrep);
518 			return (error);
519 		}
520 		ndp->ni_vp = newvp;
521 		if (lockparent || vp == newvp)
522 			nfs_lock(vp);
523 		m_freem(mrep);
524 		ndp->ni_nameiop |= SAVENAME;
525 		return (0);
526 	}
527 
528 	if (flag == RENAME && wantparent && *ndp->ni_next == 0) {
529 		if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) {
530 			nfs_lock(vp);
531 			m_freem(mrep);
532 			return (EISDIR);
533 		}
534 		if (error = nfs_nget(vp->v_mount, fhp, &np)) {
535 			nfs_lock(vp);
536 			m_freem(mrep);
537 			return (error);
538 		}
539 		newvp = NFSTOV(np);
540 		if (error =
541 		    nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) {
542 			nfs_lock(vp);
543 			nfs_nput(newvp);
544 			m_freem(mrep);
545 			return (error);
546 		}
547 		ndp->ni_vp = newvp;
548 		if (lockparent)
549 			nfs_lock(vp);
550 		m_freem(mrep);
551 		ndp->ni_nameiop |= SAVENAME;
552 		return (0);
553 	}
554 
555 	if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) {
556 		VREF(vp);
557 		newvp = vp;
558 		np = VTONFS(vp);
559 	} else if (ndp->ni_isdotdot) {
560 		if (error = nfs_nget(vp->v_mount, fhp, &np)) {
561 			nfs_lock(vp);
562 			m_freem(mrep);
563 			return (error);
564 		}
565 		newvp = NFSTOV(np);
566 	} else {
567 		if (error = nfs_nget(vp->v_mount, fhp, &np)) {
568 			nfs_lock(vp);
569 			m_freem(mrep);
570 			return (error);
571 		}
572 		newvp = NFSTOV(np);
573 	}
574 	if (error = nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) {
575 		nfs_lock(vp);
576 		if (newvp != vp)
577 			nfs_nput(newvp);
578 		else
579 			vrele(vp);
580 		m_freem(mrep);
581 		return (error);
582 	}
583 	m_freem(mrep);
584 
585 	if (vp == newvp || (lockparent && *ndp->ni_next == '\0'))
586 		nfs_lock(vp);
587 	ndp->ni_vp = newvp;
588 	if (flag != LOOKUP && *ndp->ni_next == 0)
589 		ndp->ni_nameiop |= SAVENAME;
590 	if (error == 0 && ndp->ni_makeentry) {
591 		np->n_ctime = np->n_vattr.va_ctime.tv_sec;
592 		cache_enter(ndp);
593 	}
594 	return (error);
595 }
596 
597 /*
598  * nfs read call.
599  * Just call nfs_bioread() to do the work.
600  */
601 nfs_read(vp, uiop, ioflag, cred)
602 	register struct vnode *vp;
603 	struct uio *uiop;
604 	int ioflag;
605 	struct ucred *cred;
606 {
607 	if (vp->v_type != VREG)
608 		return (EPERM);
609 	return (nfs_bioread(vp, uiop, ioflag, cred));
610 }
611 
612 /*
613  * nfs readlink call
614  */
615 nfs_readlink(vp, uiop, cred)
616 	struct vnode *vp;
617 	struct uio *uiop;
618 	struct ucred *cred;
619 {
620 	if (vp->v_type != VLNK)
621 		return (EPERM);
622 	return (nfs_bioread(vp, uiop, 0, cred));
623 }
624 
625 /*
626  * Do a readlink rpc.
627  * Called by nfs_doio() from below the buffer cache.
628  */
629 nfs_readlinkrpc(vp, uiop, cred)
630 	register struct vnode *vp;
631 	struct uio *uiop;
632 	struct ucred *cred;
633 {
634 	register u_long *tl;
635 	register caddr_t cp;
636 	register long t1;
637 	caddr_t bpos, dpos, cp2;
638 	u_long xid;
639 	int error = 0;
640 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
641 	long len;
642 
643 	nfsstats.rpccnt[NFSPROC_READLINK]++;
644 	nfsm_reqhead(nfs_procids[NFSPROC_READLINK], cred, NFSX_FH);
645 	nfsm_fhtom(vp);
646 	nfsm_request(vp, NFSPROC_READLINK, uiop->uio_procp, 0);
647 	nfsm_strsiz(len, NFS_MAXPATHLEN);
648 	nfsm_mtouio(uiop, len);
649 	nfsm_reqdone;
650 	return (error);
651 }
652 
653 /*
654  * nfs read rpc call
655  * Ditto above
656  */
657 nfs_readrpc(vp, uiop, cred)
658 	register struct vnode *vp;
659 	struct uio *uiop;
660 	struct ucred *cred;
661 {
662 	register u_long *tl;
663 	register caddr_t cp;
664 	register long t1;
665 	caddr_t bpos, dpos, cp2;
666 	u_long xid;
667 	int error = 0;
668 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
669 	struct nfsmount *nmp;
670 	long len, retlen, tsiz;
671 
672 	nmp = VFSTONFS(vp->v_mount);
673 	tsiz = uiop->uio_resid;
674 	while (tsiz > 0) {
675 		nfsstats.rpccnt[NFSPROC_READ]++;
676 		len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
677 		nfsm_reqhead(nfs_procids[NFSPROC_READ], cred, NFSX_FH+NFSX_UNSIGNED*3);
678 		nfsm_fhtom(vp);
679 		nfsm_build(tl, u_long *, NFSX_UNSIGNED*3);
680 		*tl++ = txdr_unsigned(uiop->uio_offset);
681 		*tl++ = txdr_unsigned(len);
682 		*tl = 0;
683 		nfsm_request(vp, NFSPROC_READ, uiop->uio_procp, 1);
684 		nfsm_loadattr(vp, (struct vattr *)0);
685 		nfsm_strsiz(retlen, nmp->nm_rsize);
686 		nfsm_mtouio(uiop, retlen);
687 		m_freem(mrep);
688 		if (retlen < len)
689 			tsiz = 0;
690 		else
691 			tsiz -= len;
692 	}
693 nfsmout:
694 	return (error);
695 }
696 
697 /*
698  * nfs write call
699  */
700 nfs_writerpc(vp, uiop, cred)
701 	register struct vnode *vp;
702 	struct uio *uiop;
703 	struct ucred *cred;
704 {
705 	register u_long *tl;
706 	register caddr_t cp;
707 	register long t1;
708 	caddr_t bpos, dpos;
709 	u_long xid;
710 	int error = 0;
711 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
712 	struct nfsmount *nmp;
713 	long len, tsiz;
714 
715 	nmp = VFSTONFS(vp->v_mount);
716 	tsiz = uiop->uio_resid;
717 	while (tsiz > 0) {
718 		nfsstats.rpccnt[NFSPROC_WRITE]++;
719 		len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz;
720 		nfsm_reqhead(nfs_procids[NFSPROC_WRITE], cred,
721 			NFSX_FH+NFSX_UNSIGNED*4);
722 		nfsm_fhtom(vp);
723 		nfsm_build(tl, u_long *, NFSX_UNSIGNED*4);
724 		*(tl+1) = txdr_unsigned(uiop->uio_offset);
725 		*(tl+3) = txdr_unsigned(len);
726 		nfsm_uiotom(uiop, len);
727 		nfsm_request(vp, NFSPROC_WRITE, uiop->uio_procp, 1);
728 		nfsm_loadattr(vp, (struct vattr *)0);
729 		m_freem(mrep);
730 		tsiz -= len;
731 	}
732 nfsmout:
733 	return (error);
734 }
735 
736 /*
737  * nfs mknod call
738  * This is a kludge. Use a create rpc but with the IFMT bits of the mode
739  * set to specify the file type and the size field for rdev.
740  */
741 /* ARGSUSED */
742 nfs_mknod(ndp, vap, cred, p)
743 	struct nameidata *ndp;
744 	struct ucred *cred;
745 	register struct vattr *vap;
746 	struct proc *p;
747 {
748 	register struct nfsv2_sattr *sp;
749 	register u_long *tl;
750 	register caddr_t cp;
751 	register long t1, t2;
752 	caddr_t bpos, dpos;
753 	u_long xid;
754 	int error = 0;
755 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
756 	u_long rdev;
757 
758 	if (vap->va_type == VCHR || vap->va_type == VBLK)
759 		rdev = txdr_unsigned(vap->va_rdev);
760 #ifdef FIFO
761 	else if (vap->va_type == VFIFO)
762 		rdev = 0xffffffff;
763 #endif /* FIFO */
764 	else {
765 		VOP_ABORTOP(ndp);
766 		vput(ndp->ni_dvp);
767 		return (EOPNOTSUPP);
768 	}
769 	nfsstats.rpccnt[NFSPROC_CREATE]++;
770 	nfsm_reqhead(nfs_procids[NFSPROC_CREATE], ndp->ni_cred,
771 	  NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen)+NFSX_SATTR);
772 	nfsm_fhtom(ndp->ni_dvp);
773 	nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
774 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
775 	sp->sa_mode = vtonfs_mode(vap->va_type, vap->va_mode);
776 	sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
777 	sp->sa_gid = txdr_unsigned(ndp->ni_cred->cr_gid);
778 	sp->sa_size = rdev;
779 	/* or should these be VNOVAL ?? */
780 	txdr_time(&vap->va_atime, &sp->sa_atime);
781 	txdr_time(&vap->va_mtime, &sp->sa_mtime);
782 	nfsm_request(ndp->ni_dvp, NFSPROC_CREATE, p, 1);
783 	nfsm_reqdone;
784 	FREE(ndp->ni_pnbuf, M_NAMEI);
785 	VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
786 	nfs_nput(ndp->ni_dvp);
787 	return (error);
788 }
789 
790 /*
791  * nfs file create call
792  */
793 nfs_create(ndp, vap, p)
794 	register struct nameidata *ndp;
795 	register struct vattr *vap;
796 	struct proc *p;
797 {
798 	register struct nfsv2_sattr *sp;
799 	register u_long *tl;
800 	register caddr_t cp;
801 	register long t1, t2;
802 	caddr_t bpos, dpos, cp2;
803 	u_long xid;
804 	int error = 0;
805 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
806 
807 	nfsstats.rpccnt[NFSPROC_CREATE]++;
808 	nfsm_reqhead(nfs_procids[NFSPROC_CREATE], ndp->ni_cred,
809 	  NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen)+NFSX_SATTR);
810 	nfsm_fhtom(ndp->ni_dvp);
811 	nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
812 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
813 	sp->sa_mode = vtonfs_mode(vap->va_type, vap->va_mode);
814 	sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
815 	sp->sa_gid = txdr_unsigned(ndp->ni_cred->cr_gid);
816 	sp->sa_size = txdr_unsigned(0);
817 	/* or should these be VNOVAL ?? */
818 	txdr_time(&vap->va_atime, &sp->sa_atime);
819 	txdr_time(&vap->va_mtime, &sp->sa_mtime);
820 	nfsm_request(ndp->ni_dvp, NFSPROC_CREATE, p, 1);
821 	nfsm_mtofh(ndp->ni_dvp, ndp->ni_vp);
822 	nfsm_reqdone;
823 	FREE(ndp->ni_pnbuf, M_NAMEI);
824 	VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
825 	nfs_nput(ndp->ni_dvp);
826 	return (error);
827 }
828 
829 /*
830  * nfs file remove call
831  * To try and make nfs semantics closer to ufs semantics, a file that has
832  * other processes using the vnode is renamed instead of removed and then
833  * removed later on the last close.
834  * - If v_usecount > 1
835  *	  If a rename is not already in the works
836  *	     call nfs_sillyrename() to set it up
837  *     else
838  *	  do the remove rpc
839  */
840 nfs_remove(ndp, p)
841 	register struct nameidata *ndp;
842 	struct proc *p;
843 {
844 	register struct vnode *vp = ndp->ni_vp;
845 	register struct nfsnode *np = VTONFS(ndp->ni_vp);
846 	register u_long *tl;
847 	register caddr_t cp;
848 	register long t1, t2;
849 	caddr_t bpos, dpos;
850 	u_long xid;
851 	int error = 0;
852 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
853 
854 	if (vp->v_usecount > 1) {
855 		if (!np->n_sillyrename)
856 			error = nfs_sillyrename(ndp, p);
857 	} else {
858 		nfsstats.rpccnt[NFSPROC_REMOVE]++;
859 		nfsm_reqhead(nfs_procids[NFSPROC_REMOVE], ndp->ni_cred,
860 			NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen));
861 		nfsm_fhtom(ndp->ni_dvp);
862 		nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
863 		nfsm_request(ndp->ni_dvp, NFSPROC_REMOVE, p, 1);
864 		nfsm_reqdone;
865 		FREE(ndp->ni_pnbuf, M_NAMEI);
866 		VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
867 		/*
868 		 * Kludge City: If the first reply to the remove rpc is lost..
869 		 *   the reply to the retransmitted request will be ENOENT
870 		 *   since the file was in fact removed
871 		 *   Therefore, we cheat and return success.
872 		 */
873 		if (error == ENOENT)
874 			error = 0;
875 	}
876 	np->n_attrstamp = 0;
877 	if (ndp->ni_dvp == vp)
878 		vrele(vp);
879 	else
880 		nfs_nput(ndp->ni_dvp);
881 	nfs_nput(vp);
882 	return (error);
883 }
884 
885 /*
886  * nfs file remove rpc called from nfs_inactive
887  */
888 nfs_removeit(sp, p)
889 	register struct sillyrename *sp;
890 	struct proc *p;
891 {
892 	register u_long *tl;
893 	register caddr_t cp;
894 	register long t1, t2;
895 	caddr_t bpos, dpos;
896 	u_long xid;
897 	int error = 0;
898 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
899 
900 	nfsstats.rpccnt[NFSPROC_REMOVE]++;
901 	nfsm_reqhead(nfs_procids[NFSPROC_REMOVE], sp->s_cred,
902 		NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(sp->s_namlen));
903 	nfsm_fhtom(sp->s_dvp);
904 	nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN);
905 	nfsm_request(sp->s_dvp, NFSPROC_REMOVE, p, 1);
906 	nfsm_reqdone;
907 	VTONFS(sp->s_dvp)->n_flag |= NMODIFIED;
908 	return (error);
909 }
910 
911 /*
912  * nfs file rename call
913  */
914 nfs_rename(sndp, tndp, p)
915 	register struct nameidata *sndp, *tndp;
916 	struct proc *p;
917 {
918 	register u_long *tl;
919 	register caddr_t cp;
920 	register long t1, t2;
921 	caddr_t bpos, dpos;
922 	u_long xid;
923 	int error = 0;
924 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
925 
926 	nfsstats.rpccnt[NFSPROC_RENAME]++;
927 	nfsm_reqhead(nfs_procids[NFSPROC_RENAME], tndp->ni_cred,
928 		(NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(sndp->ni_namelen) +
929 		nfsm_rndup(tndp->ni_namelen)); /* or sndp->ni_cred?*/
930 	nfsm_fhtom(sndp->ni_dvp);
931 	nfsm_strtom(sndp->ni_ptr, sndp->ni_namelen, NFS_MAXNAMLEN);
932 	nfsm_fhtom(tndp->ni_dvp);
933 	nfsm_strtom(tndp->ni_ptr, tndp->ni_namelen, NFS_MAXNAMLEN);
934 	nfsm_request(sndp->ni_dvp, NFSPROC_RENAME, p, 1);
935 	nfsm_reqdone;
936 	VTONFS(sndp->ni_dvp)->n_flag |= NMODIFIED;
937 	VTONFS(tndp->ni_dvp)->n_flag |= NMODIFIED;
938 	if (sndp->ni_vp->v_type == VDIR) {
939 		if (tndp->ni_vp != NULL && tndp->ni_vp->v_type == VDIR)
940 			cache_purge(tndp->ni_dvp);
941 		cache_purge(sndp->ni_dvp);
942 	}
943 	if (tndp->ni_dvp == tndp->ni_vp)
944 		vrele(tndp->ni_dvp);
945 	else
946 		vput(tndp->ni_dvp);
947 	if (tndp->ni_vp)
948 		vput(tndp->ni_vp);
949 	vrele(sndp->ni_dvp);
950 	vrele(sndp->ni_vp);
951 	/*
952 	 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
953 	 */
954 	if (error == ENOENT)
955 		error = 0;
956 	return (error);
957 }
958 
959 /*
960  * nfs file rename rpc called from nfs_remove() above
961  */
962 nfs_renameit(sndp, sp, p)
963 	register struct nameidata *sndp;
964 	register struct sillyrename *sp;
965 	struct proc *p;
966 {
967 	register u_long *tl;
968 	register caddr_t cp;
969 	register long t1, t2;
970 	caddr_t bpos, dpos;
971 	u_long xid;
972 	int error = 0;
973 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
974 
975 	nfsstats.rpccnt[NFSPROC_RENAME]++;
976 	nfsm_reqhead(nfs_procids[NFSPROC_RENAME], sp->s_cred,
977 		(NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(sndp->ni_namelen) +
978 		nfsm_rndup(sp->s_namlen)); /* or sndp->ni_cred?*/
979 	nfsm_fhtom(sndp->ni_dvp);
980 	nfsm_strtom(sndp->ni_ptr, sndp->ni_namelen, NFS_MAXNAMLEN);
981 	nfsm_fhtom(sp->s_dvp);
982 	nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN);
983 	nfsm_request(sndp->ni_dvp, NFSPROC_RENAME, p, 1);
984 	nfsm_reqdone;
985 	FREE(sndp->ni_pnbuf, M_NAMEI);
986 	VTONFS(sndp->ni_dvp)->n_flag |= NMODIFIED;
987 	VTONFS(sp->s_dvp)->n_flag |= NMODIFIED;
988 	return (error);
989 }
990 
991 /*
992  * nfs hard link create call
993  */
994 nfs_link(vp, ndp, p)
995 	register struct vnode *vp;
996 	register struct nameidata *ndp;
997 	struct proc *p;
998 {
999 	register u_long *tl;
1000 	register caddr_t cp;
1001 	register long t1, t2;
1002 	caddr_t bpos, dpos;
1003 	u_long xid;
1004 	int error = 0;
1005 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1006 
1007 	if (ndp->ni_dvp != vp)
1008 		nfs_lock(vp);
1009 	nfsstats.rpccnt[NFSPROC_LINK]++;
1010 	nfsm_reqhead(nfs_procids[NFSPROC_LINK], ndp->ni_cred,
1011 		NFSX_FH*2+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen));
1012 	nfsm_fhtom(vp);
1013 	nfsm_fhtom(ndp->ni_dvp);
1014 	nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
1015 	nfsm_request(vp, NFSPROC_LINK, p, 1);
1016 	nfsm_reqdone;
1017 	FREE(ndp->ni_pnbuf, M_NAMEI);
1018 	VTONFS(vp)->n_attrstamp = 0;
1019 	VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
1020 	if (ndp->ni_dvp != vp)
1021 		nfs_unlock(vp);
1022 	nfs_nput(ndp->ni_dvp);
1023 	/*
1024 	 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
1025 	 */
1026 	if (error == EEXIST)
1027 		error = 0;
1028 	return (error);
1029 }
1030 
1031 /*
1032  * nfs symbolic link create call
1033  */
1034 nfs_symlink(ndp, vap, nm, p)
1035 	struct nameidata *ndp;
1036 	struct vattr *vap;
1037 	char *nm;		/* is this the path ?? */
1038 	struct proc *p;
1039 {
1040 	register struct nfsv2_sattr *sp;
1041 	register u_long *tl;
1042 	register caddr_t cp;
1043 	register long t1, t2;
1044 	caddr_t bpos, dpos;
1045 	u_long xid;
1046 	int error = 0;
1047 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1048 
1049 	nfsstats.rpccnt[NFSPROC_SYMLINK]++;
1050 	nfsm_reqhead(nfs_procids[NFSPROC_SYMLINK], ndp->ni_cred,
1051 	NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen)+NFSX_UNSIGNED);
1052 	nfsm_fhtom(ndp->ni_dvp);
1053 	nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
1054 	nfsm_strtom(nm, strlen(nm), NFS_MAXPATHLEN);
1055 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
1056 	sp->sa_mode = vtonfs_mode(VLNK, vap->va_mode);
1057 	sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
1058 	sp->sa_gid = txdr_unsigned(ndp->ni_cred->cr_gid);
1059 	sp->sa_size = txdr_unsigned(VNOVAL);
1060 	txdr_time(&vap->va_atime, &sp->sa_atime);	/* or VNOVAL ?? */
1061 	txdr_time(&vap->va_mtime, &sp->sa_mtime);	/* or VNOVAL ?? */
1062 	nfsm_request(ndp->ni_dvp, NFSPROC_SYMLINK, p, 1);
1063 	nfsm_reqdone;
1064 	FREE(ndp->ni_pnbuf, M_NAMEI);
1065 	VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
1066 	nfs_nput(ndp->ni_dvp);
1067 	/*
1068 	 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
1069 	 */
1070 	if (error == EEXIST)
1071 		error = 0;
1072 	return (error);
1073 }
1074 
1075 /*
1076  * nfs make dir call
1077  */
1078 nfs_mkdir(ndp, vap, p)
1079 	register struct nameidata *ndp;
1080 	struct vattr *vap;
1081 	struct proc *p;
1082 {
1083 	register struct nfsv2_sattr *sp;
1084 	register u_long *tl;
1085 	register caddr_t cp;
1086 	register long t1, t2;
1087 	register int len;
1088 	caddr_t bpos, dpos, cp2;
1089 	u_long xid;
1090 	int error = 0, firsttry = 1;
1091 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1092 
1093 	len = ndp->ni_namelen;
1094 	nfsstats.rpccnt[NFSPROC_MKDIR]++;
1095 	nfsm_reqhead(nfs_procids[NFSPROC_MKDIR], ndp->ni_cred,
1096 	  NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)+NFSX_SATTR);
1097 	nfsm_fhtom(ndp->ni_dvp);
1098 	nfsm_strtom(ndp->ni_ptr, len, NFS_MAXNAMLEN);
1099 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
1100 	sp->sa_mode = vtonfs_mode(VDIR, vap->va_mode);
1101 	sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
1102 	sp->sa_gid = txdr_unsigned(ndp->ni_cred->cr_gid);
1103 	sp->sa_size = txdr_unsigned(VNOVAL);
1104 	txdr_time(&vap->va_atime, &sp->sa_atime);	/* or VNOVAL ?? */
1105 	txdr_time(&vap->va_mtime, &sp->sa_mtime);	/* or VNOVAL ?? */
1106 	nfsm_request(ndp->ni_dvp, NFSPROC_MKDIR, p, 1);
1107 	nfsm_mtofh(ndp->ni_dvp, ndp->ni_vp);
1108 	nfsm_reqdone;
1109 	VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
1110 	/*
1111 	 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry
1112 	 * if we can succeed in looking up the directory.
1113 	 * "firsttry" is necessary since the macros may "goto nfsmout" which
1114 	 * is above the if on errors. (Ugh)
1115 	 */
1116 	if (error == EEXIST && firsttry) {
1117 		firsttry = 0;
1118 		error = 0;
1119 		nfsstats.rpccnt[NFSPROC_LOOKUP]++;
1120 		ndp->ni_vp = NULL;
1121 		nfsm_reqhead(nfs_procids[NFSPROC_LOOKUP], ndp->ni_cred,
1122 		    NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
1123 		nfsm_fhtom(ndp->ni_dvp);
1124 		nfsm_strtom(ndp->ni_ptr, len, NFS_MAXNAMLEN);
1125 		nfsm_request(ndp->ni_dvp, NFSPROC_LOOKUP, p, 1);
1126 		nfsm_mtofh(ndp->ni_dvp, ndp->ni_vp);
1127 		if (ndp->ni_vp->v_type != VDIR) {
1128 			vput(ndp->ni_vp);
1129 			error = EEXIST;
1130 		}
1131 		m_freem(mrep);
1132 	}
1133 	FREE(ndp->ni_pnbuf, M_NAMEI);
1134 	nfs_nput(ndp->ni_dvp);
1135 	return (error);
1136 }
1137 
1138 /*
1139  * nfs remove directory call
1140  */
1141 nfs_rmdir(ndp, p)
1142 	register struct nameidata *ndp;
1143 	struct proc *p;
1144 {
1145 	register u_long *tl;
1146 	register caddr_t cp;
1147 	register long t1, t2;
1148 	caddr_t bpos, dpos;
1149 	u_long xid;
1150 	int error = 0;
1151 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1152 
1153 	if (ndp->ni_dvp == ndp->ni_vp) {
1154 		vrele(ndp->ni_dvp);
1155 		nfs_nput(ndp->ni_dvp);
1156 		return (EINVAL);
1157 	}
1158 	nfsstats.rpccnt[NFSPROC_RMDIR]++;
1159 	nfsm_reqhead(nfs_procids[NFSPROC_RMDIR], ndp->ni_cred,
1160 		NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen));
1161 	nfsm_fhtom(ndp->ni_dvp);
1162 	nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
1163 	nfsm_request(ndp->ni_dvp, NFSPROC_RMDIR, p, 1);
1164 	nfsm_reqdone;
1165 	FREE(ndp->ni_pnbuf, M_NAMEI);
1166 	VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
1167 	cache_purge(ndp->ni_dvp);
1168 	cache_purge(ndp->ni_vp);
1169 	nfs_nput(ndp->ni_vp);
1170 	nfs_nput(ndp->ni_dvp);
1171 	/*
1172 	 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
1173 	 */
1174 	if (error == ENOENT)
1175 		error = 0;
1176 	return (error);
1177 }
1178 
1179 /*
1180  * nfs readdir call
1181  * Although cookie is defined as opaque, I translate it to/from net byte
1182  * order so that it looks more sensible. This appears consistent with the
1183  * Ultrix implementation of NFS.
1184  */
1185 nfs_readdir(vp, uiop, cred, eofflagp)
1186 	register struct vnode *vp;
1187 	struct uio *uiop;
1188 	struct ucred *cred;
1189 	int *eofflagp;
1190 {
1191 	register struct nfsnode *np = VTONFS(vp);
1192 	int tresid, error;
1193 	struct vattr vattr;
1194 
1195 	if (vp->v_type != VDIR)
1196 		return (EPERM);
1197 	/*
1198 	 * First, check for hit on the EOF offset cache
1199 	 */
1200 	if (uiop->uio_offset != 0 && uiop->uio_offset == np->n_direofoffset &&
1201 	    (np->n_flag & NMODIFIED) == 0 &&
1202 	    nfs_dogetattr(vp, &vattr, cred, 0, uiop->uio_procp) == 0 &&
1203 	    np->n_mtime == vattr.va_mtime.tv_sec) {
1204 		*eofflagp = 1;
1205 		nfsstats.direofcache_hits++;
1206 		return (0);
1207 	}
1208 
1209 	/*
1210 	 * Call nfs_bioread() to do the real work.
1211 	 */
1212 	tresid = uiop->uio_resid;
1213 	error = nfs_bioread(vp, uiop, 0, cred);
1214 
1215 	if (!error && uiop->uio_resid == tresid) {
1216 		*eofflagp = 1;
1217 		nfsstats.direofcache_misses++;
1218 	} else
1219 		*eofflagp = 0;
1220 	return (error);
1221 }
1222 
1223 /*
1224  * Readdir rpc call.
1225  * Called from below the buffer cache by nfs_doio().
1226  */
1227 nfs_readdirrpc(vp, uiop, cred)
1228 	register struct vnode *vp;
1229 	struct uio *uiop;
1230 	struct ucred *cred;
1231 {
1232 	register long len;
1233 	register struct direct *dp;
1234 	register u_long *tl;
1235 	register caddr_t cp;
1236 	register long t1;
1237 	long tlen, lastlen;
1238 	caddr_t bpos, dpos, cp2;
1239 	u_long xid;
1240 	int error = 0;
1241 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1242 	struct mbuf *md2;
1243 	caddr_t dpos2;
1244 	int siz;
1245 	int more_dirs = 1;
1246 	off_t off, savoff;
1247 	struct direct *savdp;
1248 	struct nfsmount *nmp;
1249 	struct nfsnode *np = VTONFS(vp);
1250 	long tresid;
1251 
1252 	nmp = VFSTONFS(vp->v_mount);
1253 	tresid = uiop->uio_resid;
1254 	/*
1255 	 * Loop around doing readdir rpc's of size uio_resid or nm_rsize,
1256 	 * whichever is smaller, truncated to a multiple of NFS_DIRBLKSIZ.
1257 	 * The stopping criteria is EOF or buffer full.
1258 	 */
1259 	while (more_dirs && uiop->uio_resid >= NFS_DIRBLKSIZ) {
1260 		nfsstats.rpccnt[NFSPROC_READDIR]++;
1261 		nfsm_reqhead(nfs_procids[NFSPROC_READDIR], cred, xid);
1262 		nfsm_fhtom(vp);
1263 		nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED);
1264 		*tl++ = txdr_unsigned(uiop->uio_offset);
1265 		*tl = txdr_unsigned(((uiop->uio_resid > nmp->nm_rsize) ?
1266 			nmp->nm_rsize : uiop->uio_resid) & ~(NFS_DIRBLKSIZ-1));
1267 		nfsm_request(vp, NFSPROC_READDIR, uiop->uio_procp, 0);
1268 		siz = 0;
1269 		nfsm_disect(tl, u_long *, NFSX_UNSIGNED);
1270 		more_dirs = fxdr_unsigned(int, *tl);
1271 
1272 		/* Save the position so that we can do nfsm_mtouio() later */
1273 		dpos2 = dpos;
1274 		md2 = md;
1275 
1276 		/* loop thru the dir entries, doctoring them to 4bsd form */
1277 		off = uiop->uio_offset;
1278 #ifdef lint
1279 		dp = (struct direct *)0;
1280 #endif /* lint */
1281 		while (more_dirs && siz < uiop->uio_resid) {
1282 			savoff = off;		/* Hold onto offset and dp */
1283 			savdp = dp;
1284 			nfsm_disecton(tl, u_long *, 2*NFSX_UNSIGNED);
1285 			dp = (struct direct *)tl;
1286 			dp->d_ino = fxdr_unsigned(u_long, *tl++);
1287 			len = fxdr_unsigned(int, *tl);
1288 			if (len <= 0 || len > NFS_MAXNAMLEN) {
1289 				error = EBADRPC;
1290 				m_freem(mrep);
1291 				goto nfsmout;
1292 			}
1293 			dp->d_namlen = (u_short)len;
1294 			nfsm_adv(len);		/* Point past name */
1295 			tlen = nfsm_rndup(len);
1296 			/*
1297 			 * This should not be necessary, but some servers have
1298 			 * broken XDR such that these bytes are not null filled.
1299 			 */
1300 			if (tlen != len) {
1301 				*dpos = '\0';	/* Null-terminate */
1302 				nfsm_adv(tlen - len);
1303 				len = tlen;
1304 			}
1305 			nfsm_disecton(tl, u_long *, 2*NFSX_UNSIGNED);
1306 			off = fxdr_unsigned(off_t, *tl);
1307 			*tl++ = 0;	/* Ensures null termination of name */
1308 			more_dirs = fxdr_unsigned(int, *tl);
1309 			dp->d_reclen = len+4*NFSX_UNSIGNED;
1310 			siz += dp->d_reclen;
1311 		}
1312 		/*
1313 		 * If at end of rpc data, get the eof boolean
1314 		 */
1315 		if (!more_dirs) {
1316 			nfsm_disecton(tl, u_long *, NFSX_UNSIGNED);
1317 			more_dirs = (fxdr_unsigned(int, *tl) == 0);
1318 
1319 			/*
1320 			 * If at EOF, cache directory offset
1321 			 */
1322 			if (!more_dirs)
1323 				np->n_direofoffset = off;
1324 		}
1325 		/*
1326 		 * If there is too much to fit in the data buffer, use savoff and
1327 		 * savdp to trim off the last record.
1328 		 * --> we are not at eof
1329 		 */
1330 		if (siz > uiop->uio_resid) {
1331 			off = savoff;
1332 			siz -= dp->d_reclen;
1333 			dp = savdp;
1334 			more_dirs = 0;	/* Paranoia */
1335 		}
1336 		if (siz > 0) {
1337 			lastlen = dp->d_reclen;
1338 			md = md2;
1339 			dpos = dpos2;
1340 			nfsm_mtouio(uiop, siz);
1341 			uiop->uio_offset = off;
1342 		} else
1343 			more_dirs = 0;	/* Ugh, never happens, but in case.. */
1344 		m_freem(mrep);
1345 	}
1346 	/*
1347 	 * Fill last record, iff any, out to a multiple of NFS_DIRBLKSIZ
1348 	 * by increasing d_reclen for the last record.
1349 	 */
1350 	if (uiop->uio_resid < tresid) {
1351 		len = uiop->uio_resid & (NFS_DIRBLKSIZ - 1);
1352 		if (len > 0) {
1353 			dp = (struct direct *)
1354 				(uiop->uio_iov->iov_base - lastlen);
1355 			dp->d_reclen += len;
1356 			uiop->uio_iov->iov_base += len;
1357 			uiop->uio_iov->iov_len -= len;
1358 			uiop->uio_resid -= len;
1359 		}
1360 	}
1361 nfsmout:
1362 	return (error);
1363 }
1364 
1365 static char hextoasc[] = "0123456789abcdef";
1366 
1367 /*
1368  * Silly rename. To make the NFS filesystem that is stateless look a little
1369  * more like the "ufs" a remove of an active vnode is translated to a rename
1370  * to a funny looking filename that is removed by nfs_inactive on the
1371  * nfsnode. There is the potential for another process on a different client
1372  * to create the same funny name between the nfs_lookitup() fails and the
1373  * nfs_rename() completes, but...
1374  */
1375 nfs_sillyrename(ndp, p)
1376 	register struct nameidata *ndp;
1377 	struct proc *p;
1378 {
1379 	register struct nfsnode *np;
1380 	register struct sillyrename *sp;
1381 	int error;
1382 	short pid;
1383 
1384 	np = VTONFS(ndp->ni_dvp);
1385 	cache_purge(ndp->ni_dvp);
1386 #ifdef SILLYSEPARATE
1387 	MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename),
1388 		M_NFSREQ, M_WAITOK);
1389 #else
1390 	sp = &np->n_silly;
1391 #endif
1392 	bcopy((caddr_t)&np->n_fh, (caddr_t)&sp->s_fh, NFSX_FH);
1393 	np = VTONFS(ndp->ni_vp);
1394 	sp->s_cred = crdup(ndp->ni_cred);
1395 	sp->s_dvp = ndp->ni_dvp;
1396 	VREF(sp->s_dvp);
1397 
1398 	/* Fudge together a funny name */
1399 	pid = p->p_pid;
1400 	bcopy(".nfsAxxxx4.4", sp->s_name, 13);
1401 	sp->s_namlen = 12;
1402 	sp->s_name[8] = hextoasc[pid & 0xf];
1403 	sp->s_name[7] = hextoasc[(pid >> 4) & 0xf];
1404 	sp->s_name[6] = hextoasc[(pid >> 8) & 0xf];
1405 	sp->s_name[5] = hextoasc[(pid >> 12) & 0xf];
1406 
1407 	/* Try lookitups until we get one that isn't there */
1408 	while (nfs_lookitup(sp, (nfsv2fh_t *)0, p) == 0) {
1409 		sp->s_name[4]++;
1410 		if (sp->s_name[4] > 'z') {
1411 			error = EINVAL;
1412 			goto bad;
1413 		}
1414 	}
1415 	if (error = nfs_renameit(ndp, sp, p))
1416 		goto bad;
1417 	nfs_lookitup(sp, &np->n_fh, p);
1418 	np->n_sillyrename = sp;
1419 	return (0);
1420 bad:
1421 	vrele(sp->s_dvp);
1422 	crfree(sp->s_cred);
1423 #ifdef SILLYSEPARATE
1424 	free((caddr_t)sp, M_NFSREQ);
1425 #endif
1426 	return (error);
1427 }
1428 
1429 /*
1430  * Look up a file name for silly rename stuff.
1431  * Just like nfs_lookup() except that it doesn't load returned values
1432  * into the nfsnode table.
1433  * If fhp != NULL it copies the returned file handle out
1434  */
1435 nfs_lookitup(sp, fhp, p)
1436 	register struct sillyrename *sp;
1437 	nfsv2fh_t *fhp;
1438 	struct proc *p;
1439 {
1440 	register struct vnode *vp = sp->s_dvp;
1441 	register u_long *tl;
1442 	register caddr_t cp;
1443 	register long t1, t2;
1444 	caddr_t bpos, dpos, cp2;
1445 	u_long xid;
1446 	int error = 0;
1447 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1448 	long len;
1449 
1450 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
1451 	len = sp->s_namlen;
1452 	nfsm_reqhead(nfs_procids[NFSPROC_LOOKUP], sp->s_cred, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
1453 	nfsm_fhtom(vp);
1454 	nfsm_strtom(sp->s_name, len, NFS_MAXNAMLEN);
1455 	nfsm_request(vp, NFSPROC_LOOKUP, p, 1);
1456 	if (fhp != NULL) {
1457 		nfsm_disect(cp, caddr_t, NFSX_FH);
1458 		bcopy(cp, (caddr_t)fhp, NFSX_FH);
1459 	}
1460 	nfsm_reqdone;
1461 	return (error);
1462 }
1463 
1464 /*
1465  * Kludge City..
1466  * - make nfs_bmap() essentially a no-op that does no translation
1467  * - do nfs_strategy() by faking physical I/O with nfs_readrpc/nfs_writerpc
1468  *   after mapping the physical addresses into Kernel Virtual space in the
1469  *   nfsiobuf area.
1470  *   (Maybe I could use the process's page mapping, but I was concerned that
1471  *    Kernel Write might not be enabled and also figured copyout() would do
1472  *    a lot more work than bcopy() and also it currently happens in the
1473  *    context of the swapper process (2).
1474  */
1475 nfs_bmap(vp, bn, vpp, bnp)
1476 	struct vnode *vp;
1477 	daddr_t bn;
1478 	struct vnode **vpp;
1479 	daddr_t *bnp;
1480 {
1481 	if (vpp != NULL)
1482 		*vpp = vp;
1483 	if (bnp != NULL)
1484 		*bnp = bn * btodb(vp->v_mount->mnt_stat.f_bsize);
1485 	return (0);
1486 }
1487 
1488 /*
1489  * Strategy routine for phys. i/o
1490  * If the biod's are running, queue a request
1491  * otherwise just call nfs_doio() to get it done
1492  */
1493 nfs_strategy(bp)
1494 	register struct buf *bp;
1495 {
1496 	register struct buf *dp;
1497 	register int i;
1498 	int error = 0;
1499 	int fnd = 0;
1500 
1501 	/*
1502 	 * Set b_proc. It seems a bit silly to do it here, but since bread()
1503 	 * doesn't set it, I will.
1504 	 * Set b_proc == NULL for asynchronous ops, since these may still
1505 	 * be hanging about after the process terminates.
1506 	 */
1507 	if ((bp->b_flags & B_PHYS) == 0) {
1508 		if (bp->b_flags & B_ASYNC)
1509 			bp->b_proc = (struct proc *)0;
1510 		else
1511 			bp->b_proc = curproc;
1512 	}
1513 	/*
1514 	 * If the op is asynchronous and an i/o daemon is waiting
1515 	 * queue the request, wake it up and wait for completion
1516 	 * otherwise just do it ourselves.
1517 	 */
1518 	if ((bp->b_flags & B_ASYNC) == 0 || nfs_numasync == 0)
1519 		return (nfs_doio(bp));
1520 	for (i = 0; i < NFS_MAXASYNCDAEMON; i++) {
1521 		if (nfs_iodwant[i]) {
1522 			dp = &nfs_bqueue;
1523 			if (dp->b_actf == NULL) {
1524 				dp->b_actl = bp;
1525 				bp->b_actf = dp;
1526 			} else {
1527 				dp->b_actf->b_actl = bp;
1528 				bp->b_actf = dp->b_actf;
1529 			}
1530 			dp->b_actf = bp;
1531 			bp->b_actl = dp;
1532 			fnd++;
1533 			wakeup((caddr_t)&nfs_iodwant[i]);
1534 			break;
1535 		}
1536 	}
1537 	if (!fnd)
1538 		error = nfs_doio(bp);
1539 	return (error);
1540 }
1541 
1542 /*
1543  * Fun and games with i/o
1544  * Essentially play ubasetup() and disk interrupt service routine by
1545  * mapping the data buffer into kernel virtual space and doing the
1546  * nfs read or write rpc's from it.
1547  * If the nfsiod's are not running, this is just called from nfs_strategy(),
1548  * otherwise it is called by the nfsiods to do what would normally be
1549  * partially disk interrupt driven.
1550  */
1551 nfs_doio(bp)
1552 	register struct buf *bp;
1553 {
1554 	register struct uio *uiop;
1555 	register struct vnode *vp;
1556 	struct nfsnode *np;
1557 	struct ucred *cr;
1558 	int error;
1559 	struct uio uio;
1560 	struct iovec io;
1561 
1562 	vp = bp->b_vp;
1563 	np = VTONFS(vp);
1564 	uiop = &uio;
1565 	uiop->uio_iov = &io;
1566 	uiop->uio_iovcnt = 1;
1567 	uiop->uio_segflg = UIO_SYSSPACE;
1568 	uiop->uio_procp = (struct proc *)0;
1569 
1570 	/*
1571 	 * For phys i/o, map the b_addr into kernel virtual space using
1572 	 * the Nfsiomap pte's
1573 	 * Also, add a temporary b_rcred for reading using the process's uid
1574 	 * and a guess at a group
1575 	 */
1576 	if (bp->b_flags & B_PHYS) {
1577 		if (bp->b_flags & B_DIRTY)
1578 			uiop->uio_procp = pageproc;
1579 		cr = crcopy(uiop->uio_procp->p_ucred);
1580 		/* mapping was already done by vmapbuf */
1581 		io.iov_base = bp->b_un.b_addr;
1582 
1583 		/*
1584 		 * And do the i/o rpc
1585 		 */
1586 		io.iov_len = uiop->uio_resid = bp->b_bcount;
1587 		uiop->uio_offset = bp->b_blkno * DEV_BSIZE;
1588 		if (bp->b_flags & B_READ) {
1589 			uiop->uio_rw = UIO_READ;
1590 			nfsstats.read_physios++;
1591 			bp->b_error = error = nfs_readrpc(vp, uiop, cr);
1592 			(void) vnode_pager_uncache(vp);
1593 		} else {
1594 			uiop->uio_rw = UIO_WRITE;
1595 			nfsstats.write_physios++;
1596 			bp->b_error = error = nfs_writerpc(vp, uiop, cr);
1597 		}
1598 
1599 		/*
1600 		 * Finally, release pte's used by physical i/o
1601 		 */
1602 		crfree(cr);
1603 	} else {
1604 		if (bp->b_flags & B_READ) {
1605 			io.iov_len = uiop->uio_resid = bp->b_bcount;
1606 			io.iov_base = bp->b_un.b_addr;
1607 			uiop->uio_rw = UIO_READ;
1608 			switch (vp->v_type) {
1609 			case VREG:
1610 				uiop->uio_offset = bp->b_blkno * DEV_BSIZE;
1611 				nfsstats.read_bios++;
1612 				error = nfs_readrpc(vp, uiop, bp->b_rcred);
1613 				break;
1614 			case VLNK:
1615 				uiop->uio_offset = 0;
1616 				nfsstats.readlink_bios++;
1617 				error = nfs_readlinkrpc(vp, uiop, bp->b_rcred);
1618 				break;
1619 			case VDIR:
1620 				uiop->uio_offset = bp->b_lblkno;
1621 				nfsstats.readdir_bios++;
1622 				error = nfs_readdirrpc(vp, uiop, bp->b_rcred);
1623 				/*
1624 				 * Save offset cookie in b_blkno.
1625 				 */
1626 				bp->b_blkno = uiop->uio_offset;
1627 				break;
1628 			};
1629 			bp->b_error = error;
1630 		} else {
1631 			io.iov_len = uiop->uio_resid = bp->b_dirtyend
1632 				- bp->b_dirtyoff;
1633 			uiop->uio_offset = (bp->b_blkno * DEV_BSIZE)
1634 				+ bp->b_dirtyoff;
1635 			io.iov_base = bp->b_un.b_addr + bp->b_dirtyoff;
1636 			uiop->uio_rw = UIO_WRITE;
1637 			nfsstats.write_bios++;
1638 			bp->b_error = error = nfs_writerpc(vp, uiop,
1639 				bp->b_wcred);
1640 			if (error) {
1641 				np->n_error = error;
1642 				np->n_flag |= NWRITEERR;
1643 			}
1644 			bp->b_dirtyoff = bp->b_dirtyend = 0;
1645 		}
1646 	}
1647 	if (error)
1648 		bp->b_flags |= B_ERROR;
1649 	bp->b_resid = uiop->uio_resid;
1650 	biodone(bp);
1651 	return (error);
1652 }
1653 
1654 /*
1655  * Mmap a file
1656  *
1657  * NB Currently unsupported.
1658  */
1659 /* ARGSUSED */
1660 nfs_mmap(vp, fflags, cred, p)
1661 	struct vnode *vp;
1662 	int fflags;
1663 	struct ucred *cred;
1664 	struct proc *p;
1665 {
1666 
1667 	return (EINVAL);
1668 }
1669 
1670 /*
1671  * Flush all the blocks associated with a vnode.
1672  * 	Walk through the buffer pool and push any dirty pages
1673  *	associated with the vnode.
1674  */
1675 /* ARGSUSED */
1676 nfs_fsync(vp, fflags, cred, waitfor, p)
1677 	register struct vnode *vp;
1678 	int fflags;
1679 	struct ucred *cred;
1680 	int waitfor;
1681 	struct proc *p;
1682 {
1683 	register struct nfsnode *np = VTONFS(vp);
1684 	int error = 0;
1685 
1686 	if (np->n_flag & NMODIFIED) {
1687 		np->n_flag &= ~NMODIFIED;
1688 		vflushbuf(vp, waitfor == MNT_WAIT ? B_SYNC : 0);
1689 	}
1690 	if (!error && (np->n_flag & NWRITEERR))
1691 		error = np->n_error;
1692 	return (error);
1693 }
1694 
1695 /*
1696  * NFS advisory byte-level locks.
1697  * Currently unsupported.
1698  */
1699 nfs_advlock(vp, id, op, fl, flags)
1700 	struct vnode *vp;
1701 	caddr_t id;
1702 	int op;
1703 	struct flock *fl;
1704 	int flags;
1705 {
1706 
1707 	return (EOPNOTSUPP);
1708 }
1709 
1710 /*
1711  * Print out the contents of an nfsnode.
1712  */
1713 nfs_print(vp)
1714 	struct vnode *vp;
1715 {
1716 	register struct nfsnode *np = VTONFS(vp);
1717 
1718 	printf("tag VT_NFS, fileid %d fsid 0x%x",
1719 		np->n_vattr.va_fileid, np->n_vattr.va_fsid);
1720 #ifdef FIFO
1721 	if (vp->v_type == VFIFO)
1722 		fifo_printinfo(vp);
1723 #endif /* FIFO */
1724 	printf("%s\n", (np->n_flag & NLOCKED) ? " (LOCKED)" : "");
1725 	if (np->n_lockholder == 0)
1726 		return;
1727 	printf("\towner pid %d", np->n_lockholder);
1728 	if (np->n_lockwaiter)
1729 		printf(" waiting pid %d", np->n_lockwaiter);
1730 	printf("\n");
1731 }
1732 
1733 /*
1734  * NFS directory offset lookup.
1735  * Currently unsupported.
1736  */
1737 nfs_blkatoff(vp, offset, res, bpp)
1738 	struct vnode *vp;
1739 	off_t offset;
1740 	char **res;
1741 	struct buf **bpp;
1742 {
1743 
1744 	return (EOPNOTSUPP);
1745 }
1746 
1747 /*
1748  * NFS flat namespace lookup.
1749  * Currently unsupported.
1750  */
1751 nfs_vget(mp, ino, vpp)
1752 	struct mount *mp;
1753 	ino_t ino;
1754 	struct vnode **vpp;
1755 {
1756 
1757 	return (EOPNOTSUPP);
1758 }
1759 
1760 /*
1761  * NFS flat namespace allocation.
1762  * Currently unsupported.
1763  */
1764 nfs_valloc(pvp, mode, cred, vpp)
1765 	struct vnode *pvp;
1766 	int mode;
1767 	struct ucred *cred;
1768 	struct vnode **vpp;
1769 {
1770 
1771 	return (EOPNOTSUPP);
1772 }
1773 
1774 /*
1775  * NFS flat namespace free.
1776  * Currently unsupported.
1777  */
1778 void
1779 nfs_vfree(pvp, ino, mode)
1780 	struct vnode *pvp;
1781 	ino_t ino;
1782 	int mode;
1783 {
1784 
1785 	return;
1786 }
1787 
1788 /*
1789  * NFS file truncation.
1790  */
1791 nfs_truncate(vp, length, flags)
1792 	struct vnode *vp;
1793 	u_long length;
1794 	int flags;
1795 {
1796 
1797 	/* Use nfs_setattr */
1798 	printf("nfs_truncate: need to implement!!");
1799 	return (EOPNOTSUPP);
1800 }
1801 
1802 /*
1803  * NFS update.
1804  */
1805 nfs_update(vp, ta, tm, waitfor)
1806 	struct vnode *vp;
1807 	struct timeval *ta;
1808 	struct timeval *tm;
1809 	int waitfor;
1810 {
1811 
1812 	/* Use nfs_setattr */
1813 	printf("nfs_update: need to implement!!");
1814 	return (EOPNOTSUPP);
1815 }
1816