use mutex and condvar.
This commit is contained in:
parent
61131eb130
commit
05aaff39ff
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user