xref: /csrg-svn/sys/nfs/nfs_vnops.c (revision 40251)
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  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the University of California, Berkeley.  The name of the
14  * University may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  *	@(#)nfs_vnops.c	7.30 (Berkeley) 03/01/90
21  */
22 
23 /*
24  * vnode op calls for sun nfs version 2
25  */
26 
27 #include "machine/pte.h"
28 #include "machine/mtpr.h"
29 #include "param.h"
30 #include "user.h"
31 #include "proc.h"
32 #include "mount.h"
33 #include "buf.h"
34 #include "vm.h"
35 #include "malloc.h"
36 #include "mbuf.h"
37 #include "errno.h"
38 #include "file.h"
39 #include "conf.h"
40 #include "vnode.h"
41 #include "text.h"
42 #include "map.h"
43 #include "nfsv2.h"
44 #include "nfs.h"
45 #include "nfsnode.h"
46 #include "nfsmount.h"
47 #include "xdr_subs.h"
48 #include "nfsm_subs.h"
49 #include "nfsiom.h"
50 
51 /* Defs */
52 #define	TRUE	1
53 #define	FALSE	0
54 
55 /* Global vars */
56 int	nfs_lookup(),
57 	nfs_create(),
58 	nfs_mknod(),
59 	nfs_open(),
60 	nfs_close(),
61 	nfs_access(),
62 	nfs_getattr(),
63 	nfs_setattr(),
64 	nfs_read(),
65 	nfs_write(),
66 	vfs_noop(),
67 	vfs_nullop(),
68 	nfs_remove(),
69 	nfs_link(),
70 	nfs_rename(),
71 	nfs_mkdir(),
72 	nfs_rmdir(),
73 	nfs_symlink(),
74 	nfs_readdir(),
75 	nfs_readlink(),
76 	nfs_abortop(),
77 	nfs_lock(),
78 	nfs_unlock(),
79 	nfs_bmap(),
80 	nfs_strategy(),
81 	nfs_fsync(),
82 	nfs_inactive(),
83 	nfs_reclaim(),
84 	nfs_print(),
85 	nfs_islocked();
86 
87 struct vnodeops nfsv2_vnodeops = {
88 	nfs_lookup,		/* lookup */
89 	nfs_create,		/* create */
90 	nfs_mknod,		/* mknod */
91 	nfs_open,		/* open */
92 	nfs_close,		/* close */
93 	nfs_access,		/* access */
94 	nfs_getattr,		/* getattr */
95 	nfs_setattr,		/* setattr */
96 	nfs_read,		/* read */
97 	nfs_write,		/* write */
98 	vfs_noop,		/* ioctl */
99 	vfs_noop,		/* select */
100 	vfs_noop,		/* mmap */
101 	nfs_fsync,		/* fsync */
102 	vfs_nullop,		/* seek */
103 	nfs_remove,		/* remove */
104 	nfs_link,		/* link */
105 	nfs_rename,		/* rename */
106 	nfs_mkdir,		/* mkdir */
107 	nfs_rmdir,		/* rmdir */
108 	nfs_symlink,		/* symlink */
109 	nfs_readdir,		/* readdir */
110 	nfs_readlink,		/* readlink */
111 	nfs_abortop,		/* abortop */
112 	nfs_inactive,		/* inactive */
113 	nfs_reclaim,		/* reclaim */
114 	nfs_lock,		/* lock */
115 	nfs_unlock,		/* unlock */
116 	nfs_bmap,		/* bmap */
117 	nfs_strategy,		/* strategy */
118 	nfs_print,		/* print */
119 	nfs_islocked,		/* islocked */
120 };
121 
122 /* Special device vnode ops */
123 int	spec_lookup(),
124 	spec_open(),
125 	spec_read(),
126 	spec_write(),
127 	spec_strategy(),
128 	spec_bmap(),
129 	spec_ioctl(),
130 	spec_select(),
131 	spec_close(),
132 	spec_badop(),
133 	spec_nullop();
134 
135 struct vnodeops spec_nfsv2nodeops = {
136 	spec_lookup,		/* lookup */
137 	spec_badop,		/* create */
138 	spec_badop,		/* mknod */
139 	spec_open,		/* open */
140 	spec_close,		/* close */
141 	nfs_access,		/* access */
142 	nfs_getattr,		/* getattr */
143 	nfs_setattr,		/* setattr */
144 	spec_read,		/* read */
145 	spec_write,		/* write */
146 	spec_ioctl,		/* ioctl */
147 	spec_select,		/* select */
148 	spec_badop,		/* mmap */
149 	spec_nullop,		/* fsync */
150 	spec_badop,		/* seek */
151 	spec_badop,		/* remove */
152 	spec_badop,		/* link */
153 	spec_badop,		/* rename */
154 	spec_badop,		/* mkdir */
155 	spec_badop,		/* rmdir */
156 	spec_badop,		/* symlink */
157 	spec_badop,		/* readdir */
158 	spec_badop,		/* readlink */
159 	spec_badop,		/* abortop */
160 	nfs_inactive,		/* inactive */
161 	nfs_reclaim,		/* reclaim */
162 	nfs_lock,		/* lock */
163 	nfs_unlock,		/* unlock */
164 	spec_bmap,		/* bmap */
165 	spec_strategy,		/* strategy */
166 	nfs_print,		/* print */
167 	nfs_islocked,		/* islocked */
168 };
169 
170 extern u_long nfs_procids[NFS_NPROCS];
171 extern u_long nfs_prog, nfs_vers;
172 extern char nfsiobuf[MAXPHYS+NBPG];
173 extern int nonidempotent[NFS_NPROCS];
174 struct map nfsmap[NFS_MSIZ];
175 enum vtype v_type[NFLNK+1];
176 struct buf nfs_bqueue;		/* Queue head for nfsiod's */
177 int nfs_asyncdaemons = 0;
178 struct proc *nfs_iodwant[MAX_ASYNCDAEMON];
179 static int nfsmap_want = 0;
180 
181 /*
182  * nfs null call from vfs.
183  */
184 nfs_null(vp, cred)
185 	struct vnode *vp;
186 	struct ucred *cred;
187 {
188 	caddr_t bpos, dpos;
189 	u_long xid;
190 	int error = 0;
191 	struct mbuf *mreq, *mrep, *md, *mb;
192 
193 	nfsm_reqhead(nfs_procids[NFSPROC_NULL], cred, 0);
194 	nfsm_request(vp, nonidempotent[NFSPROC_NULL]);
195 	nfsm_reqdone;
196 	return (error);
197 }
198 
199 /*
200  * nfs access vnode op.
201  * Essentially just get vattr and then imitate iaccess()
202  */
203 nfs_access(vp, mode, cred)
204 	struct vnode *vp;
205 	int mode;
206 	register struct ucred *cred;
207 {
208 	register struct vattr *vap;
209 	register gid_t *gp;
210 	struct vattr vattr;
211 	register int i;
212 	int error;
213 
214 	/*
215 	 * If you're the super-user,
216 	 * you always get access.
217 	 */
218 	if (cred->cr_uid == 0)
219 		return (0);
220 	vap = &vattr;
221 	if (error = nfs_getattr(vp, vap, cred))
222 		return (error);
223 	/*
224 	 * Access check is based on only one of owner, group, public.
225 	 * If not owner, then check group. If not a member of the
226 	 * group, then check public access.
227 	 */
228 	if (cred->cr_uid != vap->va_uid) {
229 		mode >>= 3;
230 		gp = cred->cr_groups;
231 		for (i = 0; i < cred->cr_ngroups; i++, gp++)
232 			if (vap->va_gid == *gp)
233 				goto found;
234 		mode >>= 3;
235 found:
236 		;
237 	}
238 	if ((vap->va_mode & mode) != 0)
239 		return (0);
240 	return (EACCES);
241 }
242 
243 /*
244  * nfs open vnode op
245  * Just check to see if the type is ok
246  */
247 /* ARGSUSED */
248 nfs_open(vp, mode, cred)
249 	struct vnode *vp;
250 	int mode;
251 	struct ucred *cred;
252 {
253 	register enum vtype vtyp;
254 
255 	vtyp = vp->v_type;
256 	if (vtyp == VREG || vtyp == VDIR || vtyp == VLNK)
257 		return (0);
258 	else
259 		return (EACCES);
260 }
261 
262 /*
263  * nfs close vnode op
264  * For reg files, invalidate any buffer cache entries.
265  */
266 /* ARGSUSED */
267 nfs_close(vp, fflags, cred)
268 	register struct vnode *vp;
269 	int fflags;
270 	struct ucred *cred;
271 {
272 	register struct nfsnode *np = VTONFS(vp);
273 	int error = 0;
274 
275 	if (vp->v_type == VREG && ((np->n_flag & NMODIFIED) ||
276 	   ((np->n_flag & NBUFFERED) && np->n_sillyrename))) {
277 		nfs_lock(vp);
278 		np->n_flag &= ~(NMODIFIED|NBUFFERED);
279 		vinvalbuf(vp, TRUE);
280 		if (np->n_flag & NWRITEERR) {
281 			np->n_flag &= ~NWRITEERR;
282 			error = np->n_error;
283 		}
284 		nfs_unlock(vp);
285 	}
286 	return (error);
287 }
288 
289 /*
290  * nfs getattr call from vfs.
291  */
292 nfs_getattr(vp, vap, cred)
293 	register struct vnode *vp;
294 	struct vattr *vap;
295 	struct ucred *cred;
296 {
297 	register caddr_t cp;
298 	register long t1;
299 	caddr_t bpos, dpos;
300 	u_long xid;
301 	int error = 0;
302 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
303 
304 	/* First look in the cache.. */
305 	if (nfs_getattrcache(vp, vap) == 0)
306 		return (0);
307 	nfsstats.rpccnt[NFSPROC_GETATTR]++;
308 	nfsm_reqhead(nfs_procids[NFSPROC_GETATTR], cred, NFSX_FH);
309 	nfsm_fhtom(vp);
310 	nfsm_request(vp, nonidempotent[NFSPROC_GETATTR]);
311 	nfsm_loadattr(vp, vap);
312 	nfsm_reqdone;
313 	return (error);
314 }
315 
316 /*
317  * nfs setattr call.
318  */
319 nfs_setattr(vp, vap, cred)
320 	register struct vnode *vp;
321 	register struct vattr *vap;
322 	struct ucred *cred;
323 {
324 	register struct nfsv2_sattr *sp;
325 	register caddr_t cp;
326 	register long t1;
327 	caddr_t bpos, dpos;
328 	u_long xid;
329 	int error = 0;
330 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
331 	struct nfsnode *np;
332 
333 	nfsstats.rpccnt[NFSPROC_SETATTR]++;
334 	nfsm_reqhead(nfs_procids[NFSPROC_SETATTR], cred, NFSX_FH+NFSX_SATTR);
335 	nfsm_fhtom(vp);
336 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
337 	if (vap->va_mode == 0xffff)
338 		sp->sa_mode = VNOVAL;
339 	else
340 		sp->sa_mode = vtonfs_mode(vp->v_type, vap->va_mode);
341 	if (vap->va_uid == 0xffff)
342 		sp->sa_uid = VNOVAL;
343 	else
344 		sp->sa_uid = txdr_unsigned(vap->va_uid);
345 	if (vap->va_gid == 0xffff)
346 		sp->sa_gid = VNOVAL;
347 	else
348 		sp->sa_gid = txdr_unsigned(vap->va_gid);
349 	sp->sa_size = txdr_unsigned(vap->va_size);
350 	if (vap->va_size != VNOVAL) {
351 		np = VTONFS(vp);
352 		if (np->n_flag & NMODIFIED) {
353 			np->n_flag &= ~NMODIFIED;
354 			vinvalbuf(vp, TRUE);
355 		}
356 	}
357 	sp->sa_atime.tv_sec = txdr_unsigned(vap->va_atime.tv_sec);
358 	sp->sa_atime.tv_usec = txdr_unsigned(vap->va_flags);
359 	txdr_time(&vap->va_mtime, &sp->sa_mtime);
360 	nfsm_request(vp, nonidempotent[NFSPROC_SETATTR]);
361 	nfsm_loadattr(vp, (struct vattr *)0);
362 	/* should we fill in any vap fields ?? */
363 	nfsm_reqdone;
364 	return (error);
365 }
366 
367 /*
368  * nfs lookup call, one step at a time...
369  * First look in cache
370  * If not found, unlock the directory nfsnode and do the rpc
371  */
372 nfs_lookup(vp, ndp)
373 	register struct vnode *vp;
374 	register struct nameidata *ndp;
375 {
376 	register struct vnode *vdp;
377 	register u_long *p;
378 	register caddr_t cp;
379 	register long t1, t2;
380 	caddr_t bpos, dpos, cp2;
381 	u_long xid;
382 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
383 	struct vnode *newvp;
384 	long len;
385 	nfsv2fh_t *fhp;
386 	struct nfsnode *np;
387 	int lockparent, wantparent, flag, error = 0;
388 
389 	ndp->ni_dvp = vp;
390 	ndp->ni_vp = NULL;
391 	if (vp->v_type != VDIR)
392 		return (ENOTDIR);
393 	lockparent = ndp->ni_nameiop & LOCKPARENT;
394 	flag = ndp->ni_nameiop & OPFLAG;
395 	wantparent = ndp->ni_nameiop & (LOCKPARENT|WANTPARENT);
396 	if ((error = cache_lookup(ndp)) && error != ENOENT) {
397 		struct vattr vattr;
398 		int vpid;
399 
400 		if (vp == ndp->ni_rdir && ndp->ni_isdotdot)
401 			panic("nfs_lookup: .. through root");
402 		vdp = ndp->ni_vp;
403 		vpid = vdp->v_id;
404 		/*
405 		 * See the comment starting `Step through' in ufs/ufs_lookup.c
406 		 * for an explanation of the locking protocol
407 		 */
408 		if (vp == vdp) {
409 			VREF(vdp);
410 			error = 0;
411 		} else if (ndp->ni_isdotdot) {
412 			nfs_unlock(vp);
413 			error = vget(vdp);
414 		} else {
415 			error = vget(vdp);
416 			nfs_unlock(vp);
417 		}
418 		if (!error) {
419 			if (vpid == vdp->v_id) {
420 			   if (!nfs_getattr(vdp, &vattr, ndp->ni_cred) &&
421 			       vattr.va_ctime.tv_sec == VTONFS(vdp)->n_ctime) {
422 				nfsstats.lookupcache_hits++;
423 				return (0);
424 			   } else {
425 				cache_purge(vdp);
426 				nfs_nput(vdp);
427 			   }
428 			} else {
429 				nfs_nput(vdp);
430 			}
431 		}
432 		ndp->ni_vp = (struct vnode *)0;
433 	} else
434 		nfs_unlock(vp);
435 	error = 0;
436 	nfsstats.lookupcache_misses++;
437 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
438 	len = ndp->ni_namelen;
439 	nfsm_reqhead(nfs_procids[NFSPROC_LOOKUP], ndp->ni_cred, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
440 	nfsm_fhtom(vp);
441 	nfsm_strtom(ndp->ni_ptr, len, NFS_MAXNAMLEN);
442 	nfsm_request(vp, nonidempotent[NFSPROC_LOOKUP]);
443 nfsmout:
444 	if (error) {
445 		if (lockparent || (flag != CREATE && flag != RENAME) ||
446 		    *ndp->ni_next != 0)
447 			nfs_lock(vp);
448 		return (ENOENT);
449 	}
450 	nfsm_disect(fhp,nfsv2fh_t *,NFSX_FH);
451 
452 	/*
453 	 * Handle DELETE and RENAME cases...
454 	 */
455 	if (flag == DELETE && *ndp->ni_next == 0) {
456 		if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) {
457 			VREF(vp);
458 			newvp = vp;
459 			np = VTONFS(vp);
460 		} else {
461 			if (error = nfs_nget(vp->v_mount, fhp, &np)) {
462 				nfs_lock(vp);
463 				m_freem(mrep);
464 				return (error);
465 			}
466 			newvp = NFSTOV(np);
467 		}
468 		if (error =
469 		    nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) {
470 			nfs_lock(vp);
471 			if (newvp != vp)
472 				nfs_nput(newvp);
473 			else
474 				vrele(vp);
475 			m_freem(mrep);
476 			return (error);
477 		}
478 		ndp->ni_vp = newvp;
479 		if (lockparent || vp == newvp)
480 			nfs_lock(vp);
481 		m_freem(mrep);
482 		return (0);
483 	}
484 
485 	if (flag == RENAME && wantparent && *ndp->ni_next == 0) {
486 		if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) {
487 			nfs_lock(vp);
488 			m_freem(mrep);
489 			return (EISDIR);
490 		}
491 		if (error = nfs_nget(vp->v_mount, fhp, &np)) {
492 			nfs_lock(vp);
493 			m_freem(mrep);
494 			return (error);
495 		}
496 		newvp = NFSTOV(np);
497 		if (error =
498 		    nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) {
499 			nfs_lock(vp);
500 			nfs_nput(newvp);
501 			m_freem(mrep);
502 			return (error);
503 		}
504 		ndp->ni_vp = newvp;
505 		if (lockparent)
506 			nfs_lock(vp);
507 		return (0);
508 	}
509 
510 	if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) {
511 		VREF(vp);
512 		newvp = vp;
513 		np = VTONFS(vp);
514 	} else if (ndp->ni_isdotdot) {
515 		if (error = nfs_nget(vp->v_mount, fhp, &np)) {
516 			nfs_lock(vp);
517 			m_freem(mrep);
518 			return (error);
519 		}
520 		newvp = NFSTOV(np);
521 	} else {
522 		if (error = nfs_nget(vp->v_mount, fhp, &np)) {
523 			nfs_lock(vp);
524 			m_freem(mrep);
525 			return (error);
526 		}
527 		newvp = NFSTOV(np);
528 	}
529 	if (error = nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) {
530 		nfs_lock(vp);
531 		if (newvp != vp)
532 			nfs_nput(newvp);
533 		else
534 			vrele(vp);
535 		m_freem(mrep);
536 		return (error);
537 	}
538 	m_freem(mrep);
539 
540 	if (vp == newvp || (lockparent && *ndp->ni_next == '\0'))
541 		nfs_lock(vp);
542 	ndp->ni_vp = newvp;
543 	if (error == 0 && ndp->ni_makeentry) {
544 		np->n_ctime = np->n_vattr.va_ctime.tv_sec;
545 		cache_enter(ndp);
546 	}
547 	return (error);
548 }
549 
550 /*
551  * nfs readlink call
552  */
553 nfs_readlink(vp, uiop, cred)
554 	register struct vnode *vp;
555 	struct uio *uiop;
556 	struct ucred *cred;
557 {
558 	register u_long *p;
559 	register caddr_t cp;
560 	register long t1;
561 	caddr_t bpos, dpos, cp2;
562 	u_long xid;
563 	int error = 0;
564 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
565 	long len;
566 
567 	nfsstats.rpccnt[NFSPROC_READLINK]++;
568 	nfsm_reqhead(nfs_procids[NFSPROC_READLINK], cred, NFSX_FH);
569 	nfsm_fhtom(vp);
570 	nfsm_request(vp, nonidempotent[NFSPROC_READLINK]);
571 	nfsm_strsiz(len, NFS_MAXPATHLEN);
572 	nfsm_mtouio(uiop, len);
573 	nfsm_reqdone;
574 	return (error);
575 }
576 
577 /*
578  * nfs read call
579  */
580 nfs_readrpc(vp, uiop, cred)
581 	register struct vnode *vp;
582 	struct uio *uiop;
583 	struct ucred *cred;
584 {
585 	register u_long *p;
586 	register caddr_t cp;
587 	register long t1;
588 	caddr_t bpos, dpos, cp2;
589 	u_long xid;
590 	int error = 0;
591 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
592 	struct nfsmount *nmp;
593 	long len, retlen, tsiz;
594 
595 	nmp = vfs_to_nfs(vp->v_mount);
596 	tsiz = uiop->uio_resid;
597 	while (tsiz > 0) {
598 		nfsstats.rpccnt[NFSPROC_READ]++;
599 		len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
600 		nfsm_reqhead(nfs_procids[NFSPROC_READ], cred, NFSX_FH+NFSX_UNSIGNED*3);
601 		nfsm_fhtom(vp);
602 		nfsm_build(p, u_long *, NFSX_UNSIGNED*3);
603 		*p++ = txdr_unsigned(uiop->uio_offset);
604 		*p++ = txdr_unsigned(len);
605 		*p = 0;
606 		nfsm_request(vp, nonidempotent[NFSPROC_READ]);
607 		nfsm_loadattr(vp, (struct vattr *)0);
608 		nfsm_strsiz(retlen, nmp->nm_rsize);
609 		nfsm_mtouio(uiop, retlen);
610 		m_freem(mrep);
611 		if (retlen < len)
612 			tsiz = 0;
613 		else
614 			tsiz -= len;
615 	}
616 nfsmout:
617 	return (error);
618 }
619 
620 /*
621  * nfs write call
622  */
623 nfs_writerpc(vp, uiop, cred)
624 	register struct vnode *vp;
625 	struct uio *uiop;
626 	struct ucred *cred;
627 {
628 	register u_long *p;
629 	register caddr_t cp;
630 	register long t1;
631 	caddr_t bpos, dpos;
632 	u_long xid;
633 	int error = 0;
634 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
635 	struct nfsmount *nmp;
636 	long len, tsiz;
637 
638 	nmp = vfs_to_nfs(vp->v_mount);
639 	tsiz = uiop->uio_resid;
640 	while (tsiz > 0) {
641 		nfsstats.rpccnt[NFSPROC_WRITE]++;
642 		len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz;
643 		nfsm_reqhead(nfs_procids[NFSPROC_WRITE], cred,
644 			NFSX_FH+NFSX_UNSIGNED*4);
645 		nfsm_fhtom(vp);
646 		nfsm_build(p, u_long *, NFSX_UNSIGNED*4);
647 		*(p+1) = txdr_unsigned(uiop->uio_offset);
648 		*(p+3) = txdr_unsigned(len);
649 		nfsm_uiotom(uiop, len);
650 		nfsm_request(vp, nonidempotent[NFSPROC_WRITE]);
651 		nfsm_loadattr(vp, (struct vattr *)0);
652 		m_freem(mrep);
653 		tsiz -= len;
654 	}
655 nfsmout:
656 	return (error);
657 }
658 
659 /*
660  * nfs mknod call
661  * This call is currently not supported.
662  */
663 /* ARGSUSED */
664 nfs_mknod(ndp, vap, cred)
665 	struct nameidata *ndp;
666 	struct ucred *cred;
667 	struct vattr *vap;
668 {
669 
670 	nfs_abortop(ndp);
671 	return (EOPNOTSUPP);
672 }
673 
674 /*
675  * nfs file create call
676  */
677 nfs_create(ndp, vap)
678 	register struct nameidata *ndp;
679 	register struct vattr *vap;
680 {
681 	register struct nfsv2_sattr *sp;
682 	register u_long *p;
683 	register caddr_t cp;
684 	register long t1, t2;
685 	caddr_t bpos, dpos, cp2;
686 	u_long xid;
687 	int error = 0;
688 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
689 
690 	nfsstats.rpccnt[NFSPROC_CREATE]++;
691 	nfsm_reqhead(nfs_procids[NFSPROC_CREATE], ndp->ni_cred,
692 	  NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)+NFSX_SATTR);
693 	nfsm_fhtom(ndp->ni_dvp);
694 	nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
695 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
696 	sp->sa_mode = vtonfs_mode(VREG, vap->va_mode);
697 	sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
698 	sp->sa_gid = txdr_unsigned(ndp->ni_cred->cr_gid);
699 	sp->sa_size = txdr_unsigned(0);
700 	/* or should these be VNOVAL ?? */
701 	txdr_time(&vap->va_atime, &sp->sa_atime);
702 	txdr_time(&vap->va_mtime, &sp->sa_mtime);
703 	nfsm_request(ndp->ni_dvp, nonidempotent[NFSPROC_CREATE]);
704 	nfsm_mtofh(ndp->ni_dvp, ndp->ni_vp);
705 	nfsm_reqdone;
706 	nfs_nput(ndp->ni_dvp);
707 	return (error);
708 }
709 
710 /*
711  * nfs file remove call
712  * To try and make nfs semantics closer to vfs semantics, a file that has
713  * other references to the vnode is renamed instead of removed and then
714  * removed later on the last close.
715  * Unfortunately you must flush the buffer cache and cmap to get rid of
716  * all extraneous vnode references before you check the reference cnt.
717  * 1 - If the file could have blocks in the buffer cache
718  *	  flush them out and invalidate them
719  *	  mpurge the vnode to flush out cmap references
720  *	  (This is necessary to update the vnode ref cnt as well as sensible
721  *	   for actual removes, to free up the buffers)
722  * 2 - If v_usecount > 1
723  *	  If a rename is not already in the works
724  *	     call nfs_sillyrename() to set it up
725  *     else
726  *	  do the remove rpc
727  */
728 nfs_remove(ndp)
729 	register struct nameidata *ndp;
730 {
731 	register struct vnode *vp = ndp->ni_vp;
732 	register struct nfsnode *np = VTONFS(ndp->ni_vp);
733 	register u_long *p;
734 	register caddr_t cp;
735 	register long t1, t2;
736 	caddr_t bpos, dpos;
737 	u_long xid;
738 	int error = 0;
739 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
740 
741 	if (vp->v_type == VREG) {
742 		if (np->n_flag & (NMODIFIED|NBUFFERED)) {
743 			np->n_flag &= ~(NMODIFIED|NBUFFERED);
744 			vinvalbuf(vp, TRUE);
745 		}
746 		if (np->n_flag & NPAGEDON) {
747 			np->n_flag &= ~NPAGEDON;
748 			mpurge(vp);	/* In case cmap entries still ref it */
749 		}
750 	}
751 	if (vp->v_usecount > 1) {
752 		if (!np->n_sillyrename)
753 			error = nfs_sillyrename(ndp, REMOVE);
754 	} else {
755 		nfsstats.rpccnt[NFSPROC_REMOVE]++;
756 		nfsm_reqhead(nfs_procids[NFSPROC_REMOVE], ndp->ni_cred,
757 			NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen));
758 		nfsm_fhtom(ndp->ni_dvp);
759 		nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
760 		nfsm_request(ndp->ni_dvp, nonidempotent[NFSPROC_REMOVE]);
761 		nfsm_reqdone;
762 		/*
763 		 * Kludge City: If the first reply to the remove rpc is lost..
764 		 *   the reply to the retransmitted request will be ENOENT
765 		 *   since the file was in fact removed
766 		 *   Therefore, we cheat and return success.
767 		 */
768 		if (error == ENOENT)
769 			error = 0;
770 	}
771 	np->n_attrstamp = 0;
772 	if (ndp->ni_dvp == vp)
773 		vrele(vp);
774 	else
775 		nfs_nput(ndp->ni_dvp);
776 	nfs_nput(vp);
777 	return (error);
778 }
779 
780 /*
781  * nfs file remove rpc called from nfs_inactive
782  */
783 nfs_removeit(ndp)
784 	register struct nameidata *ndp;
785 {
786 	register u_long *p;
787 	register caddr_t cp;
788 	register long t1, t2;
789 	caddr_t bpos, dpos;
790 	u_long xid;
791 	int error = 0;
792 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
793 
794 	nfsstats.rpccnt[NFSPROC_REMOVE]++;
795 	nfsm_reqhead(nfs_procids[NFSPROC_REMOVE], ndp->ni_cred,
796 		NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen));
797 	nfsm_fhtom(ndp->ni_dvp);
798 	nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
799 	nfsm_request(ndp->ni_dvp, nonidempotent[NFSPROC_REMOVE]);
800 	nfsm_reqdone;
801 	return (error);
802 }
803 
804 /*
805  * nfs file rename call
806  */
807 nfs_rename(sndp, tndp)
808 	register struct nameidata *sndp, *tndp;
809 {
810 	register u_long *p;
811 	register caddr_t cp;
812 	register long t1, t2;
813 	caddr_t bpos, dpos;
814 	u_long xid;
815 	int error = 0;
816 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
817 
818 	nfsstats.rpccnt[NFSPROC_RENAME]++;
819 	nfsm_reqhead(nfs_procids[NFSPROC_RENAME], tndp->ni_cred,
820 		(NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(sndp->ni_dent.d_namlen)+
821 		nfsm_rndup(tndp->ni_dent.d_namlen)); /* or sndp->ni_cred?*/
822 	nfsm_fhtom(sndp->ni_dvp);
823 	nfsm_strtom(sndp->ni_dent.d_name,sndp->ni_dent.d_namlen,NFS_MAXNAMLEN);
824 	nfsm_fhtom(tndp->ni_dvp);
825 	nfsm_strtom(tndp->ni_dent.d_name,tndp->ni_dent.d_namlen,NFS_MAXNAMLEN);
826 	nfsm_request(sndp->ni_dvp, nonidempotent[NFSPROC_RENAME]);
827 	nfsm_reqdone;
828 	if (sndp->ni_vp->v_type == VDIR) {
829 		if (tndp->ni_vp != NULL && tndp->ni_vp->v_type == VDIR)
830 			cache_purge(tndp->ni_dvp);
831 		cache_purge(sndp->ni_dvp);
832 	}
833 	nfs_abortop(sndp);
834 	nfs_abortop(tndp);
835 	/*
836 	 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
837 	 */
838 	if (error == ENOENT)
839 		error = 0;
840 	return (error);
841 }
842 
843 /*
844  * nfs file rename rpc called from above
845  */
846 nfs_renameit(sndp, tndp)
847 	register struct nameidata *sndp, *tndp;
848 {
849 	register u_long *p;
850 	register caddr_t cp;
851 	register long t1, t2;
852 	caddr_t bpos, dpos;
853 	u_long xid;
854 	int error = 0;
855 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
856 
857 	nfsstats.rpccnt[NFSPROC_RENAME]++;
858 	nfsm_reqhead(nfs_procids[NFSPROC_RENAME], tndp->ni_cred,
859 		(NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(sndp->ni_dent.d_namlen)+
860 		nfsm_rndup(tndp->ni_dent.d_namlen)); /* or sndp->ni_cred?*/
861 	nfsm_fhtom(sndp->ni_dvp);
862 	nfsm_strtom(sndp->ni_dent.d_name,sndp->ni_dent.d_namlen,NFS_MAXNAMLEN);
863 	nfsm_fhtom(tndp->ni_dvp);
864 	nfsm_strtom(tndp->ni_dent.d_name,tndp->ni_dent.d_namlen,NFS_MAXNAMLEN);
865 	nfsm_request(sndp->ni_dvp, nonidempotent[NFSPROC_RENAME]);
866 	nfsm_reqdone;
867 	return (error);
868 }
869 
870 /*
871  * nfs hard link create call
872  */
873 nfs_link(vp, ndp)
874 	register struct vnode *vp;
875 	register struct nameidata *ndp;
876 {
877 	register u_long *p;
878 	register caddr_t cp;
879 	register long t1, t2;
880 	caddr_t bpos, dpos;
881 	u_long xid;
882 	int error = 0;
883 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
884 
885 	if (ndp->ni_dvp != vp)
886 		nfs_lock(vp);
887 	nfsstats.rpccnt[NFSPROC_LINK]++;
888 	nfsm_reqhead(nfs_procids[NFSPROC_LINK], ndp->ni_cred,
889 		NFSX_FH*2+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen));
890 	nfsm_fhtom(vp);
891 	nfsm_fhtom(ndp->ni_dvp);
892 	nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
893 	nfsm_request(vp, nonidempotent[NFSPROC_LINK]);
894 	nfsm_reqdone;
895 	VTONFS(vp)->n_attrstamp = 0;
896 	if (ndp->ni_dvp != vp)
897 		nfs_unlock(vp);
898 	nfs_nput(ndp->ni_dvp);
899 	/*
900 	 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
901 	 */
902 	if (error == EEXIST)
903 		error = 0;
904 	return (error);
905 }
906 
907 /*
908  * nfs symbolic link create call
909  */
910 nfs_symlink(ndp, vap, nm)
911 	struct nameidata *ndp;
912 	struct vattr *vap;
913 	char *nm;		/* is this the path ?? */
914 {
915 	register struct nfsv2_sattr *sp;
916 	register u_long *p;
917 	register caddr_t cp;
918 	register long t1, t2;
919 	caddr_t bpos, dpos;
920 	u_long xid;
921 	int error = 0;
922 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
923 
924 	nfsstats.rpccnt[NFSPROC_SYMLINK]++;
925 	nfsm_reqhead(nfs_procids[NFSPROC_SYMLINK], ndp->ni_cred,
926 	NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)+NFSX_UNSIGNED);
927 	nfsm_fhtom(ndp->ni_dvp);
928 	nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
929 	nfsm_strtom(nm, strlen(nm), NFS_MAXPATHLEN);
930 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
931 	sp->sa_mode = vtonfs_mode(VLNK, vap->va_mode);
932 	sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
933 	sp->sa_gid = txdr_unsigned(ndp->ni_cred->cr_gid);
934 	sp->sa_size = txdr_unsigned(VNOVAL);
935 	txdr_time(&vap->va_atime, &sp->sa_atime);	/* or VNOVAL ?? */
936 	txdr_time(&vap->va_mtime, &sp->sa_mtime);	/* or VNOVAL ?? */
937 	nfsm_request(ndp->ni_dvp, nonidempotent[NFSPROC_SYMLINK]);
938 	nfsm_reqdone;
939 	nfs_nput(ndp->ni_dvp);
940 	/*
941 	 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
942 	 */
943 	if (error == EEXIST)
944 		error = 0;
945 	return (error);
946 }
947 
948 /*
949  * nfs make dir call
950  */
951 nfs_mkdir(ndp, vap)
952 	register struct nameidata *ndp;
953 	struct vattr *vap;
954 {
955 	register struct nfsv2_sattr *sp;
956 	register u_long *p;
957 	register caddr_t cp;
958 	register long t1, t2;
959 	caddr_t bpos, dpos, cp2;
960 	u_long xid;
961 	int error = 0;
962 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
963 
964 	nfsstats.rpccnt[NFSPROC_MKDIR]++;
965 	nfsm_reqhead(nfs_procids[NFSPROC_MKDIR], ndp->ni_cred,
966 	  NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)+NFSX_SATTR);
967 	nfsm_fhtom(ndp->ni_dvp);
968 	nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
969 	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
970 	sp->sa_mode = vtonfs_mode(VDIR, vap->va_mode);
971 	sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
972 	sp->sa_gid = txdr_unsigned(ndp->ni_cred->cr_gid);
973 	sp->sa_size = txdr_unsigned(VNOVAL);
974 	txdr_time(&vap->va_atime, &sp->sa_atime);	/* or VNOVAL ?? */
975 	txdr_time(&vap->va_mtime, &sp->sa_mtime);	/* or VNOVAL ?? */
976 	nfsm_request(ndp->ni_dvp, nonidempotent[NFSPROC_MKDIR]);
977 	nfsm_mtofh(ndp->ni_dvp, ndp->ni_vp);
978 	nfsm_reqdone;
979 	nfs_nput(ndp->ni_dvp);
980 	/*
981 	 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry.
982 	 */
983 	if (error == EEXIST)
984 		error = 0;
985 	return (error);
986 }
987 
988 /*
989  * nfs remove directory call
990  */
991 nfs_rmdir(ndp)
992 	register struct nameidata *ndp;
993 {
994 	register u_long *p;
995 	register caddr_t cp;
996 	register long t1, t2;
997 	caddr_t bpos, dpos;
998 	u_long xid;
999 	int error = 0;
1000 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1001 
1002 	if (ndp->ni_dvp == ndp->ni_vp) {
1003 		vrele(ndp->ni_dvp);
1004 		nfs_nput(ndp->ni_dvp);
1005 		return (EINVAL);
1006 	}
1007 	nfsstats.rpccnt[NFSPROC_RMDIR]++;
1008 	nfsm_reqhead(nfs_procids[NFSPROC_RMDIR], ndp->ni_cred,
1009 		NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen));
1010 	nfsm_fhtom(ndp->ni_dvp);
1011 	nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
1012 	nfsm_request(ndp->ni_dvp, nonidempotent[NFSPROC_RMDIR]);
1013 	nfsm_reqdone;
1014 	cache_purge(ndp->ni_dvp);
1015 	cache_purge(ndp->ni_vp);
1016 	nfs_nput(ndp->ni_vp);
1017 	nfs_nput(ndp->ni_dvp);
1018 	/*
1019 	 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
1020 	 */
1021 	if (error == ENOENT)
1022 		error = 0;
1023 	return (error);
1024 }
1025 
1026 /*
1027  * nfs readdir call
1028  * Although cookie is defined as opaque, I translate it to/from net byte
1029  * order so that it looks more sensible. This appears consistent with the
1030  * Ultrix implementation of NFS.
1031  */
1032 nfs_readdir(vp, uiop, cred)
1033 	register struct vnode *vp;
1034 	struct uio *uiop;
1035 	struct ucred *cred;
1036 {
1037 	register long len;
1038 	register struct direct *dp;
1039 	register u_long *p;
1040 	register caddr_t cp;
1041 	register long t1;
1042 	long tlen;
1043 	caddr_t bpos, dpos, cp2;
1044 	u_long xid;
1045 	int error = 0;
1046 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1047 	struct mbuf *md2;
1048 	caddr_t dpos2;
1049 	int siz;
1050 	int more_dirs;
1051 	off_t off, savoff;
1052 	struct direct *savdp;
1053 
1054 	nfsstats.rpccnt[NFSPROC_READDIR]++;
1055 	nfsm_reqhead(nfs_procids[NFSPROC_READDIR], cred, xid);
1056 	nfsm_fhtom(vp);
1057 	nfsm_build(p, u_long *, 2*NFSX_UNSIGNED);
1058 	*p++ = txdr_unsigned(uiop->uio_offset);
1059 	*p = txdr_unsigned(uiop->uio_resid);
1060 	nfsm_request(vp, nonidempotent[NFSPROC_READDIR]);
1061 	siz = 0;
1062 	nfsm_disect(p, u_long *, NFSX_UNSIGNED);
1063 	more_dirs = fxdr_unsigned(int, *p);
1064 
1065 	/* Save the position so that we can do nfsm_mtouio() later */
1066 	dpos2 = dpos;
1067 	md2 = md;
1068 
1069 	/* loop thru the dir entries, doctoring them to 4bsd form */
1070 	savoff = off = 0;
1071 	savdp = dp = NULL;
1072 	while (more_dirs && siz < uiop->uio_resid) {
1073 		savoff = off;		/* Hold onto offset and dp */
1074 		savdp = dp;
1075 		nfsm_disecton(p, u_long *, 2*NFSX_UNSIGNED);
1076 		dp = (struct direct *)p;
1077 		dp->d_ino = fxdr_unsigned(u_long, *p++);
1078 		len = fxdr_unsigned(int, *p);
1079 		if (len <= 0 || len > NFS_MAXNAMLEN) {
1080 			error = EBADRPC;
1081 			m_freem(mrep);
1082 			goto nfsmout;
1083 		}
1084 		dp->d_namlen = (u_short)len;
1085 		nfsm_adv(len);		/* Point past name */
1086 		tlen = nfsm_rndup(len);
1087 		if (tlen != len) {	/* If name not on rounded boundary */
1088 			*dpos = '\0';	/* Null-terminate */
1089 			nfsm_adv(tlen - len);
1090 			len = tlen;
1091 		}
1092 		nfsm_disecton(p, u_long *, 2*NFSX_UNSIGNED);
1093 		off = fxdr_unsigned(off_t, *p);
1094 		*p++ = 0;		/* Ensures null termination of name */
1095 		more_dirs = fxdr_unsigned(int, *p);
1096 		dp->d_reclen = len+4*NFSX_UNSIGNED;
1097 		siz += dp->d_reclen;
1098 	}
1099 	/*
1100 	 * If at end of rpc data, get the eof boolean
1101 	 */
1102 	if (!more_dirs)
1103 		nfsm_disecton(p, u_long *, NFSX_UNSIGNED);
1104 	/*
1105 	 * If there is too much to fit in the data buffer, use savoff and
1106 	 * savdp to trim off the last record.
1107 	 * --> we are not at eof
1108 	 */
1109 	if (siz > uiop->uio_resid) {
1110 		off = savoff;
1111 		siz -= dp->d_reclen;
1112 		dp = savdp;
1113 	}
1114 	if (siz > 0) {
1115 		md = md2;
1116 		dpos = dpos2;
1117 		nfsm_mtouio(uiop, siz);
1118 		uiop->uio_offset = off;
1119 	}
1120 	nfsm_reqdone;
1121 	return (error);
1122 }
1123 
1124 /*
1125  * nfs statfs call
1126  * (Actually a vfsop, not a vnode op)
1127  */
1128 nfs_statfs(mp, sbp)
1129 	struct mount *mp;
1130 	register struct statfs *sbp;
1131 {
1132 	register struct vnode *vp;
1133 	register struct nfsv2_statfs *sfp;
1134 	register caddr_t cp;
1135 	register long t1;
1136 	caddr_t bpos, dpos, cp2;
1137 	u_long xid;
1138 	int error = 0;
1139 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1140 	struct nfsmount *nmp;
1141 	struct ucred *cred;
1142 	struct nfsnode *np;
1143 
1144 	nmp = vfs_to_nfs(mp);
1145 	if (error = nfs_nget(mp, &nmp->nm_fh, &np))
1146 		return (error);
1147 	vp = NFSTOV(np);
1148 	nfsstats.rpccnt[NFSPROC_STATFS]++;
1149 	cred = crget();
1150 	cred->cr_ngroups = 1;
1151 	nfsm_reqhead(nfs_procids[NFSPROC_STATFS], cred, NFSX_FH);
1152 	nfsm_fhtom(vp);
1153 	nfsm_request(vp, nonidempotent[NFSPROC_STATFS]);
1154 	nfsm_disect(sfp, struct nfsv2_statfs *, NFSX_STATFS);
1155 	sbp->f_type = MOUNT_NFS;
1156 	sbp->f_flags = nmp->nm_flag;
1157 	sbp->f_bsize = fxdr_unsigned(long, sfp->sf_tsize);
1158 	sbp->f_fsize = fxdr_unsigned(long, sfp->sf_bsize);
1159 	sbp->f_blocks = fxdr_unsigned(long, sfp->sf_blocks);
1160 	sbp->f_bfree = fxdr_unsigned(long, sfp->sf_bfree);
1161 	sbp->f_bavail = fxdr_unsigned(long, sfp->sf_bavail);
1162 	sbp->f_files = 0;
1163 	sbp->f_ffree = 0;
1164 	sbp->f_fsid.val[0] = mp->m_fsid.val[0];
1165 	sbp->f_fsid.val[1] = mp->m_fsid.val[1];
1166 	bcopy(nmp->nm_path, sbp->f_mntonname, MNAMELEN);
1167 	bcopy(nmp->nm_host, sbp->f_mntfromname, MNAMELEN);
1168 	nfsm_reqdone;
1169 	nfs_nput(vp);
1170 	crfree(cred);
1171 	return (error);
1172 }
1173 
1174 static char hextoasc[] = "0123456789abcdef";
1175 
1176 /*
1177  * Silly rename. To make the NFS filesystem that is stateless look a little
1178  * more like the "ufs" a remove of an active vnode is translated to a rename
1179  * to a funny looking filename that is removed by nfs_inactive on the
1180  * nfsnode. There is the potential for another process on a different client
1181  * to create the same funny name between the nfs_lookitup() fails and the
1182  * nfs_rename() completes, but...
1183  */
1184 nfs_sillyrename(ndp, flag)
1185 	register struct nameidata *ndp;
1186 	int flag;
1187 {
1188 	register struct nfsnode *np;
1189 	register struct sillyrename *sp;
1190 	register struct nameidata *tndp;
1191 	int error;
1192 	short pid;
1193 
1194 	np = VTONFS(ndp->ni_dvp);
1195 	cache_purge(ndp->ni_dvp);
1196 	MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename),
1197 		M_TEMP, M_WAITOK);
1198 	sp->s_flag = flag;
1199 	bcopy((caddr_t)&np->n_fh, (caddr_t)&sp->s_fh, NFSX_FH);
1200 	np = VTONFS(ndp->ni_vp);
1201 	tndp = &sp->s_namei;
1202 	tndp->ni_cred = crdup(ndp->ni_cred);
1203 
1204 	/* Fudge together a funny name */
1205 	pid = u.u_procp->p_pid;
1206 	bcopy(".nfsAxxxx4.4", tndp->ni_dent.d_name, 13);
1207 	tndp->ni_dent.d_namlen = 12;
1208 	tndp->ni_dent.d_name[8] = hextoasc[pid & 0xf];
1209 	tndp->ni_dent.d_name[7] = hextoasc[(pid >> 4) & 0xf];
1210 	tndp->ni_dent.d_name[6] = hextoasc[(pid >> 8) & 0xf];
1211 	tndp->ni_dent.d_name[5] = hextoasc[(pid >> 12) & 0xf];
1212 
1213 	/* Try lookitups until we get one that isn't there */
1214 	while (nfs_lookitup(ndp->ni_dvp, tndp, (nfsv2fh_t *)0) == 0) {
1215 		tndp->ni_dent.d_name[4]++;
1216 		if (tndp->ni_dent.d_name[4] > 'z') {
1217 			error = EINVAL;
1218 			goto bad;
1219 		}
1220 	}
1221 	if (error = nfs_renameit(ndp, tndp))
1222 		goto bad;
1223 	nfs_lookitup(ndp->ni_dvp, tndp, &np->n_fh);
1224 	np->n_sillyrename = sp;
1225 	return (0);
1226 bad:
1227 	crfree(tndp->ni_cred);
1228 	free((caddr_t)sp, M_TEMP);
1229 	return (error);
1230 }
1231 
1232 /*
1233  * Look up a file name for silly rename stuff.
1234  * Just like nfs_lookup() except that it doesn't load returned values
1235  * into the nfsnode table.
1236  * If fhp != NULL it copies the returned file handle out
1237  */
1238 nfs_lookitup(vp, ndp, fhp)
1239 	register struct vnode *vp;
1240 	register struct nameidata *ndp;
1241 	nfsv2fh_t *fhp;
1242 {
1243 	register u_long *p;
1244 	register caddr_t cp;
1245 	register long t1, t2;
1246 	caddr_t bpos, dpos, cp2;
1247 	u_long xid;
1248 	int error = 0;
1249 	struct mbuf *mreq, *mrep, *md, *mb, *mb2;
1250 	long len;
1251 
1252 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
1253 	ndp->ni_dvp = vp;
1254 	ndp->ni_vp = NULL;
1255 	len = ndp->ni_dent.d_namlen;
1256 	nfsm_reqhead(nfs_procids[NFSPROC_LOOKUP], ndp->ni_cred, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
1257 	nfsm_fhtom(vp);
1258 	nfsm_strtom(ndp->ni_dent.d_name, len, NFS_MAXNAMLEN);
1259 	nfsm_request(vp, nonidempotent[NFSPROC_LOOKUP]);
1260 	if (fhp != NULL) {
1261 		nfsm_disect(cp, caddr_t, NFSX_FH);
1262 		bcopy(cp, (caddr_t)fhp, NFSX_FH);
1263 	}
1264 	nfsm_reqdone;
1265 	return (error);
1266 }
1267 
1268 /*
1269  * Kludge City..
1270  * - make nfs_bmap() essentially a no-op that does no translation
1271  * - do nfs_strategy() by faking physical I/O with nfs_readit/nfs_writeit
1272  *   after mapping the physical addresses into Kernel Virtual space in the
1273  *   nfsiobuf area.
1274  *   (Maybe I could use the process's page mapping, but I was concerned that
1275  *    Kernel Write might not be enabled and also figured copyout() would do
1276  *    a lot more work than bcopy() and also it currently happens in the
1277  *    context of the swapper process (2).
1278  */
1279 nfs_bmap(vp, bn, vpp, bnp)
1280 	struct vnode *vp;
1281 	daddr_t bn;
1282 	struct vnode **vpp;
1283 	daddr_t *bnp;
1284 {
1285 	if (vpp != NULL)
1286 		*vpp = vp;
1287 	if (bnp != NULL)
1288 		*bnp = bn * btodb(vp->v_mount->m_bsize);
1289 	return (0);
1290 }
1291 
1292 /*
1293  * Strategy routine for phys. i/o
1294  * If the biod's are running, queue a request
1295  * otherwise just call nfs_doio() to get it done
1296  */
1297 nfs_strategy(bp)
1298 	register struct buf *bp;
1299 {
1300 	register struct buf *dp;
1301 	register int i;
1302 	struct proc *rp;
1303 	int error = 0;
1304 	int fnd = 0;
1305 
1306 	/*
1307 	 * If an i/o daemon is waiting
1308 	 * queue the request, wake it up and wait for completion
1309 	 * otherwise just do it ourselves
1310 	 */
1311 	for (i = 0; i < nfs_asyncdaemons; i++) {
1312 		if (rp = nfs_iodwant[i]) {
1313 			/*
1314 			 * Ensure that the async_daemon is still waiting here
1315 			 */
1316 			if (rp->p_stat != SSLEEP ||
1317 			    rp->p_wchan != ((caddr_t)&nfs_iodwant[i])) {
1318 				nfs_iodwant[i] = (struct proc *)0;
1319 				continue;
1320 			}
1321 			dp = &nfs_bqueue;
1322 			if (dp->b_actf == NULL) {
1323 				dp->b_actl = bp;
1324 				bp->b_actf = dp;
1325 			} else {
1326 				dp->b_actf->b_actl = bp;
1327 				bp->b_actf = dp->b_actf;
1328 			}
1329 			dp->b_actf = bp;
1330 			bp->b_actl = dp;
1331 			fnd++;
1332 			nfs_iodwant[i] = (struct proc *)0;
1333 			wakeup((caddr_t)&nfs_iodwant[i]);
1334 			break;
1335 		}
1336 	}
1337 	if (!fnd)
1338 		error = nfs_doio(bp);
1339 	return (error);
1340 }
1341 
1342 /*
1343  * Fun and games with i/o
1344  * Essentially play ubasetup() and disk interrupt service routine by
1345  * mapping the data buffer into kernel virtual space and doing the
1346  * nfs read or write rpc's from it.
1347  * If the biod's are not running, this is just called from nfs_strategy(),
1348  * otherwise it is called by the biod's to do what would normally be
1349  * partially disk interrupt driven.
1350  */
1351 nfs_doio(bp)
1352 	register struct buf *bp;
1353 {
1354 	register struct pte *pte, *ppte;
1355 	register caddr_t vaddr;
1356 	register struct uio *uiop;
1357 	register struct vnode *vp;
1358 	struct nfsnode *np;
1359 	struct ucred *cr;
1360 	int npf, npf2;
1361 	int reg;
1362 	caddr_t vbase;
1363 	unsigned v;
1364 	struct proc *rp;
1365 	int o, error;
1366 	struct uio uio;
1367 	struct iovec io;
1368 
1369 	vp = bp->b_vp;
1370 	np = VTONFS(vp);
1371 	uiop = &uio;
1372 	uiop->uio_iov = &io;
1373 	uiop->uio_iovcnt = 1;
1374 	uiop->uio_segflg = UIO_SYSSPACE;
1375 
1376 	/*
1377 	 * For phys i/o, map the b_addr into kernel virtual space using
1378 	 * the Nfsiomap pte's
1379 	 * Also, add a temporary b_rcred for reading using the process's uid
1380 	 * and a guess at a group
1381 	 */
1382 	if (bp->b_flags & B_PHYS) {
1383 		np->n_flag |= NPAGEDON;
1384 		bp->b_rcred = cr = crget();
1385 		rp = (bp->b_flags & B_DIRTY) ? &proc[2] : bp->b_proc;
1386 		cr->cr_uid = rp->p_uid;
1387 		cr->cr_gid = 0;		/* Anything ?? */
1388 		cr->cr_ngroups = 1;
1389 		o = (int)bp->b_un.b_addr & PGOFSET;
1390 		npf2 = npf = btoc(bp->b_bcount + o);
1391 
1392 		/*
1393 		 * Get some mapping page table entries
1394 		 */
1395 		while ((reg = rmalloc(nfsmap, (long)npf)) == 0) {
1396 			nfsmap_want++;
1397 			sleep((caddr_t)&nfsmap_want, PZERO-1);
1398 		}
1399 		reg--;
1400 		if (bp->b_flags & B_PAGET)
1401 			pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
1402 		else {
1403 			v = btop(bp->b_un.b_addr);
1404 			if (bp->b_flags & B_UAREA)
1405 				pte = &rp->p_addr[v];
1406 			else
1407 				pte = vtopte(rp, v);
1408 		}
1409 
1410 		/*
1411 		 * Play vmaccess() but with the Nfsiomap page table
1412 		 */
1413 		ppte = &Nfsiomap[reg];
1414 		vbase = vaddr = &nfsiobuf[reg*NBPG];
1415 		while (npf != 0) {
1416 			mapin(ppte, (u_int)vaddr, pte->pg_pfnum, (int)(PG_V|PG_KW));
1417 #if defined(tahoe)
1418 			mtpr(P1DC, vaddr);
1419 #endif
1420 			ppte++;
1421 			pte++;
1422 			vaddr += NBPG;
1423 			--npf;
1424 		}
1425 
1426 		/*
1427 		 * And do the i/o rpc
1428 		 */
1429 		io.iov_base = vbase+o;
1430 		io.iov_len = uiop->uio_resid = bp->b_bcount;
1431 		uiop->uio_offset = bp->b_blkno * DEV_BSIZE;
1432 		if (bp->b_flags & B_READ) {
1433 			uiop->uio_rw = UIO_READ;
1434 			nfsstats.read_physios++;
1435 			bp->b_error = error = nfs_readrpc(vp, uiop, bp->b_rcred);
1436 			/*
1437 			 * If a text file has been modified since it was exec'd
1438 			 * blow the process' out of the water. This is the
1439 			 * closest we can come to "Text File Busy" in good old
1440 			 * stateless nfs.
1441 			 */
1442 			if ((vp->v_flag & VTEXT) &&
1443 			    (vp->v_text->x_mtime != np->n_vattr.va_mtime.tv_sec))
1444 				xinval(vp);
1445 		} else {
1446 			uiop->uio_rw = UIO_WRITE;
1447 			nfsstats.write_physios++;
1448 			bp->b_error = error = nfs_writerpc(vp, uiop, bp->b_wcred);
1449 		}
1450 
1451 		/*
1452 		 * Finally, release pte's used by physical i/o
1453 		 */
1454 		crfree(cr);
1455 		rmfree(nfsmap, (long)npf2, (long)++reg);
1456 		if (nfsmap_want) {
1457 			nfsmap_want = 0;
1458 			wakeup((caddr_t)&nfsmap_want);
1459 		}
1460 	} else {
1461 		if (bp->b_flags & B_READ) {
1462 			io.iov_len = uiop->uio_resid = bp->b_bcount;
1463 			uiop->uio_offset = bp->b_blkno * DEV_BSIZE;
1464 			io.iov_base = bp->b_un.b_addr;
1465 			uiop->uio_rw = UIO_READ;
1466 			nfsstats.read_bios++;
1467 			bp->b_error = error = nfs_readrpc(vp, uiop, bp->b_rcred);
1468 		} else {
1469 			io.iov_len = uiop->uio_resid = bp->b_dirtyend
1470 				- bp->b_dirtyoff;
1471 			uiop->uio_offset = (bp->b_blkno * DEV_BSIZE)
1472 				+ bp->b_dirtyoff;
1473 			io.iov_base = bp->b_un.b_addr + bp->b_dirtyoff;
1474 			uiop->uio_rw = UIO_WRITE;
1475 			nfsstats.write_bios++;
1476 			bp->b_error = error = nfs_writerpc(vp, uiop, bp->b_wcred);
1477 			if (error) {
1478 				np->n_error = error;
1479 				np->n_flag |= NWRITEERR;
1480 			}
1481 			bp->b_dirtyoff = bp->b_dirtyend = 0;
1482 		}
1483 	}
1484 	if (error)
1485 		bp->b_flags |= B_ERROR;
1486 	bp->b_resid = uiop->uio_resid;
1487 	biodone(bp);
1488 	return (error);
1489 }
1490 
1491 /*
1492  * Flush all the blocks associated with a vnode.
1493  * 	Walk through the buffer pool and push any dirty pages
1494  *	associated with the vnode.
1495  */
1496 /* ARGSUSED */
1497 nfs_fsync(vp, fflags, cred, waitfor)
1498 	register struct vnode *vp;
1499 	int fflags;
1500 	struct ucred *cred;
1501 	int waitfor;
1502 {
1503 	register struct nfsnode *np = VTONFS(vp);
1504 	int error = 0;
1505 
1506 	if (np->n_flag & NMODIFIED) {
1507 		np->n_flag &= ~NMODIFIED;
1508 		vflushbuf(vp, waitfor == MNT_WAIT ? B_SYNC : 0);
1509 	}
1510 	if (!error && (np->n_flag & NWRITEERR))
1511 		error = np->n_error;
1512 	return (error);
1513 }
1514 
1515 /*
1516  * Print out the contents of an nfsnode.
1517  */
1518 nfs_print(vp)
1519 	struct vnode *vp;
1520 {
1521 	register struct nfsnode *np = VTONFS(vp);
1522 
1523 	printf("tag VT_NFS, fileid %d fsid 0x%x%s\n",
1524 		np->n_vattr.va_fileid, np->n_vattr.va_fsid,
1525 		(np->n_flag & NLOCKED) ? " (LOCKED)" : "");
1526 	if (np->n_lockholder == 0)
1527 		return;
1528 	printf("\towner pid %d", np->n_lockholder);
1529 	if (np->n_lockwaiter)
1530 		printf(" waiting pid %d", np->n_lockwaiter);
1531 	printf("\n");
1532 }
1533