use mutex and condvar.

This commit is contained in:
yamt 2007-06-01 11:56:03 +00:00
parent 61131eb130
commit 05aaff39ff
5 changed files with 125 additions and 144 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs.h,v 1.64 2007/04/30 23:10:55 yamt Exp $ */
/* $NetBSD: nfs.h,v 1.65 2007/06/01 11:56:03 yamt Exp $ */
/*
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
@ -433,7 +433,8 @@ struct nfsuid {
#endif
struct nfssvc_sock {
struct simplelock ns_lock;
kmutex_t ns_lock;
kcondvar_t ns_cv;
TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */
TAILQ_ENTRY(nfssvc_sock) ns_pending; /* List of pending sockets */
TAILQ_HEAD(, nfsuid) ns_uidlruhead;
@ -463,7 +464,6 @@ struct nfssvc_sock {
#define SLP_NEEDQ 0x04
#define SLP_DISCONN 0x08
#define SLP_BUSY 0x10
#define SLP_WANT 0x20
#define SLP_LASTFRAG 0x40
#define SLP_SENDING 0x80
@ -471,7 +471,6 @@ extern TAILQ_HEAD(nfssvc_sockhead, nfssvc_sock) nfssvc_sockhead;
extern struct nfssvc_sockhead nfssvc_sockpending;
extern int nfssvc_sockhead_flag;
#define SLP_INIT 0x01
#define SLP_WANTINIT 0x02
/*
* One of these structures is allocated for each nfsd.
@ -479,6 +478,7 @@ extern int nfssvc_sockhead_flag;
struct nfsd {
TAILQ_ENTRY(nfsd) nfsd_chain; /* List of all nfsd's */
SLIST_ENTRY(nfsd) nfsd_idle; /* List of idle nfsd's */
kcondvar_t nfsd_cv;
int nfsd_flag; /* NFSD_ flags */
struct nfssvc_sock *nfsd_slp; /* Current socket */
int nfsd_authlen; /* Authenticator len */
@ -545,7 +545,8 @@ struct nfsrv_descript {
#define ND_KERBFULL 0x40
#define ND_KERBAUTH (ND_KERBNICK | ND_KERBFULL)
extern struct simplelock nfsd_slock;
extern kmutex_t nfsd_lock;
extern kcondvar_t nfsd_initcv;
extern TAILQ_HEAD(nfsdhead, nfsd) nfsd_head;
extern SLIST_HEAD(nfsdidlehead, nfsd) nfsd_idle_head;
extern int nfsd_head_flag;

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_socket.c,v 1.156 2007/06/01 11:38:44 yamt Exp $ */
/* $NetBSD: nfs_socket.c,v 1.157 2007/06/01 11:56:03 yamt Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1995
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.156 2007/06/01 11:38:44 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.157 2007/06/01 11:56:03 yamt Exp $");
#include "fs_nfs.h"
#include "opt_nfs.h"
@ -2183,9 +2183,9 @@ nfsrv_rcv(so, arg, waitflag)
goto dorecs;
}
#endif
simple_lock(&slp->ns_lock);
mutex_enter(&slp->ns_lock);
slp->ns_flag &= ~SLP_NEEDQ;
simple_unlock(&slp->ns_lock);
mutex_exit(&slp->ns_lock);
if (so->so_type == SOCK_STREAM) {
#ifndef NFS_TEST_HEAVY
/*
@ -2274,9 +2274,9 @@ dorecs_unlocked:
* Now try and process the request records, non-blocking.
*/
if (setflags) {
simple_lock(&slp->ns_lock);
mutex_enter(&slp->ns_lock);
slp->ns_flag |= setflags;
simple_unlock(&slp->ns_lock);
mutex_exit(&slp->ns_lock);
}
if (waitflag == M_DONTWAIT &&
(slp->ns_rec || (slp->ns_flag & (SLP_DISCONN | SLP_NEEDQ)) != 0)) {
@ -2288,21 +2288,21 @@ int
nfsdsock_lock(struct nfssvc_sock *slp, bool waitok)
{
simple_lock(&slp->ns_lock);
mutex_enter(&slp->ns_lock);
while ((~slp->ns_flag & (SLP_BUSY|SLP_VALID)) == 0) {
if (!waitok) {
simple_unlock(&slp->ns_lock);
mutex_exit(&slp->ns_lock);
return EWOULDBLOCK;
}
slp->ns_flag |= SLP_WANT;
ltsleep(&slp->ns_flag, PSOCK, "nslock", 0, &slp->ns_lock);
cv_wait(&slp->ns_cv, &slp->ns_lock);
}
if ((slp->ns_flag & SLP_VALID) == 0) {
simple_unlock(&slp->ns_lock);
mutex_exit(&slp->ns_lock);
return EINVAL;
}
KASSERT((slp->ns_flag & SLP_BUSY) == 0);
slp->ns_flag |= SLP_BUSY;
simple_unlock(&slp->ns_lock);
mutex_exit(&slp->ns_lock);
return 0;
}
@ -2311,14 +2311,11 @@ void
nfsdsock_unlock(struct nfssvc_sock *slp)
{
mutex_enter(&slp->ns_lock);
KASSERT((slp->ns_flag & SLP_BUSY) != 0);
simple_lock(&slp->ns_lock);
if ((slp->ns_flag & SLP_WANT) != 0) {
wakeup(&slp->ns_flag);
}
slp->ns_flag &= ~(SLP_BUSY|SLP_WANT);
simple_unlock(&slp->ns_lock);
cv_broadcast(&slp->ns_cv);
slp->ns_flag &= ~SLP_BUSY;
mutex_exit(&slp->ns_lock);
}
int
@ -2326,18 +2323,17 @@ nfsdsock_drain(struct nfssvc_sock *slp)
{
int error = 0;
simple_lock(&slp->ns_lock);
mutex_enter(&slp->ns_lock);
if ((slp->ns_flag & SLP_VALID) == 0) {
error = EINVAL;
goto done;
}
slp->ns_flag &= ~SLP_VALID;
while ((slp->ns_flag & SLP_BUSY) != 0) {
slp->ns_flag |= SLP_WANT;
ltsleep(&slp->ns_flag, PSOCK, "nsdrain", 0, &slp->ns_lock);
cv_wait(&slp->ns_cv, &slp->ns_lock);
}
done:
simple_unlock(&slp->ns_lock);
mutex_exit(&slp->ns_lock);
return error;
}
@ -2357,6 +2353,7 @@ nfsrv_getstream(slp, waitflag)
u_int32_t recmark;
int error = 0;
KASSERT((slp->ns_flag & SLP_BUSY) != 0);
for (;;) {
if (slp->ns_reclen == 0) {
if (slp->ns_cc < NFSX_UNSIGNED) {
@ -2489,27 +2486,25 @@ nfsrv_wakenfsd(slp)
if ((slp->ns_flag & SLP_VALID) == 0)
return;
simple_lock(&nfsd_slock);
mutex_enter(&nfsd_lock);
if (slp->ns_flag & SLP_DOREC) {
simple_unlock(&nfsd_slock);
mutex_exit(&nfsd_lock);
return;
}
nd = SLIST_FIRST(&nfsd_idle_head);
if (nd) {
SLIST_REMOVE_HEAD(&nfsd_idle_head, nfsd_idle);
simple_unlock(&nfsd_slock);
if (nd->nfsd_slp)
panic("nfsd wakeup");
slp->ns_sref++;
nd->nfsd_slp = slp;
wakeup(nd);
return;
cv_signal(&nd->nfsd_cv);
} else {
slp->ns_flag |= SLP_DOREC;
nfsd_head_flag |= NFSD_CHECKSLP;
TAILQ_INSERT_TAIL(&nfssvc_sockpending, slp, ns_pending);
}
slp->ns_flag |= SLP_DOREC;
nfsd_head_flag |= NFSD_CHECKSLP;
TAILQ_INSERT_TAIL(&nfssvc_sockpending, slp, ns_pending);
simple_unlock(&nfsd_slock);
mutex_exit(&nfsd_lock);
}
int
@ -2522,15 +2517,15 @@ nfsdsock_sendreply(struct nfssvc_sock *slp, struct nfsrv_descript *nd)
nd->nd_mrep = NULL;
}
simple_lock(&slp->ns_lock);
mutex_enter(&slp->ns_lock);
if ((slp->ns_flag & SLP_SENDING) != 0) {
SIMPLEQ_INSERT_TAIL(&slp->ns_sendq, nd, nd_sendq);
simple_unlock(&slp->ns_lock);
mutex_exit(&slp->ns_lock);
return 0;
}
KASSERT(SIMPLEQ_EMPTY(&slp->ns_sendq));
slp->ns_flag |= SLP_SENDING;
simple_unlock(&slp->ns_lock);
mutex_exit(&slp->ns_lock);
again:
error = nfs_send(slp->ns_so, nd->nd_nam2, nd->nd_mreq, NULL, curlwp);
@ -2539,16 +2534,16 @@ again:
}
nfsdreq_free(nd);
simple_lock(&slp->ns_lock);
mutex_enter(&slp->ns_lock);
KASSERT((slp->ns_flag & SLP_SENDING) != 0);
nd = SIMPLEQ_FIRST(&slp->ns_sendq);
if (nd != NULL) {
SIMPLEQ_REMOVE_HEAD(&slp->ns_sendq, nd_sendq);
simple_unlock(&slp->ns_lock);
mutex_exit(&slp->ns_lock);
goto again;
}
slp->ns_flag &= ~SLP_SENDING;
simple_unlock(&slp->ns_lock);
mutex_exit(&slp->ns_lock);
return error;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_srvcache.c,v 1.39 2007/03/12 18:18:36 ad Exp $ */
/* $NetBSD: nfs_srvcache.c,v 1.40 2007/06/01 11:56:03 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@ -41,12 +41,13 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_srvcache.c,v 1.39 2007/03/12 18:18:36 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_srvcache.c,v 1.40 2007/06/01 11:56:03 yamt Exp $");
#include "opt_iso.h"
#include <sys/param.h>
#include <sys/vnode.h>
#include <sys/condvar.h>
#include <sys/mount.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@ -55,6 +56,7 @@ __KERNEL_RCSID(0, "$NetBSD: nfs_srvcache.c,v 1.39 2007/03/12 18:18:36 ad Exp $")
#include <sys/pool.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@ -78,7 +80,7 @@ struct pool nfs_reqcache_pool;
(&nfsrvhashtbl[((xid) + ((xid) >> 24)) & nfsrvhash])
LIST_HEAD(nfsrvhash, nfsrvcache) *nfsrvhashtbl;
TAILQ_HEAD(nfsrvlru, nfsrvcache) nfsrvlruhead;
struct simplelock nfsrv_reqcache_lock = SIMPLELOCK_INITIALIZER;
kmutex_t nfsrv_reqcache_lock;
u_long nfsrvhash;
#if defined(MBUFTRACE)
@ -162,6 +164,7 @@ void
nfsrv_initcache()
{
mutex_init(&nfsrv_reqcache_lock, MUTEX_DRIVER, IPL_NONE);
nfsrvhashtbl = hashinit(desirednfsrvcache, HASH_LIST, M_NFSD,
M_WAITOK, &nfsrvhash);
TAILQ_INIT(&nfsrvlruhead);
@ -179,7 +182,7 @@ nfsrv_lookupcache(nd)
{
struct nfsrvcache *rp;
LOCK_ASSERT(simple_lock_held(&nfsrv_reqcache_lock));
KASSERT(mutex_owned(&nfsrv_reqcache_lock));
loop:
LIST_FOREACH(rp, NFSRCHASH(nd->nd_retxid), rc_hash) {
@ -187,9 +190,7 @@ loop:
nd->nd_procnum == rp->rc_proc &&
netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nd->nd_nam)) {
if ((rp->rc_flag & RC_LOCKED) != 0) {
rp->rc_flag |= RC_WANTED;
(void) ltsleep(rp, PZERO - 1, "nfsrc", 0,
&nfsrv_reqcache_lock);
cv_wait(&rp->rc_cv, &nfsrv_reqcache_lock);
goto loop;
}
rp->rc_flag |= RC_LOCKED;
@ -208,13 +209,10 @@ nfsrv_unlockcache(rp)
struct nfsrvcache *rp;
{
LOCK_ASSERT(simple_lock_held(&nfsrv_reqcache_lock));
KASSERT(mutex_owned(&nfsrv_reqcache_lock));
rp->rc_flag &= ~RC_LOCKED;
if (rp->rc_flag & RC_WANTED) {
rp->rc_flag &= ~RC_WANTED;
wakeup(rp);
}
cv_broadcast(&rp->rc_cv);
}
/*
@ -243,17 +241,17 @@ nfsrv_getcache(nd, slp, repp)
char *bpos;
int ret;
simple_lock(&nfsrv_reqcache_lock);
mutex_enter(&nfsrv_reqcache_lock);
rp = nfsrv_lookupcache(nd);
if (rp) {
simple_unlock(&nfsrv_reqcache_lock);
mutex_exit(&nfsrv_reqcache_lock);
found:
/* If not at end of LRU chain, move it there */
if (TAILQ_NEXT(rp, rc_lru)) { /* racy but ok */
simple_lock(&nfsrv_reqcache_lock);
mutex_enter(&nfsrv_reqcache_lock);
TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru);
TAILQ_INSERT_TAIL(&nfsrvlruhead, rp, rc_lru);
simple_unlock(&nfsrv_reqcache_lock);
mutex_exit(&nfsrv_reqcache_lock);
}
if (rp->rc_state == RC_UNUSED)
panic("nfsrv cache");
@ -275,30 +273,30 @@ found:
rp->rc_state = RC_INPROG;
ret = RC_DOIT;
}
simple_lock(&nfsrv_reqcache_lock);
mutex_enter(&nfsrv_reqcache_lock);
nfsrv_unlockcache(rp);
simple_unlock(&nfsrv_reqcache_lock);
mutex_exit(&nfsrv_reqcache_lock);
return ret;
}
nfsstats.srvcache_misses++;
if (numnfsrvcache < desirednfsrvcache) {
numnfsrvcache++;
simple_unlock(&nfsrv_reqcache_lock);
mutex_exit(&nfsrv_reqcache_lock);
rp = pool_get(&nfs_reqcache_pool, PR_WAITOK);
memset(rp, 0, sizeof *rp);
cv_init(&rp->rc_cv, "nfsdrc");
rp->rc_flag = RC_LOCKED;
} else {
rp = TAILQ_FIRST(&nfsrvlruhead);
while ((rp->rc_flag & RC_LOCKED) != 0) {
rp->rc_flag |= RC_WANTED;
(void) ltsleep(rp, PZERO-1, "nfsrc", 0,
&nfsrv_reqcache_lock);
cv_wait(&rp->rc_cv, &nfsrv_reqcache_lock);
rp = TAILQ_FIRST(&nfsrvlruhead);
}
rp->rc_flag |= RC_LOCKED;
LIST_REMOVE(rp, rc_hash);
TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru);
simple_unlock(&nfsrv_reqcache_lock);
mutex_exit(&nfsrv_reqcache_lock);
cleanentry(rp);
rp->rc_flag &= (RC_LOCKED | RC_WANTED);
}
@ -318,13 +316,14 @@ found:
break;
};
rp->rc_proc = nd->nd_procnum;
simple_lock(&nfsrv_reqcache_lock);
mutex_enter(&nfsrv_reqcache_lock);
rpdup = nfsrv_lookupcache(nd);
if (rpdup != NULL) {
/*
* other thread made duplicate cache entry.
*/
simple_unlock(&nfsrv_reqcache_lock);
mutex_exit(&nfsrv_reqcache_lock);
cv_destroy(&rp->rc_cv);
pool_put(&nfs_reqcache_pool, rp);
rp = rpdup;
goto found;
@ -332,7 +331,7 @@ found:
TAILQ_INSERT_TAIL(&nfsrvlruhead, rp, rc_lru);
LIST_INSERT_HEAD(NFSRCHASH(nd->nd_retxid), rp, rc_hash);
nfsrv_unlockcache(rp);
simple_unlock(&nfsrv_reqcache_lock);
mutex_exit(&nfsrv_reqcache_lock);
return RC_DOIT;
}
@ -347,9 +346,9 @@ nfsrv_updatecache(nd, repvalid, repmbuf)
{
struct nfsrvcache *rp;
simple_lock(&nfsrv_reqcache_lock);
mutex_enter(&nfsrv_reqcache_lock);
rp = nfsrv_lookupcache(nd);
simple_unlock(&nfsrv_reqcache_lock);
mutex_exit(&nfsrv_reqcache_lock);
if (rp) {
cleanentry(rp);
rp->rc_state = RC_DONE;
@ -369,9 +368,9 @@ nfsrv_updatecache(nd, repvalid, repmbuf)
rp->rc_flag |= RC_REPMBUF;
}
}
simple_lock(&nfsrv_reqcache_lock);
mutex_enter(&nfsrv_reqcache_lock);
nfsrv_unlockcache(rp);
simple_unlock(&nfsrv_reqcache_lock);
mutex_exit(&nfsrv_reqcache_lock);
}
}
@ -383,15 +382,16 @@ nfsrv_cleancache()
{
struct nfsrvcache *rp, *nextrp;
simple_lock(&nfsrv_reqcache_lock);
mutex_enter(&nfsrv_reqcache_lock);
for (rp = TAILQ_FIRST(&nfsrvlruhead); rp != 0; rp = nextrp) {
nextrp = TAILQ_NEXT(rp, rc_lru);
LIST_REMOVE(rp, rc_hash);
TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru);
KASSERT((rp->rc_flag & (RC_LOCKED|RC_WANTED)) == 0);
cleanentry(rp);
cv_destroy(&rp->rc_cv);
pool_put(&nfs_reqcache_pool, rp);
}
numnfsrvcache = 0;
simple_unlock(&nfsrv_reqcache_lock);
mutex_exit(&nfsrv_reqcache_lock);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_syscalls.c,v 1.110 2007/04/30 10:30:51 yamt Exp $ */
/* $NetBSD: nfs_syscalls.c,v 1.111 2007/06/01 11:56:03 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.110 2007/04/30 10:30:51 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.111 2007/06/01 11:56:03 yamt Exp $");
#include "fs_nfs.h"
#include "opt_nfs.h"
@ -98,15 +98,15 @@ struct nfssvc_sock *nfs_cltpsock;
struct nfssvc_sock *nfs_udp6sock;
#endif
int nuidhash_max = NFS_MAXUIDHASH;
int nfsd_waiting = 0;
#ifdef NFSSERVER
static int nfs_numnfsd = 0;
static struct nfsdrt nfsdrt;
#endif
#ifdef NFSSERVER
struct simplelock nfsd_slock = SIMPLELOCK_INITIALIZER;
kmutex_t nfsd_lock;
struct nfssvc_sockhead nfssvc_sockhead;
kcondvar_t nfsd_initcv;
struct nfssvc_sockhead nfssvc_sockpending;
struct nfsdhead nfsd_head;
struct nfsdidlehead nfsd_idle_head;
@ -149,7 +149,6 @@ sys_nfssvc(struct lwp *l, void *v, register_t *retval)
} */ *uap = v;
int error;
#ifdef NFSSERVER
int s;
struct file *fp;
struct mbuf *nam;
struct nfsd_args nfsdarg;
@ -171,15 +170,11 @@ sys_nfssvc(struct lwp *l, void *v, register_t *retval)
nfs_init();
#ifdef NFSSERVER
s = splsoftnet();
simple_lock(&nfsd_slock);
mutex_enter(&nfsd_lock);
while (nfssvc_sockhead_flag & SLP_INIT) {
nfssvc_sockhead_flag |= SLP_WANTINIT;
(void) ltsleep(&nfssvc_sockhead, PSOCK, "nfsd init", 0,
&nfsd_slock);
cv_wait(&nfsd_initcv, &nfsd_lock);
}
simple_unlock(&nfsd_slock);
splx(s);
mutex_exit(&nfsd_lock);
#endif
if (SCARG(uap, flag) & NFSSVC_BIOD) {
#if defined(NFS) && defined(COMPAT_14)
@ -353,20 +348,18 @@ static struct nfssvc_sock *
nfsrv_sockalloc()
{
struct nfssvc_sock *slp;
int s;
slp = (struct nfssvc_sock *)
malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
memset(slp, 0, sizeof (struct nfssvc_sock));
simple_lock_init(&slp->ns_lock);
mutex_init(&slp->ns_lock, MUTEX_DRIVER, IPL_SOFTNET);
cv_init(&slp->ns_cv, "nfsdsock");
TAILQ_INIT(&slp->ns_uidlruhead);
LIST_INIT(&slp->ns_tq);
SIMPLEQ_INIT(&slp->ns_sendq);
s = splsoftnet();
simple_lock(&nfsd_slock);
mutex_enter(&nfsd_lock);
TAILQ_INSERT_TAIL(&nfssvc_sockhead, slp, ns_chain);
simple_unlock(&nfsd_slock);
splx(s);
mutex_exit(&nfsd_lock);
return slp;
}
@ -378,6 +371,8 @@ nfsrv_sockfree(struct nfssvc_sock *slp)
KASSERT(slp->ns_so == NULL);
KASSERT(slp->ns_fp == NULL);
KASSERT((slp->ns_flag & SLP_VALID) == 0);
mutex_destroy(&slp->ns_lock);
cv_destroy(&slp->ns_cv);
free(slp, M_NFSSVC);
}
@ -459,9 +454,9 @@ nfssvc_addsock(fp, mynam)
so->so_rcv.sb_timeo = 0;
so->so_snd.sb_flags &= ~SB_NOINTR;
so->so_snd.sb_timeo = 0;
if (tslp)
if (tslp) {
slp = tslp;
else {
} else {
slp = nfsrv_sockalloc();
}
slp->ns_so = so;
@ -472,7 +467,7 @@ nfssvc_addsock(fp, mynam)
so->so_upcallarg = (void *)slp;
so->so_upcall = nfsrv_rcv;
so->so_rcv.sb_flags |= SB_UPCALL;
slp->ns_flag = (SLP_VALID | SLP_NEEDQ);
slp->ns_flag = SLP_VALID | SLP_NEEDQ;
nfsrv_wakenfsd(slp);
splx(s);
return (0);
@ -495,23 +490,24 @@ nfssvc_nfsd(nsd, argp, l)
struct nfsrv_descript *nd = NULL;
struct mbuf *mreq;
u_quad_t cur_usec;
int error = 0, cacherep, s, siz, sotype, writes_todo;
int error = 0, cacherep, siz, sotype, writes_todo;
struct proc *p = l->l_proc;
int s;
#ifndef nolint
cacherep = RC_DOIT;
writes_todo = 0;
#endif
s = splsoftnet();
if (nfsd == (struct nfsd *)0) {
nsd->nsd_nfsd = nfsd = (struct nfsd *)
if (nfsd == NULL) {
nsd->nsd_nfsd = nfsd =
malloc(sizeof (struct nfsd), M_NFSD, M_WAITOK);
memset((void *)nfsd, 0, sizeof (struct nfsd));
memset(nfsd, 0, sizeof (struct nfsd));
cv_init(&nfsd->nfsd_cv, "nfsd");
nfsd->nfsd_procp = p;
simple_lock(&nfsd_slock);
mutex_enter(&nfsd_lock);
TAILQ_INSERT_TAIL(&nfsd_head, nfsd, nfsd_chain);
nfs_numnfsd++;
simple_unlock(&nfsd_slock);
mutex_exit(&nfsd_lock);
}
PHOLD(l);
/*
@ -519,22 +515,19 @@ nfssvc_nfsd(nsd, argp, l)
*/
for (;;) {
if (nfsd->nfsd_slp == NULL) {
simple_lock(&nfsd_slock);
mutex_enter(&nfsd_lock);
while (nfsd->nfsd_slp == NULL &&
(nfsd_head_flag & NFSD_CHECKSLP) == 0) {
SLIST_INSERT_HEAD(&nfsd_idle_head, nfsd,
nfsd_idle);
nfsd_waiting++;
error = ltsleep(nfsd, PSOCK | PCATCH, "nfsd",
0, &nfsd_slock);
nfsd_waiting--;
error = cv_wait_sig(&nfsd->nfsd_cv, &nfsd_lock);
if (error) {
slp = nfsd->nfsd_slp;
nfsd->nfsd_slp = NULL;
if (!slp)
SLIST_REMOVE(&nfsd_idle_head,
nfsd, nfsd, nfsd_idle);
simple_unlock(&nfsd_slock);
mutex_exit(&nfsd_lock);
if (slp) {
nfsrv_wakenfsd(slp);
nfsrv_slpderef(slp);
@ -557,7 +550,7 @@ nfssvc_nfsd(nsd, argp, l)
} else
nfsd_head_flag &= ~NFSD_CHECKSLP;
}
simple_unlock(&nfsd_slock);
mutex_exit(&nfsd_lock);
if ((slp = nfsd->nfsd_slp) == NULL)
continue;
if (slp->ns_flag & SLP_VALID) {
@ -596,7 +589,6 @@ nfssvc_nfsd(nsd, argp, l)
nfsrv_slpderef(slp);
continue;
}
splx(s);
sotype = slp->ns_so->so_type;
if (nd) {
getmicrotime(&nd->nd_starttime);
@ -736,7 +728,6 @@ nfssvc_nfsd(nsd, argp, l)
nfsd_rt(slp->ns_so->so_type, nd,
cacherep);
}
s = splsoftnet();
error = nfsdsock_sendreply(slp, nd);
nd = NULL;
if (error == EPIPE)
@ -745,7 +736,6 @@ nfssvc_nfsd(nsd, argp, l)
nfsrv_slpderef(slp);
goto done;
}
splx(s);
break;
case RC_DROPIT:
if (nfsrtton)
@ -775,7 +765,6 @@ nfssvc_nfsd(nsd, argp, l)
writes_todo = 0;
splx(s);
} while (writes_todo);
s = splsoftnet();
if (nfsrv_dorec(slp, nfsd, &nd)) {
nfsd->nfsd_slp = NULL;
nfsrv_slpderef(slp);
@ -783,12 +772,12 @@ nfssvc_nfsd(nsd, argp, l)
}
done:
PRELE(l);
simple_lock(&nfsd_slock);
mutex_enter(&nfsd_lock);
TAILQ_REMOVE(&nfsd_head, nfsd, nfsd_chain);
simple_unlock(&nfsd_slock);
splx(s);
free((void *)nfsd, M_NFSD);
nsd->nsd_nfsd = (struct nfsd *)0;
mutex_exit(&nfsd_lock);
cv_destroy(&nfsd->nfsd_cv);
free(nfsd, M_NFSD);
nsd->nsd_nfsd = NULL;
if (--nfs_numnfsd == 0)
nfsrv_init(true); /* Reinitialize everything */
return (error);
@ -816,11 +805,11 @@ nfsrv_zapsock(slp)
if (nfsdsock_drain(slp)) {
return;
}
simple_lock(&nfsd_slock);
mutex_enter(&nfsd_lock);
if (slp->ns_flag & SLP_DOREC) {
TAILQ_REMOVE(&nfssvc_sockpending, slp, ns_pending);
}
simple_unlock(&nfsd_slock);
mutex_exit(&nfsd_lock);
so = slp->ns_so;
KASSERT(so != NULL);
@ -866,15 +855,13 @@ void
nfsrv_slpderef(slp)
struct nfssvc_sock *slp;
{
LOCK_ASSERT(!simple_lock_held(&nfsd_slock));
if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) {
struct file *fp;
int s = splsoftnet();
simple_lock(&nfsd_slock);
mutex_enter(&nfsd_lock);
TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
simple_unlock(&nfsd_slock);
splx(s);
mutex_exit(&nfsd_lock);
fp = slp->ns_fp;
if (fp != NULL) {
@ -901,35 +888,35 @@ nfsrv_init(terminating)
int terminating;
{
struct nfssvc_sock *slp;
int s;
s = splsoftnet();
simple_lock(&nfsd_slock);
if (!terminating) {
mutex_init(&nfsd_lock, MUTEX_DRIVER, IPL_SOFTNET);
cv_init(&nfsd_initcv, "nfsdinit");
}
mutex_enter(&nfsd_lock);
if (nfssvc_sockhead_flag & SLP_INIT)
panic("nfsd init");
nfssvc_sockhead_flag |= SLP_INIT;
if (terminating) {
while ((slp = TAILQ_FIRST(&nfssvc_sockhead)) != NULL) {
simple_unlock(&nfsd_slock);
mutex_exit(&nfsd_lock);
KASSERT(slp->ns_sref == 0);
slp->ns_sref++;
nfsrv_zapsock(slp);
nfsrv_slpderef(slp);
simple_lock(&nfsd_slock);
mutex_enter(&nfsd_lock);
}
simple_unlock(&nfsd_slock);
splx(s);
mutex_exit(&nfsd_lock);
nfsrv_cleancache(); /* And clear out server cache */
} else {
simple_unlock(&nfsd_slock);
splx(s);
mutex_exit(&nfsd_lock);
nfs_pub.np_valid = 0;
}
TAILQ_INIT(&nfssvc_sockhead);
TAILQ_INIT(&nfssvc_sockpending);
nfssvc_sockhead_flag &= ~SLP_INIT;
TAILQ_INIT(&nfsd_head);
SLIST_INIT(&nfsd_idle_head);
@ -945,13 +932,10 @@ nfsrv_init(terminating)
nfs_cltpsock = nfsrv_sockalloc();
#endif
simple_lock(&nfsd_slock);
if (nfssvc_sockhead_flag & SLP_WANTINIT) {
nfssvc_sockhead_flag &= ~SLP_WANTINIT;
wakeup(&nfssvc_sockhead);
}
simple_unlock(&nfsd_slock);
splx(s);
mutex_enter(&nfsd_lock);
nfssvc_sockhead_flag &= ~SLP_INIT;
cv_broadcast(&nfsd_initcv);
mutex_exit(&nfsd_lock);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsrvcache.h,v 1.14 2006/12/28 00:39:03 yamt Exp $ */
/* $NetBSD: nfsrvcache.h,v 1.15 2007/06/01 11:56:04 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@ -45,6 +45,7 @@
#define NFSRVCACHESIZ 64
struct nfsrvcache {
kcondvar_t rc_cv;
TAILQ_ENTRY(nfsrvcache) rc_lru; /* LRU chain */
LIST_ENTRY(nfsrvcache) rc_hash; /* Hash chain */
u_int32_t rc_xid; /* rpc id number */