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