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