Annotation of 43BSDReno/sys/nfs/nfs_syscalls.c, revision 1.1.1.1

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 is only permitted until one year after the first shipment
                      9:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                     10:  * binary forms are permitted provided that: (1) source distributions retain
                     11:  * this entire copyright notice and comment, and (2) distributions including
                     12:  * binaries display the following acknowledgement:  This product includes
                     13:  * software developed by the University of California, Berkeley and its
                     14:  * contributors'' in the documentation or other materials provided with the
                     15:  * distribution and in all advertising materials mentioning features or use
                     16:  * of this software.  Neither the name of the University nor the names of
                     17:  * its contributors may be used to endorse or promote products derived from
                     18:  * this software without specific prior written permission.
                     19:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     20:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     21:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     22:  *
                     23:  *     @(#)nfs_syscalls.c      7.18 (Berkeley) 6/28/90
                     24:  */
                     25: 
                     26: #include "param.h"
                     27: #include "systm.h"
                     28: #include "user.h"
                     29: #include "kernel.h"
                     30: #include "file.h"
                     31: #include "stat.h"
                     32: #include "vnode.h"
                     33: #include "mount.h"
                     34: #include "proc.h"
                     35: #include "uio.h"
                     36: #include "malloc.h"
                     37: #include "buf.h"
                     38: #include "mbuf.h"
                     39: #include "socket.h"
                     40: #include "socketvar.h"
                     41: #include "domain.h"
                     42: #include "protosw.h"
                     43: #include "../netinet/in.h"
                     44: #include "../netinet/tcp.h"
                     45: #include "nfsv2.h"
                     46: #include "nfs.h"
                     47: #include "nfsrvcache.h"
                     48: 
                     49: /* Global defs. */
                     50: extern u_long nfs_prog, nfs_vers;
                     51: extern int (*nfsrv_procs[NFS_NPROCS])();
                     52: extern struct buf nfs_bqueue;
                     53: extern int nfs_asyncdaemons;
                     54: extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON];
                     55: extern int nfs_tcpnodelay;
                     56: struct file *getsock();
                     57: 
                     58: #define        TRUE    1
                     59: #define        FALSE   0
                     60: 
                     61: /*
                     62:  * NFS server system calls
                     63:  * getfh() lives here too, but maybe should move to kern/vfs_syscalls.c
                     64:  */
                     65: 
                     66: /*
                     67:  * Get file handle system call
                     68:  */
                     69: /* ARGSUSED */
                     70: getfh(p, uap, retval)
                     71:        struct proc *p;
                     72:        register struct args {
                     73:                char    *fname;
                     74:                fhandle_t *fhp;
                     75:        } *uap;
                     76:        int *retval;
                     77: {
                     78:        register struct nameidata *ndp = &u.u_nd;
                     79:        register struct vnode *vp;
                     80:        fhandle_t fh;
                     81:        int error;
                     82: 
                     83:        /*
                     84:         * Must be super user
                     85:         */
                     86:        if (error = suser(ndp->ni_cred, &u.u_acflag))
                     87:                return (error);
                     88:        ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW;
                     89:        ndp->ni_segflg = UIO_USERSPACE;
                     90:        ndp->ni_dirp = uap->fname;
                     91:        if (error = namei(ndp))
                     92:                return (error);
                     93:        vp = ndp->ni_vp;
                     94:        bzero((caddr_t)&fh, sizeof(fh));
                     95:        fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
                     96:        error = VFS_VPTOFH(vp, &fh.fh_fid);
                     97:        vput(vp);
                     98:        if (error)
                     99:                return (error);
                    100:        error = copyout((caddr_t)&fh, (caddr_t)uap->fhp, sizeof (fh));
                    101:        return (error);
                    102: }
                    103: 
                    104: /*
                    105:  * Nfs server psuedo system call for the nfsd's
                    106:  * Never returns unless it fails or gets killed
                    107:  */
                    108: /* ARGSUSED */
                    109: nfssvc(p, uap, retval)
                    110:        struct proc *p;
                    111:        register struct args {
                    112:                int s;
                    113:                caddr_t mskval;
                    114:                int msklen;
                    115:                caddr_t mtchval;
                    116:                int mtchlen;
                    117:        } *uap;
                    118:        int *retval;
                    119: {
                    120:        register struct mbuf *m;
                    121:        register int siz;
                    122:        register struct ucred *cr;
                    123:        struct file *fp;
                    124:        struct mbuf *mreq, *mrep, *nam, *md;
                    125:        struct mbuf msk, mtch;
                    126:        struct socket *so;
                    127:        caddr_t dpos;
                    128:        int procid, repstat, error, cacherep;
                    129:        u_long retxid;
                    130: 
                    131:        /*
                    132:         * Must be super user
                    133:         */
                    134:        if (error = suser(u.u_cred, &u.u_acflag))
                    135:                goto bad;
                    136:        fp = getsock(uap->s);
                    137:        if (fp == 0)
                    138:                return;
                    139:        so = (struct socket *)fp->f_data;
                    140:        if (sosendallatonce(so))
                    141:                siz = NFS_MAXPACKET;
                    142:        else
                    143:                siz = NFS_MAXPACKET + sizeof(u_long);
                    144:        if (error = soreserve(so, siz, siz))
                    145:                goto bad;
                    146:        if (error = sockargs(&nam, uap->mskval, uap->msklen, MT_SONAME))
                    147:                goto bad;
                    148:        bcopy((caddr_t)nam, (caddr_t)&msk, sizeof (struct mbuf));
                    149:        msk.m_data = msk.m_dat;
                    150:        m_freem(nam);
                    151:        if (error = sockargs(&nam, uap->mtchval, uap->mtchlen, MT_SONAME))
                    152:                goto bad;
                    153:        bcopy((caddr_t)nam, (caddr_t)&mtch, sizeof (struct mbuf));
                    154:        mtch.m_data = mtch.m_dat;
                    155:        m_freem(nam);
                    156: 
                    157:        /* Copy the cred so others don't see changes */
                    158:        cr = u.u_cred = crcopy(u.u_cred);
                    159: 
                    160:        /*
                    161:         * Set protocol specific options { for now TCP only } and
                    162:         * reserve some space. For datagram sockets, this can get called
                    163:         * repeatedly for the same socket, but that isn't harmful.
                    164:         */
                    165:        if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
                    166:                MGET(m, M_WAIT, MT_SOOPTS);
                    167:                *mtod(m, int *) = 1;
                    168:                m->m_len = sizeof(int);
                    169:                sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m);
                    170:        }
                    171:        if (so->so_proto->pr_domain->dom_family == AF_INET &&
                    172:            so->so_proto->pr_protocol == IPPROTO_TCP &&
                    173:            nfs_tcpnodelay) {
                    174:                MGET(m, M_WAIT, MT_SOOPTS);
                    175:                *mtod(m, int *) = 1;
                    176:                m->m_len = sizeof(int);
                    177:                sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m);
                    178:        }
                    179:        so->so_rcv.sb_flags &= ~SB_NOINTR;
                    180:        so->so_rcv.sb_timeo = 0;
                    181:        so->so_snd.sb_flags &= ~SB_NOINTR;
                    182:        so->so_snd.sb_timeo = 0;
                    183: 
                    184:        /*
                    185:         * Just loop around doin our stuff until SIGKILL
                    186:         */
                    187:        for (;;) {
                    188:                if (error = nfs_getreq(so, nfs_prog, nfs_vers, NFS_NPROCS-1,
                    189:                   &nam, &mrep, &md, &dpos, &retxid, &procid, cr,
                    190:                   &msk, &mtch)) {
                    191:                        if (nam)
                    192:                                m_freem(nam);
                    193:                        if (error == EPIPE || error == EINTR ||
                    194:                            error == ERESTART) {
                    195:                                error = 0;
                    196:                                goto bad;
                    197:                        }
                    198:                        so->so_error = 0;
                    199:                        continue;
                    200:                }
                    201: 
                    202:                if (nam)
                    203:                        cacherep = nfsrv_getcache(nam, retxid, procid, &mreq);
                    204:                else
                    205:                        cacherep = RC_DOIT;
                    206:                switch (cacherep) {
                    207:                case RC_DOIT:
                    208:                        if (error = (*(nfsrv_procs[procid]))(mrep, md, dpos,
                    209:                                cr, retxid, &mreq, &repstat)) {
                    210:                                nfsstats.srv_errs++;
                    211:                                if (nam) {
                    212:                                        nfsrv_updatecache(nam, retxid, procid,
                    213:                                                FALSE, repstat, mreq);
                    214:                                        m_freem(nam);
                    215:                                }
                    216:                                break;
                    217:                        }
                    218:                        nfsstats.srvrpccnt[procid]++;
                    219:                        if (nam)
                    220:                                nfsrv_updatecache(nam, retxid, procid, TRUE,
                    221:                                        repstat, mreq);
                    222:                        mrep = (struct mbuf *)0;
                    223:                case RC_REPLY:
                    224:                        m = mreq;
                    225:                        siz = 0;
                    226:                        while (m) {
                    227:                                siz += m->m_len;
                    228:                                m = m->m_next;
                    229:                        }
                    230:                        if (siz <= 0 || siz > NFS_MAXPACKET) {
                    231:                                printf("mbuf siz=%d\n",siz);
                    232:                                panic("Bad nfs svc reply");
                    233:                        }
                    234:                        mreq->m_pkthdr.len = siz;
                    235:                        mreq->m_pkthdr.rcvif = (struct ifnet *)0;
                    236:                        /*
                    237:                         * For non-atomic protocols, prepend a Sun RPC
                    238:                         * Record Mark.
                    239:                         */
                    240:                        if (!sosendallatonce(so)) {
                    241:                                M_PREPEND(mreq, sizeof(u_long), M_WAIT);
                    242:                                *mtod(mreq, u_long *) = htonl(0x80000000 | siz);
                    243:                        }
                    244:                        error = nfs_send(so, nam, mreq, (struct nfsreq *)0);
                    245:                        if (nam)
                    246:                                m_freem(nam);
                    247:                        if (mrep)
                    248:                                m_freem(mrep);
                    249:                        if (error) {
                    250:                                if (error == EPIPE || error == EINTR ||
                    251:                                    error == ERESTART)
                    252:                                        goto bad;
                    253:                                so->so_error = 0;
                    254:                        }
                    255:                        break;
                    256:                case RC_DROPIT:
                    257:                        m_freem(mrep);
                    258:                        m_freem(nam);
                    259:                        break;
                    260:                };
                    261:        }
                    262: bad:
                    263:        return (error);
                    264: }
                    265: 
                    266: /*
                    267:  * Nfs pseudo system call for asynchronous i/o daemons.
                    268:  * These babies just pretend to be disk interrupt service routines
                    269:  * for client nfs. They are mainly here for read ahead/write behind.
                    270:  * Never returns unless it fails or gets killed
                    271:  */
                    272: /* ARGSUSED */
                    273: async_daemon(p, uap, retval)
                    274:        struct proc *p;
                    275:        struct args *uap;
                    276:        int *retval;
                    277: {
                    278:        register struct buf *bp, *dp;
                    279:        int error;
                    280:        int myiod;
                    281: 
                    282:        /*
                    283:         * Must be super user
                    284:         */
                    285:        if (error = suser(u.u_cred, &u.u_acflag))
                    286:                return (error);
                    287:        /*
                    288:         * Assign my position or return error if too many already running
                    289:         */
                    290:        if (nfs_asyncdaemons > NFS_MAXASYNCDAEMON)
                    291:                return (EBUSY);
                    292:        myiod = nfs_asyncdaemons++;
                    293:        dp = &nfs_bqueue;
                    294:        /*
                    295:         * Just loop around doin our stuff until SIGKILL
                    296:         */
                    297:        for (;;) {
                    298:                while (dp->b_actf == NULL) {
                    299:                        nfs_iodwant[myiod] = p;
                    300:                        if (error = tsleep((caddr_t)&nfs_iodwant[myiod],
                    301:                                PWAIT | PCATCH, "nfsidl", 0))
                    302:                                return (error);
                    303:                }
                    304:                /* Take one off the end of the list */
                    305:                bp = dp->b_actl;
                    306:                if (bp->b_actl == dp) {
                    307:                        dp->b_actf = dp->b_actl = (struct buf *)0;
                    308:                } else {
                    309:                        dp->b_actl = bp->b_actl;
                    310:                        bp->b_actl->b_actf = dp;
                    311:                }
                    312:                (void) nfs_doio(bp);
                    313:        }
                    314: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.