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