|
|
1.1 root 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: * @(#)nfs_syscalls.c 7.26 (Berkeley) 4/16/91
1.1.1.2 ! root 37: *
! 38: * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
! 39: * -------------------- ----- ----------------------
! 40: * CURRENT PATCH LEVEL: 1 00053
! 41: * -------------------- ----- ----------------------
! 42: *
! 43: * 08 Sep 92 Rick "gopher I" Fix "reserved port" bug, fixed for
! 44: * AIX3.2 NFS clients
1.1 root 45: */
46:
47: #include "param.h"
48: #include "systm.h"
49: #include "kernel.h"
50: #include "file.h"
51: #include "stat.h"
52: #include "namei.h"
53: #include "vnode.h"
54: #include "mount.h"
55: #include "proc.h"
56: #include "malloc.h"
57: #include "buf.h"
58: #include "mbuf.h"
59: #include "socket.h"
60: #include "socketvar.h"
61: #include "domain.h"
62: #include "protosw.h"
63:
64: #include "../netinet/in.h"
65: #include "../netinet/tcp.h"
66:
67: #include "nfsv2.h"
68: #include "nfs.h"
69: #include "nfsrvcache.h"
70:
71: /* Global defs. */
72: extern u_long nfs_prog, nfs_vers;
73: extern int (*nfsrv_procs[NFS_NPROCS])();
74: extern struct buf nfs_bqueue;
75: extern int nfs_numasync;
76: extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON];
77: extern int nfs_tcpnodelay;
78: struct mbuf *nfs_compress();
79:
80: #define TRUE 1
81: #define FALSE 0
82:
83: static int nfs_asyncdaemon[NFS_MAXASYNCDAEMON];
84: static int compressreply[NFS_NPROCS] = {
85: FALSE,
86: TRUE,
87: TRUE,
88: FALSE,
89: TRUE,
90: TRUE,
91: FALSE,
92: FALSE,
93: TRUE,
94: TRUE,
95: TRUE,
96: TRUE,
97: TRUE,
98: TRUE,
99: TRUE,
100: TRUE,
101: TRUE,
102: TRUE,
103: };
1.1.1.2 ! root 104:
! 105: #ifdef NFSCLIENT
! 106:
1.1 root 107: /*
108: * NFS server system calls
109: * getfh() lives here too, but maybe should move to kern/vfs_syscalls.c
110: */
111:
112: /*
113: * Get file handle system call
114: */
115: /* ARGSUSED */
116: getfh(p, uap, retval)
117: struct proc *p;
118: register struct args {
119: char *fname;
120: fhandle_t *fhp;
121: } *uap;
122: int *retval;
123: {
124: register struct nameidata *ndp;
125: register struct vnode *vp;
126: fhandle_t fh;
127: int error;
128: struct nameidata nd;
129:
130: /*
131: * Must be super user
132: */
133: if (error = suser(p->p_ucred, &p->p_acflag))
134: return (error);
135: ndp = &nd;
136: ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW;
137: ndp->ni_segflg = UIO_USERSPACE;
138: ndp->ni_dirp = uap->fname;
139: if (error = namei(ndp, p))
140: return (error);
141: vp = ndp->ni_vp;
142: bzero((caddr_t)&fh, sizeof(fh));
143: fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
144: error = VFS_VPTOFH(vp, &fh.fh_fid);
145: vput(vp);
146: if (error)
147: return (error);
148: error = copyout((caddr_t)&fh, (caddr_t)uap->fhp, sizeof (fh));
149: return (error);
150: }
151:
1.1.1.2 ! root 152: #endif /*NFSCLIENT*/
! 153:
! 154: #ifdef NFSSERVER
! 155:
1.1 root 156: /*
157: * Nfs server psuedo system call for the nfsd's
158: * Never returns unless it fails or gets killed
159: */
160: /* ARGSUSED */
161: nfssvc(p, uap, retval)
162: struct proc *p;
163: register struct args {
164: int s;
165: caddr_t mskval;
166: int msklen;
167: caddr_t mtchval;
168: int mtchlen;
169: } *uap;
170: int *retval;
171: {
172: register struct mbuf *m;
173: register int siz;
174: register struct ucred *cr;
175: struct file *fp;
176: struct mbuf *mreq, *mrep, *nam, *md;
177: struct mbuf msk, mtch;
178: struct socket *so;
179: caddr_t dpos;
180: int procid, repstat, error, cacherep, wascomp;
181: u_long retxid;
182:
183: /*
184: * Must be super user
185: */
186: if (error = suser(p->p_ucred, &p->p_acflag))
187: return (error);
188: if (error = getsock(p->p_fd, uap->s, &fp))
189: return (error);
190: so = (struct socket *)fp->f_data;
191: if (sosendallatonce(so))
192: siz = NFS_MAXPACKET;
193: else
194: siz = NFS_MAXPACKET + sizeof(u_long);
195: if (error = soreserve(so, siz, siz))
196: goto bad;
197: if (error = sockargs(&nam, uap->mskval, uap->msklen, MT_SONAME))
198: goto bad;
199: bcopy((caddr_t)nam, (caddr_t)&msk, sizeof (struct mbuf));
200: msk.m_data = msk.m_dat;
201: m_freem(nam);
202: if (error = sockargs(&nam, uap->mtchval, uap->mtchlen, MT_SONAME))
203: goto bad;
204: bcopy((caddr_t)nam, (caddr_t)&mtch, sizeof (struct mbuf));
205: mtch.m_data = mtch.m_dat;
206: m_freem(nam);
207:
208: /* Copy the cred so others don't see changes */
209: cr = p->p_ucred = crcopy(p->p_ucred);
210:
211: /*
212: * Set protocol specific options { for now TCP only } and
213: * reserve some space. For datagram sockets, this can get called
214: * repeatedly for the same socket, but that isn't harmful.
215: */
216: if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
217: MGET(m, M_WAIT, MT_SOOPTS);
218: *mtod(m, int *) = 1;
219: m->m_len = sizeof(int);
220: sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m);
221: }
222: if (so->so_proto->pr_domain->dom_family == AF_INET &&
223: so->so_proto->pr_protocol == IPPROTO_TCP &&
224: nfs_tcpnodelay) {
225: MGET(m, M_WAIT, MT_SOOPTS);
226: *mtod(m, int *) = 1;
227: m->m_len = sizeof(int);
228: sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m);
229: }
230: so->so_rcv.sb_flags &= ~SB_NOINTR;
231: so->so_rcv.sb_timeo = 0;
232: so->so_snd.sb_flags &= ~SB_NOINTR;
233: so->so_snd.sb_timeo = 0;
234:
235: /*
236: * Just loop around doin our stuff until SIGKILL
237: */
238: for (;;) {
239: if (error = nfs_getreq(so, nfs_prog, nfs_vers, NFS_NPROCS-1,
240: &nam, &mrep, &md, &dpos, &retxid, &procid, cr,
1.1.1.2 ! root 241: /* 08 Sep 92*/ &msk, &mtch, &wascomp, &repstat)) {
1.1 root 242: if (nam)
243: m_freem(nam);
244: if (error == EPIPE || error == EINTR ||
245: error == ERESTART) {
246: error = 0;
247: goto bad;
248: }
249: so->so_error = 0;
250: continue;
251: }
252:
253: if (nam)
254: cacherep = nfsrv_getcache(nam, retxid, procid, &mreq);
255: else
256: cacherep = RC_DOIT;
257: switch (cacherep) {
258: case RC_DOIT:
259: if (error = (*(nfsrv_procs[procid]))(mrep, md, dpos,
260: cr, retxid, &mreq, &repstat, p)) {
261: nfsstats.srv_errs++;
262: if (nam) {
263: nfsrv_updatecache(nam, retxid, procid,
264: FALSE, repstat, mreq);
265: m_freem(nam);
266: }
267: break;
268: }
269: nfsstats.srvrpccnt[procid]++;
270: if (nam)
271: nfsrv_updatecache(nam, retxid, procid, TRUE,
272: repstat, mreq);
273: mrep = (struct mbuf *)0;
274: case RC_REPLY:
275: m = mreq;
276: siz = 0;
277: while (m) {
278: siz += m->m_len;
279: m = m->m_next;
280: }
281: if (siz <= 0 || siz > NFS_MAXPACKET) {
282: printf("mbuf siz=%d\n",siz);
283: panic("Bad nfs svc reply");
284: }
285: mreq->m_pkthdr.len = siz;
286: mreq->m_pkthdr.rcvif = (struct ifnet *)0;
287: if (wascomp && compressreply[procid]) {
288: mreq = nfs_compress(mreq);
289: siz = mreq->m_pkthdr.len;
290: }
291: /*
292: * For non-atomic protocols, prepend a Sun RPC
293: * Record Mark.
294: */
295: if (!sosendallatonce(so)) {
296: M_PREPEND(mreq, sizeof(u_long), M_WAIT);
297: *mtod(mreq, u_long *) = htonl(0x80000000 | siz);
298: }
299: error = nfs_send(so, nam, mreq, (struct nfsreq *)0);
300: if (nam)
301: m_freem(nam);
302: if (mrep)
303: m_freem(mrep);
304: if (error) {
305: if (error == EPIPE || error == EINTR ||
306: error == ERESTART)
307: goto bad;
308: so->so_error = 0;
309: }
310: break;
311: case RC_DROPIT:
312: m_freem(mrep);
313: m_freem(nam);
314: break;
315: };
316: }
317: bad:
318: return (error);
319: }
320:
1.1.1.2 ! root 321: #endif /* NFSSERVER */
! 322:
! 323: #ifdef NFSCLIENT
! 324:
1.1 root 325: /*
326: * Nfs pseudo system call for asynchronous i/o daemons.
327: * These babies just pretend to be disk interrupt service routines
328: * for client nfs. They are mainly here for read ahead/write behind.
329: * Never returns unless it fails or gets killed
330: */
331: /* ARGSUSED */
332: async_daemon(p, uap, retval)
333: struct proc *p;
334: struct args *uap;
335: int *retval;
336: {
337: register struct buf *bp, *dp;
338: register int i, myiod;
339: int error;
340:
341: /*
342: * Must be super user
343: */
344: if (error = suser(p->p_ucred, &p->p_acflag))
345: return (error);
346: /*
347: * Assign my position or return error if too many already running
348: */
349: myiod = -1;
350: for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
351: if (nfs_asyncdaemon[i] == 0) {
352: nfs_asyncdaemon[i]++;
353: myiod = i;
354: break;
355: }
356: if (myiod == -1)
357: return (EBUSY);
358: nfs_numasync++;
359: dp = &nfs_bqueue;
360: /*
361: * Just loop around doin our stuff until SIGKILL
362: */
363: for (;;) {
364: while (dp->b_actf == NULL && error == 0) {
365: nfs_iodwant[myiod] = p;
366: error = tsleep((caddr_t)&nfs_iodwant[myiod],
367: PWAIT | PCATCH, "nfsidl", 0);
368: nfs_iodwant[myiod] = (struct proc *)0;
369: }
370: while (dp->b_actf != NULL) {
371: /* Take one off the end of the list */
372: bp = dp->b_actl;
373: if (bp->b_actl == dp) {
374: dp->b_actf = dp->b_actl = (struct buf *)0;
375: } else {
376: dp->b_actl = bp->b_actl;
377: bp->b_actl->b_actf = dp;
378: }
379: (void) nfs_doio(bp);
380: }
381: if (error) {
382: nfs_asyncdaemon[myiod] = 0;
383: nfs_numasync--;
384: return (error);
385: }
386: }
387: }
1.1.1.2 ! root 388:
! 389: #endif /* NFSCLIENT*/
! 390:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.