kernel - use new td_ucred in numerous places
[dragonfly.git] / sys / vfs / nfs / nfs_syscalls.c
index 1acd9a4..2058282 100644 (file)
 
 static MALLOC_DEFINE(M_NFSSVC, "NFS srvsock", "Nfs server structure");
 
-/* Global defs. */
-extern int32_t (*nfsrv3_procs[NFS_NPROCS]) (struct nfsrv_descript *nd,
-                                           struct nfssvc_sock *slp,
-                                           struct thread *td,
-                                           struct mbuf **mreqp);
-extern int nfs_numasync;
-extern int nfsrtton;
-extern struct nfsstats nfsstats;
-extern int nfsrvw_procrastinate;
-extern int nfsrvw_procrastinate_v3;
 static int nuidhash_max = NFS_MAXUIDHASH;
 
 #ifndef NFS_NOSERVER
 static void    nfsrv_zapsock (struct nfssvc_sock *slp);
 #endif
-static int     nfssvc_iod (struct thread *);
 
 #define        TRUE    1
 #define        FALSE   0
 
-static int nfs_asyncdaemon[NFS_MAXASYNCDAEMON];
-
 SYSCTL_DECL(_vfs_nfs);
 
 #ifndef NFS_NOSERVER
@@ -117,7 +104,7 @@ static int nfs_privport = 0;
 SYSCTL_INT(_vfs_nfs, NFS_NFSPRIVPORT, nfs_privport, CTLFLAG_RW, &nfs_privport, 0, "");
 SYSCTL_INT(_vfs_nfs, OID_AUTO, gatherdelay, CTLFLAG_RW, &nfsrvw_procrastinate, 0, "");
 SYSCTL_INT(_vfs_nfs, OID_AUTO, gatherdelay_v3, CTLFLAG_RW, &nfsrvw_procrastinate_v3, 0, "");
-static int     nfs_soreserve = 65535;
+int    nfs_soreserve = NFS_MAXPACKET * NFS_MAXASYNCBIO;
 SYSCTL_INT(_vfs_nfs, OID_AUTO, soreserve, CTLFLAG_RW, &nfs_soreserve, 0, "");
 
 /*
@@ -133,6 +120,8 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, soreserve, CTLFLAG_RW, &nfs_soreserve, 0, "");
  * - adds a socket to the selection list
  * - remains in the kernel as an nfsd
  * - remains in the kernel as an nfsiod
+ *
+ * MPALMOSTSAFE
  */
 int
 sys_nfssvc(struct nfssvc_args *uap)
@@ -157,15 +146,16 @@ sys_nfssvc(struct nfssvc_args *uap)
         * Must be super user
         */
        error = priv_check(td, PRIV_ROOT);
-       if(error)
+       if (error)
                return (error);
-       KKASSERT(td->td_proc);  /* for ucred and p_fd */
+
+       get_mplock();
        while (nfssvc_sockhead_flag & SLP_INIT) {
-                nfssvc_sockhead_flag |= SLP_WANTINIT;
-               (void) tsleep((caddr_t)&nfssvc_sockhead, 0, "nfsd init", 0);
+               nfssvc_sockhead_flag |= SLP_WANTINIT;
+               tsleep((caddr_t)&nfssvc_sockhead, 0, "nfsd init", 0);
        }
        if (uap->flag & NFSSVC_BIOD)
-               error = nfssvc_iod(td);
+               error = ENXIO;          /* no longer need nfsiod's */
 #ifdef NFS_NOSERVER
        else
                error = ENXIO;
@@ -173,7 +163,7 @@ sys_nfssvc(struct nfssvc_args *uap)
        else if (uap->flag & NFSSVC_MNTD) {
                error = copyin(uap->argp, (caddr_t)&ncd, sizeof (ncd));
                if (error)
-                       return (error);
+                       goto done;
                vp = NULL;
                error = nlookup_init(&nd, ncd.ncd_dirp, UIO_USERSPACE, 
                                        NLC_FOLLOW);
@@ -183,27 +173,29 @@ sys_nfssvc(struct nfssvc_args *uap)
                        error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp);   
                nlookup_done(&nd);
                if (error)
-                       return (error);
+                       goto done;
 
                if ((vp->v_flag & VROOT) == 0)
                        error = EINVAL;
                nmp = VFSTONFS(vp->v_mount);
                vput(vp);
                if (error)
-                       return (error);
+                       goto done;
                if ((nmp->nm_state & NFSSTA_MNTD) &&
-                       (uap->flag & NFSSVC_GOTAUTH) == 0)
-                       return (0);
+                       (uap->flag & NFSSVC_GOTAUTH) == 0) {
+                       error = 0;
+                       goto done;
+               }
                nmp->nm_state |= NFSSTA_MNTD;
-               error = nfs_clientd(nmp, td->td_proc->p_ucred, &ncd, uap->flag,
+               error = nfs_clientd(nmp, td->td_ucred, &ncd, uap->flag,
                                    uap->argp, td);
        } else if (uap->flag & NFSSVC_ADDSOCK) {
                error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg));
                if (error)
-                       return (error);
+                       goto done;
                error = holdsock(td->td_proc->p_fd, nfsdarg.sock, &fp);
                if (error)
-                       return (error);
+                       goto done;
                /*
                 * Get the client address for connected sockets.
                 */
@@ -214,7 +206,7 @@ sys_nfssvc(struct nfssvc_args *uap)
                                            nfsdarg.namelen);
                        if (error) {
                                fdrop(fp);
-                               return (error);
+                               goto done;
                        }
                }
                error = nfssvc_addsock(fp, nam, td);
@@ -222,7 +214,7 @@ sys_nfssvc(struct nfssvc_args *uap)
        } else {
                error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd));
                if (error)
-                       return (error);
+                       goto done;
                if ((uap->flag & NFSSVC_AUTHIN) &&
                    ((nfsd = nsd->nsd_nfsd)) != NULL &&
                    (nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
@@ -314,6 +306,8 @@ sys_nfssvc(struct nfssvc_args *uap)
 #endif /* NFS_NOSERVER */
        if (error == EINTR || error == ERESTART)
                error = 0;
+done:
+       rel_mplock();
        return (error);
 }
 
@@ -348,6 +342,9 @@ nfssvc_addsock(struct file *fp, struct sockaddr *mynam, struct thread *td)
         * Reserve buffer space in the socket.  Note that due to bugs in
         * Linux's delayed-ack code, serious performance degredation may
         * occur with linux hosts if the minimum is used.
+        *
+        * NFS sockets are not limited to the standard sb_max or by
+        * resource limits.
         */
        if (so->so_type == SOCK_STREAM)
                siz = NFS_MAXPACKET + sizeof (u_long);
@@ -355,14 +352,8 @@ nfssvc_addsock(struct file *fp, struct sockaddr *mynam, struct thread *td)
                siz = NFS_MAXPACKET;
        if (siz < nfs_soreserve)
            siz = nfs_soreserve;
-       if (siz > sb_max_adj) {
-           kprintf("Warning: vfs.nfs.soreserve (%d) "
-               "limited to adjusted sb_max (%ld)\n",
-               nfs_soreserve, sb_max_adj);
-           siz = sb_max_adj;
-       }
 
-       error = soreserve(so, siz, siz, &td->td_proc->p_rlimit[RLIMIT_SBSIZE]);
+       error = soreserve(so, siz, siz, NULL);
        if (error) {
                if (mynam != NULL)
                        FREE(mynam, M_SONAME);
@@ -885,85 +876,6 @@ nfsd_rt(int sotype, struct nfsrv_descript *nd, int cacherep)
 static int nfs_defect = 0;
 SYSCTL_INT(_vfs_nfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0, "");
 
-/*
- * Asynchronous I/O daemons for client nfs.
- * They do read-ahead and write-behind operations on the block I/O cache.
- * Never returns unless it fails or gets killed.
- */
-static int
-nfssvc_iod(struct thread *td)
-{
-       struct bio *bio;
-       int i, myiod;
-       struct nfsmount *nmp;
-       int error = 0;
-
-       /*
-        * Assign my position or return error if too many already running
-        */
-       myiod = -1;
-       for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
-               if (nfs_asyncdaemon[i] == 0) {
-                       nfs_asyncdaemon[i]++;
-                       myiod = i;
-                       break;
-               }
-       if (myiod == -1)
-               return (EBUSY);
-       nfs_numasync++;
-       /*
-        * Just loop around doin our stuff until SIGKILL
-        */
-       for (;;) {
-           while (((nmp = nfs_iodmount[myiod]) == NULL
-                    || TAILQ_EMPTY(&nmp->nm_bioq))
-                  && error == 0) {
-               if (nmp)
-                   nmp->nm_bioqiods--;
-               nfs_iodwant[myiod] = td;
-               nfs_iodmount[myiod] = NULL;
-               error = tsleep((caddr_t)&nfs_iodwant[myiod],
-                       PCATCH, "nfsidl", 0);
-           }
-           if (error) {
-               nfs_asyncdaemon[myiod] = 0;
-               if (nmp)
-                   nmp->nm_bioqiods--;
-               nfs_iodwant[myiod] = NULL;
-               nfs_iodmount[myiod] = NULL;
-               nfs_numasync--;
-               return (error);
-           }
-           while ((bio = TAILQ_FIRST(&nmp->nm_bioq)) != NULL) {
-               /* 
-                * Take one off the front of the list.   The BIO's
-                * block number is normalized for DEV_BSIZE.
-                */
-               TAILQ_REMOVE(&nmp->nm_bioq, bio, bio_act);
-               nmp->nm_bioqlen--;
-               if (nmp->nm_bioqwant && nmp->nm_bioqlen <= nfs_numasync) {
-                   nmp->nm_bioqwant = FALSE;
-                   wakeup(&nmp->nm_bioq);
-               }
-               nfs_doio((struct vnode *)bio->bio_driver_info, bio, NULL);
-
-               /*
-                * If there are more than one iod on this mount, then defect
-                * so that the iods can be shared out fairly between the mounts
-                */
-               if (nfs_defect && nmp->nm_bioqiods > 1) {
-                   NFS_DPF(ASYNCIO,
-                           ("nfssvc_iod: iod %d defecting from mount %p\n",
-                            myiod, nmp));
-                   nfs_iodmount[myiod] = NULL;
-                   nmp->nm_bioqiods--;
-                   break;
-               }
-           }
-       }
-}
-
-
 /*
  * Get an authorization string for the uid by having the mount_nfs sitting
  * on this mount point porpous out of the kernel and do it.
@@ -1076,6 +988,9 @@ nfs_getnickauth(struct nfsmount *nmp, struct ucred *cred, char **auth_str,
         */
 #ifdef NFSKERB
        XXX
+#else
+       ktvout.tv_sec = 0;
+       ktvout.tv_usec = 0;
 #endif
 
        *verfp++ = ktvout.tv_sec;
@@ -1094,15 +1009,17 @@ nfs_savenickauth(struct nfsmount *nmp, struct ucred *cred, int len,
 {
        struct nfsuid *nuidp;
        u_int32_t *tl;
-       int32_t t1;
-       struct mbuf *md = *mdp;
        struct timeval ktvin, ktvout;
        u_int32_t nick;
-       char *dpos = *dposp, *cp2;
        int deltasec, error = 0;
+       struct nfsm_info info;
+
+       info.md = *mdp;
+       info.dpos = *dposp;
+       info.mrep = mrep;
 
        if (len == (3 * NFSX_UNSIGNED)) {
-               nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
+               NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED));
                ktvin.tv_sec = *tl++;
                ktvin.tv_usec = *tl++;
                nick = fxdr_unsigned(u_int32_t, *tl);
@@ -1112,6 +1029,9 @@ nfs_savenickauth(struct nfsmount *nmp, struct ucred *cred, int len,
                 */
 #ifdef NFSKERB
                XXX
+#else
+               ktvout.tv_sec = 0;
+               ktvout.tv_usec = 0;
 #endif
                ktvout.tv_sec = fxdr_unsigned(long, ktvout.tv_sec);
                ktvout.tv_usec = fxdr_unsigned(long, ktvout.tv_usec);
@@ -1144,10 +1064,11 @@ nfs_savenickauth(struct nfsmount *nmp, struct ucred *cred, int len,
                        LIST_INSERT_HEAD(NMUIDHASH(nmp, cred->cr_uid),
                                nuidp, nu_hash);
                }
-       } else
-               nfsm_adv(nfsm_rndup(len));
+       } else {
+               ERROROUT(nfsm_adv(&info, nfsm_rndup(len)));
+       }
 nfsmout:
-       *mdp = md;
-       *dposp = dpos;
+       *mdp = info.md;
+       *dposp = info.dpos;
        return (error);
 }