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