1*52e1cf57SMatthew Dillon /* 2*52e1cf57SMatthew Dillon * Copyright (c) 2009 The DragonFly Project. All rights reserved. 3*52e1cf57SMatthew Dillon * 4*52e1cf57SMatthew Dillon * This code is derived from software contributed to The DragonFly Project 5*52e1cf57SMatthew Dillon * by Matthew Dillon <dillon@backplane.com> 6*52e1cf57SMatthew Dillon * 7*52e1cf57SMatthew Dillon * Redistribution and use in source and binary forms, with or without 8*52e1cf57SMatthew Dillon * modification, are permitted provided that the following conditions 9*52e1cf57SMatthew Dillon * are met: 10*52e1cf57SMatthew Dillon * 11*52e1cf57SMatthew Dillon * 1. Redistributions of source code must retain the above copyright 12*52e1cf57SMatthew Dillon * notice, this list of conditions and the following disclaimer. 13*52e1cf57SMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright 14*52e1cf57SMatthew Dillon * notice, this list of conditions and the following disclaimer in 15*52e1cf57SMatthew Dillon * the documentation and/or other materials provided with the 16*52e1cf57SMatthew Dillon * distribution. 17*52e1cf57SMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its 18*52e1cf57SMatthew Dillon * contributors may be used to endorse or promote products derived 19*52e1cf57SMatthew Dillon * from this software without specific, prior written permission. 20*52e1cf57SMatthew Dillon * 21*52e1cf57SMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22*52e1cf57SMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23*52e1cf57SMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24*52e1cf57SMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25*52e1cf57SMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26*52e1cf57SMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27*52e1cf57SMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28*52e1cf57SMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29*52e1cf57SMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30*52e1cf57SMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31*52e1cf57SMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32*52e1cf57SMatthew Dillon * SUCH DAMAGE. 33*52e1cf57SMatthew Dillon */ 34*52e1cf57SMatthew Dillon /* 35*52e1cf57SMatthew Dillon * NFSIOD operations - now built into the kernel. 36*52e1cf57SMatthew Dillon */ 37*52e1cf57SMatthew Dillon #include <sys/param.h> 38*52e1cf57SMatthew Dillon #include <sys/systm.h> 39*52e1cf57SMatthew Dillon #include <sys/proc.h> 40*52e1cf57SMatthew Dillon #include <sys/malloc.h> 41*52e1cf57SMatthew Dillon #include <sys/mount.h> 42*52e1cf57SMatthew Dillon #include <sys/kernel.h> 43*52e1cf57SMatthew Dillon #include <sys/mbuf.h> 44*52e1cf57SMatthew Dillon #include <sys/vnode.h> 45*52e1cf57SMatthew Dillon #include <sys/fcntl.h> 46*52e1cf57SMatthew Dillon #include <sys/protosw.h> 47*52e1cf57SMatthew Dillon #include <sys/resourcevar.h> 48*52e1cf57SMatthew Dillon #include <sys/socket.h> 49*52e1cf57SMatthew Dillon #include <sys/socketvar.h> 50*52e1cf57SMatthew Dillon #include <sys/socketops.h> 51*52e1cf57SMatthew Dillon #include <sys/syslog.h> 52*52e1cf57SMatthew Dillon #include <sys/thread.h> 53*52e1cf57SMatthew Dillon #include <sys/tprintf.h> 54*52e1cf57SMatthew Dillon #include <sys/sysctl.h> 55*52e1cf57SMatthew Dillon #include <sys/signalvar.h> 56*52e1cf57SMatthew Dillon #include <sys/mutex.h> 57*52e1cf57SMatthew Dillon 58*52e1cf57SMatthew Dillon #include <sys/signal2.h> 59*52e1cf57SMatthew Dillon #include <sys/mutex2.h> 60*52e1cf57SMatthew Dillon 61*52e1cf57SMatthew Dillon #include <netinet/in.h> 62*52e1cf57SMatthew Dillon #include <netinet/tcp.h> 63*52e1cf57SMatthew Dillon #include <sys/thread2.h> 64*52e1cf57SMatthew Dillon 65*52e1cf57SMatthew Dillon #include "rpcv2.h" 66*52e1cf57SMatthew Dillon #include "nfsproto.h" 67*52e1cf57SMatthew Dillon #include "nfs.h" 68*52e1cf57SMatthew Dillon #include "xdr_subs.h" 69*52e1cf57SMatthew Dillon #include "nfsm_subs.h" 70*52e1cf57SMatthew Dillon #include "nfsmount.h" 71*52e1cf57SMatthew Dillon #include "nfsnode.h" 72*52e1cf57SMatthew Dillon #include "nfsrtt.h" 73*52e1cf57SMatthew Dillon 74*52e1cf57SMatthew Dillon void 75*52e1cf57SMatthew Dillon nfssvc_iod_reader(void *arg) 76*52e1cf57SMatthew Dillon { 77*52e1cf57SMatthew Dillon struct nfsmount *nmp = arg; 78*52e1cf57SMatthew Dillon 79*52e1cf57SMatthew Dillon if (nmp->nm_rxstate == NFSSVC_INIT) 80*52e1cf57SMatthew Dillon nmp->nm_rxstate = NFSSVC_PENDING; 81*52e1cf57SMatthew Dillon for (;;) { 82*52e1cf57SMatthew Dillon if (nmp->nm_rxstate == NFSSVC_WAITING) { 83*52e1cf57SMatthew Dillon tsleep(&nmp->nm_rxstate, 0, "nfsidl", 0); 84*52e1cf57SMatthew Dillon continue; 85*52e1cf57SMatthew Dillon } 86*52e1cf57SMatthew Dillon if (nmp->nm_rxstate != NFSSVC_PENDING) 87*52e1cf57SMatthew Dillon break; 88*52e1cf57SMatthew Dillon nmp->nm_rxstate = NFSSVC_WAITING; 89*52e1cf57SMatthew Dillon 90*52e1cf57SMatthew Dillon #if 0 91*52e1cf57SMatthew Dillon error = tsleep((caddr_t)&nfs_iodwant[myiod], 92*52e1cf57SMatthew Dillon PCATCH, "nfsidl", 0); 93*52e1cf57SMatthew Dillon #endif 94*52e1cf57SMatthew Dillon } 95*52e1cf57SMatthew Dillon nmp->nm_rxthread = NULL; 96*52e1cf57SMatthew Dillon nmp->nm_rxstate = NFSSVC_DONE; 97*52e1cf57SMatthew Dillon wakeup(&nmp->nm_rxthread); 98*52e1cf57SMatthew Dillon } 99*52e1cf57SMatthew Dillon 100*52e1cf57SMatthew Dillon /* 101*52e1cf57SMatthew Dillon * The writer sits on the send side of the client's socket and 102*52e1cf57SMatthew Dillon * does both the initial processing of BIOs and also transmission 103*52e1cf57SMatthew Dillon * and retransmission of nfsreq's. 104*52e1cf57SMatthew Dillon */ 105*52e1cf57SMatthew Dillon void 106*52e1cf57SMatthew Dillon nfssvc_iod_writer(void *arg) 107*52e1cf57SMatthew Dillon { 108*52e1cf57SMatthew Dillon struct nfsmount *nmp = arg; 109*52e1cf57SMatthew Dillon struct bio *bio; 110*52e1cf57SMatthew Dillon struct vnode *vp; 111*52e1cf57SMatthew Dillon 112*52e1cf57SMatthew Dillon if (nmp->nm_txstate == NFSSVC_INIT) 113*52e1cf57SMatthew Dillon nmp->nm_txstate = NFSSVC_PENDING; 114*52e1cf57SMatthew Dillon for (;;) { 115*52e1cf57SMatthew Dillon if (nmp->nm_txstate == NFSSVC_WAITING) { 116*52e1cf57SMatthew Dillon tsleep(&nmp->nm_txstate, 0, "nfsidl", 0); 117*52e1cf57SMatthew Dillon continue; 118*52e1cf57SMatthew Dillon } 119*52e1cf57SMatthew Dillon if (nmp->nm_txstate != NFSSVC_PENDING) 120*52e1cf57SMatthew Dillon break; 121*52e1cf57SMatthew Dillon nmp->nm_txstate = NFSSVC_WAITING; 122*52e1cf57SMatthew Dillon 123*52e1cf57SMatthew Dillon while (nmp->nm_bioqlen && nmp->nm_reqqlen < 32) { 124*52e1cf57SMatthew Dillon bio = TAILQ_FIRST(&nmp->nm_bioq); 125*52e1cf57SMatthew Dillon KKASSERT(bio); 126*52e1cf57SMatthew Dillon TAILQ_REMOVE(&nmp->nm_bioq, bio, bio_act); 127*52e1cf57SMatthew Dillon nmp->nm_bioqlen--; 128*52e1cf57SMatthew Dillon vp = bio->bio_driver_info; 129*52e1cf57SMatthew Dillon nfs_doio(vp, bio, NULL); 130*52e1cf57SMatthew Dillon } 131*52e1cf57SMatthew Dillon } 132*52e1cf57SMatthew Dillon nmp->nm_txthread = NULL; 133*52e1cf57SMatthew Dillon nmp->nm_txstate = NFSSVC_DONE; 134*52e1cf57SMatthew Dillon wakeup(&nmp->nm_txthread); 135*52e1cf57SMatthew Dillon } 136*52e1cf57SMatthew Dillon 137*52e1cf57SMatthew Dillon void 138*52e1cf57SMatthew Dillon nfssvc_iod_stop(struct nfsmount *nmp) 139*52e1cf57SMatthew Dillon { 140*52e1cf57SMatthew Dillon nmp->nm_txstate = NFSSVC_STOPPING; 141*52e1cf57SMatthew Dillon wakeup(&nmp->nm_txstate); 142*52e1cf57SMatthew Dillon while (nmp->nm_txthread) 143*52e1cf57SMatthew Dillon tsleep(&nmp->nm_txthread, 0, "nfssttx", 0); 144*52e1cf57SMatthew Dillon 145*52e1cf57SMatthew Dillon nmp->nm_rxstate = NFSSVC_STOPPING; 146*52e1cf57SMatthew Dillon wakeup(&nmp->nm_rxstate); 147*52e1cf57SMatthew Dillon while (nmp->nm_rxthread) 148*52e1cf57SMatthew Dillon tsleep(&nmp->nm_rxthread, 0, "nfsstrx", 0); 149*52e1cf57SMatthew Dillon } 150*52e1cf57SMatthew Dillon 151*52e1cf57SMatthew Dillon void 152*52e1cf57SMatthew Dillon nfssvc_iod_writer_wakeup(struct nfsmount *nmp) 153*52e1cf57SMatthew Dillon { 154*52e1cf57SMatthew Dillon if (nmp->nm_txstate == NFSSVC_WAITING) { 155*52e1cf57SMatthew Dillon nmp->nm_txstate = NFSSVC_PENDING; 156*52e1cf57SMatthew Dillon wakeup(&nmp->nm_txstate); 157*52e1cf57SMatthew Dillon } 158*52e1cf57SMatthew Dillon } 159