summaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-03-17 22:05:47 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-03-17 22:05:47 +0000
commit27cfca1ec98e91261b1a5355d10a8996464b63af (patch)
tree8e895a53e372fa682b4c0a585b9377d67ed70d0e /net/sunrpc
parent6a76fb7214c477ccf6582bd79c5b4ccc4f9c41b1 (diff)
Look Ma' what I found on my harddisk ...
o New faster syscalls for 2.1.x, too o Upgrade to 2.1.89. Don't try to run this. It's flaky as hell. But feel free to debug ...
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/.cvsignore1
-rw-r--r--net/sunrpc/clnt.c67
-rw-r--r--net/sunrpc/sched.c106
-rw-r--r--net/sunrpc/stats.c58
-rw-r--r--net/sunrpc/sunrpc_syms.c2
-rw-r--r--net/sunrpc/svc.c61
-rw-r--r--net/sunrpc/svcsock.c36
-rw-r--r--net/sunrpc/sysctl.c32
-rw-r--r--net/sunrpc/xprt.c30
9 files changed, 249 insertions, 144 deletions
diff --git a/net/sunrpc/.cvsignore b/net/sunrpc/.cvsignore
index 4671378ae..857dd22e9 100644
--- a/net/sunrpc/.cvsignore
+++ b/net/sunrpc/.cvsignore
@@ -1 +1,2 @@
.depend
+.*.flags
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 7abaa691e..e8ca9a511 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -21,9 +21,6 @@
* Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de>
*/
-#include <linux/config.h>
-#include <linux/module.h>
-
#include <asm/system.h>
#include <asm/segment.h>
@@ -72,20 +69,19 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
struct rpc_program *program, u32 vers, int flavor)
{
struct rpc_version *version;
- struct rpc_clnt *clnt;
+ struct rpc_clnt *clnt = NULL;
dprintk("RPC: creating %s client for %s (xprt %p)\n",
- program->name, servname, xprt);
+ program->name, servname, xprt);
if (!xprt)
- return NULL;
- if (vers>= program->nrvers || !(version = program->version[vers]))
- return NULL;
+ goto out;
+ if (vers >= program->nrvers || !(version = program->version[vers]))
+ goto out;
- if (!(clnt = (struct rpc_clnt *) rpc_allocate(0, sizeof(*clnt)))) {
- printk("RPC: out of memory in rpc_create_client\n");
- return NULL;
- }
+ clnt = (struct rpc_clnt *) rpc_allocate(0, sizeof(*clnt));
+ if (!clnt)
+ goto out_no_clnt;
memset(clnt, 0, sizeof(*clnt));
clnt->cl_xprt = xprt;
@@ -103,13 +99,20 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
if (!clnt->cl_port)
clnt->cl_autobind = 1;
- if (!rpcauth_create(flavor, clnt)) {
- printk("RPC: Couldn't create auth handle (flavor %d)\n",
- flavor);
- rpc_free(clnt);
- return NULL;
- }
+ if (!rpcauth_create(flavor, clnt))
+ goto out_no_auth;
+out:
return clnt;
+
+out_no_clnt:
+ printk("RPC: out of memory in rpc_create_client\n");
+ goto out;
+out_no_auth:
+ printk("RPC: Couldn't create auth handle (flavor %d)\n",
+ flavor);
+ rpc_free(clnt);
+ clnt = NULL;
+ goto out;
}
/*
@@ -753,8 +756,10 @@ call_verify(struct rpc_task *task)
rpc_exit(task, error);
return NULL;
}
- if (!(p = rpcauth_checkverf(task, p)))
+ if (!(p = rpcauth_checkverf(task, p))) {
+ printk("call_verify: auth check failed\n");
goto garbage; /* bad verifier, retry */
+ }
switch ((n = ntohl(*p++))) {
case RPC_SUCCESS:
return p;
@@ -768,7 +773,8 @@ call_verify(struct rpc_task *task)
garbage:
dprintk("RPC: %4d call_verify: server saw garbage\n", task->tk_pid);
task->tk_client->cl_stats->rpcgarbage++;
- if (0 && task->tk_garb_retry--) {
+ if (task->tk_garb_retry--) {
+ printk("RPC: garbage, retrying %4d\n", task->tk_pid);
task->tk_action = call_encode;
return NULL;
}
@@ -776,24 +782,3 @@ garbage:
rpc_exit(task, -EIO);
return NULL;
}
-
-#ifdef MODULE
-int
-init_module(void)
-{
-#ifdef RPC_DEBUG
- rpc_register_sysctl();
-#endif
- rpc_proc_init();
- return 0;
-}
-
-void
-cleanup_module(void)
-{
-#ifdef RPC_DEBUG
- rpc_unregister_sysctl();
-#endif
- rpc_proc_exit();
-}
-#endif
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 6e14bb287..765dc05fc 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -16,6 +16,7 @@
#include <linux/unistd.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
+
#include <linux/sunrpc/clnt.h>
#ifdef RPC_DEBUG
@@ -45,6 +46,11 @@ static struct rpc_wait_queue schedq = RPC_INIT_WAITQ("schedq");
static struct rpc_wait_queue childq = RPC_INIT_WAITQ("childq");
/*
+ * RPC tasks sit here while waiting for conditions to improve.
+ */
+static struct rpc_wait_queue delay_queue = RPC_INIT_WAITQ("delayq");
+
+/*
* All RPC tasks are linked into this list
*/
static struct rpc_task * all_tasks = NULL;
@@ -92,7 +98,8 @@ rpc_add_wait_queue(struct rpc_wait_queue *queue, struct rpc_task *task)
}
/*
- * Remove request from queue
+ * Remove request from queue.
+ * Note: must be called with interrupts disabled.
*/
void
rpc_remove_wait_queue(struct rpc_task *task)
@@ -149,6 +156,9 @@ rpc_del_timer(struct rpc_task *task)
/*
* Make an RPC task runnable.
+ *
+ * Note: If the task is ASYNC, this must be called with
+ * interrupts disabled to protect the wait queue operation.
*/
static inline void
rpc_make_runnable(struct rpc_task *task)
@@ -313,8 +323,6 @@ static void __rpc_atrun(struct rpc_task *);
void
rpc_delay(struct rpc_task *task, unsigned long delay)
{
- static struct rpc_wait_queue delay_queue;
-
task->tk_timeout = delay;
rpc_sleep_on(&delay_queue, task, NULL, __rpc_atrun);
}
@@ -388,12 +396,14 @@ __rpc_execute(struct rpc_task *task)
/* sync task: sleep here */
dprintk("RPC: %4d sync task going to sleep\n",
task->tk_pid);
+ if (current->pid == rpciod_pid)
+ printk("RPC: rpciod waiting on sync task!\n");
current->timeout = 0;
sleep_on(&task->tk_wait);
/* When the task received a signal, remove from
* any queues etc, and make runnable again. */
- if (signalled())
+ if (0 && signalled())
__rpc_wake_up(task);
dprintk("RPC: %4d sync task resuming\n",
@@ -433,10 +443,15 @@ rpc_execute(struct rpc_task *task)
static int executing = 0;
int incr = RPC_IS_ASYNC(task)? 1 : 0;
- if (incr && (executing || rpc_inhibit)) {
- printk("RPC: rpc_execute called recursively!\n");
- return;
+ if (incr) {
+ if (rpc_inhibit) {
+ printk("RPC: execution inhibited!\n");
+ return;
+ }
+ if (executing)
+ printk("RPC: %d tasks executed\n", executing);
}
+
executing += incr;
__rpc_execute(task);
executing -= incr;
@@ -519,6 +534,7 @@ rpc_allocate(unsigned int flags, unsigned int size)
if (flags & RPC_TASK_ASYNC)
return NULL;
current->timeout = jiffies + (HZ >> 4);
+ current->state = TASK_INTERRUPTIBLE;
schedule();
} while (!signalled());
@@ -684,20 +700,27 @@ rpc_new_child(struct rpc_clnt *clnt, struct rpc_task *parent)
{
struct rpc_task *task;
- if (!(task = rpc_new_task(clnt, NULL, RPC_TASK_ASYNC|RPC_TASK_CHILD))) {
- parent->tk_status = -ENOMEM;
- return NULL;
- }
+ task = rpc_new_task(clnt, NULL, RPC_TASK_ASYNC | RPC_TASK_CHILD);
+ if (!task)
+ goto fail;
task->tk_exit = rpc_child_exit;
task->tk_calldata = parent;
-
return task;
+
+fail:
+ parent->tk_status = -ENOMEM;
+ return NULL;
}
void
rpc_run_child(struct rpc_task *task, struct rpc_task *child, rpc_action func)
{
+ unsigned long oldflags;
+
+ save_flags(oldflags); cli();
rpc_make_runnable(child);
+ restore_flags(oldflags);
+ /* N.B. Is it possible for the child to have already finished? */
rpc_sleep_on(&childq, task, func, NULL);
}
@@ -711,6 +734,7 @@ rpc_killall_tasks(struct rpc_clnt *clnt)
struct rpc_task **q, *rovr;
dprintk("RPC: killing all tasks for client %p\n", clnt);
+ /* N.B. Why bother to inhibit? Nothing blocks here ... */
rpc_inhibit++;
for (q = &all_tasks; (rovr = *q); q = &rovr->tk_next_task) {
if (!clnt || rovr->tk_client == clnt) {
@@ -792,29 +816,21 @@ static void
rpciod_killall(void)
{
unsigned long flags;
- sigset_t old_set;
-
- /* FIXME: What had been going on before was saving and restoring
- current->signal. This as opposed to blocking signals? Do we
- still need them to wake up out of schedule? In any case it
- isn't playing nice and a better way should be found. */
-
- spin_lock_irqsave(&current->sigmask_lock, flags);
- old_set = current->blocked;
- sigfillset(&current->blocked);
- recalc_sigpending(current);
- spin_unlock_irqrestore(&current->sigmask_lock, flags);
while (all_tasks) {
+ current->sigpending = 0;
rpc_killall_tasks(NULL);
__rpc_schedule();
- current->timeout = jiffies + HZ / 100;
- need_resched = 1;
- schedule();
+ if (all_tasks) {
+printk("rpciod_killall: waiting for tasks to exit\n");
+ current->state = TASK_INTERRUPTIBLE;
+ current->timeout = jiffies + 1;
+ schedule();
+ current->timeout = 0;
+ }
}
spin_lock_irqsave(&current->sigmask_lock, flags);
- current->blocked = old_set;
recalc_sigpending(current);
spin_unlock_irqrestore(&current->sigmask_lock, flags);
}
@@ -901,3 +917,37 @@ out:
up(&rpciod_sema);
MOD_DEC_USE_COUNT;
}
+
+#ifdef RPC_DEBUG
+#include <linux/nfs_fs.h>
+void rpc_show_tasks(void)
+{
+ struct rpc_task *t = all_tasks, *next;
+ struct nfs_wreq *wreq;
+
+ if (!t)
+ return;
+ printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout "
+ "-rpcwait -action- --exit--\n");
+ for (; t; t = next) {
+ next = t->tk_next_task;
+ printk("%05d %04d %04x %06d %8p %6d %8p %08ld %8s %8p %8p\n",
+ t->tk_pid, t->tk_proc, t->tk_flags, t->tk_status,
+ t->tk_client, t->tk_client->cl_prog,
+ t->tk_rqstp, t->tk_timeout,
+ t->tk_rpcwait ? rpc_qname(t->tk_rpcwait) : " <NULL> ",
+ t->tk_action, t->tk_exit);
+
+ if (!(t->tk_flags & RPC_TASK_NFSWRITE))
+ continue;
+ /* NFS write requests */
+ wreq = (struct nfs_wreq *) t->tk_calldata;
+ printk(" NFS: flgs=%08x, pid=%d, pg=%p, off=(%d, %d)\n",
+ wreq->wb_flags, wreq->wb_pid, wreq->wb_page,
+ wreq->wb_offset, wreq->wb_bytes);
+ printk(" name=%s/%s\n",
+ wreq->wb_dentry->d_parent->d_name.name,
+ wreq->wb_dentry->d_name.name);
+ }
+}
+#endif
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 90a23a232..94a5ba21c 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -12,6 +12,8 @@
* Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
*/
+#include <linux/module.h>
+
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
@@ -20,7 +22,7 @@
#define RPCDBG_FACILITY RPCDBG_MISC
-static struct proc_dir_entry *proc_net_rpc = 0;
+static struct proc_dir_entry *proc_net_rpc = NULL;
/*
* Get RPC client stats
@@ -161,15 +163,61 @@ void
rpc_proc_init(void)
{
dprintk("RPC: registering /proc/net/rpc\n");
- if (!proc_net_rpc)
- proc_net_rpc = create_proc_entry("net/rpc", S_IFDIR, 0);
+ if (!proc_net_rpc) {
+ struct proc_dir_entry *ent;
+ ent = create_proc_entry("net/rpc", S_IFDIR, 0);
+ if (ent) {
+#ifdef MODULE
+ ent->fill_inode = rpc_modcount;
+#endif
+ proc_net_rpc = ent;
+ }
+ }
}
void
rpc_proc_exit(void)
{
dprintk("RPC: unregistering /proc/net/rpc\n");
- if (proc_net_rpc)
+ if (proc_net_rpc) {
+ proc_net_rpc = NULL;
remove_proc_entry("net/rpc", 0);
- proc_net_rpc = 0;
+ }
+}
+
+#ifdef MODULE
+/*
+ * This is called as the proc_dir_entry fill_inode function
+ * when an inode is going into or out of service (fill == 1
+ * or 0 respectively).
+ *
+ * We use it here to keep the module from being unloaded
+ * while /proc inodes are in use.
+ */
+void rpc_modcount(struct inode *inode, int fill)
+{
+ if (fill)
+ MOD_INC_USE_COUNT;
+ else
+ MOD_DEC_USE_COUNT;
+}
+
+int
+init_module(void)
+{
+#ifdef RPC_DEBUG
+ rpc_register_sysctl();
+#endif
+ rpc_proc_init();
+ return 0;
+}
+
+void
+cleanup_module(void)
+{
+#ifdef RPC_DEBUG
+ rpc_unregister_sysctl();
+#endif
+ rpc_proc_exit();
}
+#endif
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 73f805f40..8c1df5a50 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -62,7 +62,6 @@ EXPORT_SYMBOL(rpcauth_releasecred);
/* RPC server stuff */
EXPORT_SYMBOL(svc_create);
-EXPORT_SYMBOL(svc_create_socket);
EXPORT_SYMBOL(svc_create_thread);
EXPORT_SYMBOL(svc_exit_thread);
EXPORT_SYMBOL(svc_destroy);
@@ -70,6 +69,7 @@ EXPORT_SYMBOL(svc_drop);
EXPORT_SYMBOL(svc_process);
EXPORT_SYMBOL(svc_recv);
EXPORT_SYMBOL(svc_wake_up);
+EXPORT_SYMBOL(svc_makesock);
/* RPC statistics */
#ifdef CONFIG_PROC_FS
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 79882845c..1d1c0a95e 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -172,7 +172,6 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port)
{
struct svc_program *progp;
unsigned long flags;
- sigset_t old_set;
int i, error = 0, dummy;
progp = serv->sv_program;
@@ -180,18 +179,8 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port)
dprintk("RPC: svc_register(%s, %s, %d)\n",
progp->pg_name, proto == IPPROTO_UDP? "udp" : "tcp", port);
- /* FIXME: What had been going on before was saving and restoring
- current->signal. This as opposed to blocking signals? Do we
- still need them to wake up out of schedule? In any case it
- isn't playing nice and a better way should be found. */
-
- if (!port) {
- spin_lock_irqsave(&current->sigmask_lock, flags);
- old_set = current->blocked;
- sigfillset(&current->blocked);
- recalc_sigpending(current);
- spin_unlock_irqrestore(&current->sigmask_lock, flags);
- }
+ if (!port)
+ current->sigpending = 0;
for (i = 0; i < progp->pg_nvers; i++) {
if (progp->pg_vers[i] == NULL)
@@ -207,7 +196,6 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port)
if (!port) {
spin_lock_irqsave(&current->sigmask_lock, flags);
- current->blocked = old_set;
recalc_sigpending(current);
spin_unlock_irqrestore(&current->sigmask_lock, flags);
}
@@ -235,7 +223,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
bufp = argp->buf;
if (argp->len < 5)
- goto dropit;
+ goto err_short_len;
dir = ntohl(*bufp++);
vers = ntohl(*bufp++);
@@ -244,10 +232,8 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
svc_putlong(resp, xdr_one); /* REPLY */
svc_putlong(resp, xdr_zero); /* ACCEPT */
- if (dir != 0) { /* direction != CALL */
- serv->sv_stats->rpcbadfmt++;
- goto dropit; /* drop request */
- }
+ if (dir != 0) /* direction != CALL */
+ goto err_bad_dir;
if (vers != 2) /* RPC version number */
goto err_bad_rpc;
@@ -281,7 +267,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
procp = versp->vs_proc + proc;
if (proc >= versp->vs_nproc || !procp->pc_func)
- goto err_unknown;
+ goto err_bad_proc;
rqstp->rq_server = serv;
rqstp->rq_procinfo = procp;
@@ -329,21 +315,36 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
if (procp->pc_release)
procp->pc_release(rqstp, NULL, rqstp->rq_resp);
- if (procp->pc_encode != NULL)
- return svc_send(rqstp);
+ if (procp->pc_encode == NULL)
+ goto dropit;
+sendit:
+ return svc_send(rqstp);
dropit:
dprintk("svc: svc_process dropit\n");
svc_drop(rqstp);
return 0;
+err_short_len:
+#ifdef RPC_PARANOIA
+ printk("svc: short len %d, dropping request\n", argp->len);
+#endif
+ goto dropit; /* drop request */
+
+err_bad_dir:
+#ifdef RPC_PARANOIA
+ printk("svc: bad direction %d, dropping request\n", dir);
+#endif
+ serv->sv_stats->rpcbadfmt++;
+ goto dropit; /* drop request */
+
err_bad_rpc:
serv->sv_stats->rpcbadfmt++;
resp->buf[-1] = xdr_one; /* REJECT */
svc_putlong(resp, xdr_zero); /* RPC_MISMATCH */
svc_putlong(resp, xdr_two); /* Only RPCv2 supported */
svc_putlong(resp, xdr_two);
- goto error;
+ goto sendit;
err_bad_auth:
dprintk("svc: authentication failed (%ld)\n", ntohl(auth_stat));
@@ -351,7 +352,7 @@ err_bad_auth:
resp->buf[-1] = xdr_one; /* REJECT */
svc_putlong(resp, xdr_one); /* AUTH_ERROR */
svc_putlong(resp, auth_stat); /* status */
- goto error;
+ goto sendit;
err_bad_prog:
#ifdef RPC_PARANOIA
@@ -359,7 +360,7 @@ err_bad_prog:
#endif
serv->sv_stats->rpcbadfmt++;
svc_putlong(resp, rpc_prog_unavail);
- goto error;
+ goto sendit;
err_bad_vers:
#ifdef RPC_PARANOIA
@@ -369,15 +370,15 @@ err_bad_vers:
svc_putlong(resp, rpc_prog_mismatch);
svc_putlong(resp, htonl(progp->pg_lovers));
svc_putlong(resp, htonl(progp->pg_hivers));
- goto error;
+ goto sendit;
-err_unknown:
+err_bad_proc:
#ifdef RPC_PARANOIA
printk("svc: unknown procedure (%d)\n", proc);
#endif
serv->sv_stats->rpcbadfmt++;
svc_putlong(resp, rpc_proc_unavail);
- goto error;
+ goto sendit;
err_garbage:
#ifdef RPC_PARANOIA
@@ -385,7 +386,5 @@ err_garbage:
#endif
serv->sv_stats->rpcbadfmt++;
svc_putlong(resp, rpc_garbage_args);
-
-error:
- return svc_send(rqstp);
+ goto sendit;
}
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 2701a8398..cec276857 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -131,10 +131,10 @@ svc_sock_dequeue(struct svc_serv *serv)
{
struct svc_sock *svsk;
- disable_bh(NET_BH);
+ start_bh_atomic();
if ((svsk = serv->sv_sockets) != NULL)
rpc_remove_list(&serv->sv_sockets, svsk);
- enable_bh(NET_BH);
+ end_bh_atomic();
if (svsk) {
dprintk("svc: socket %p dequeued\n", svsk->sk_sk);
@@ -151,7 +151,7 @@ svc_sock_dequeue(struct svc_serv *serv)
static inline void
svc_sock_received(struct svc_sock *svsk, int count)
{
- disable_bh(NET_BH);
+ start_bh_atomic();
if ((svsk->sk_data -= count) < 0) {
printk(KERN_NOTICE "svc: sk_data negative!\n");
svsk->sk_data = 0;
@@ -163,7 +163,7 @@ svc_sock_received(struct svc_sock *svsk, int count)
svsk->sk_sk);
svc_sock_enqueue(svsk);
}
- enable_bh(NET_BH);
+ end_bh_atomic();
}
/*
@@ -172,7 +172,7 @@ svc_sock_received(struct svc_sock *svsk, int count)
static inline void
svc_sock_accepted(struct svc_sock *svsk)
{
- disable_bh(NET_BH);
+ start_bh_atomic();
svsk->sk_busy = 0;
svsk->sk_conn--;
if (svsk->sk_conn || svsk->sk_data || svsk->sk_close) {
@@ -180,7 +180,7 @@ svc_sock_accepted(struct svc_sock *svsk)
svsk->sk_sk);
svc_sock_enqueue(svsk);
}
- enable_bh(NET_BH);
+ end_bh_atomic();
}
/*
@@ -739,9 +739,9 @@ again:
if (signalled())
return -EINTR;
- disable_bh(NET_BH);
+ start_bh_atomic();
if ((svsk = svc_sock_dequeue(serv)) != NULL) {
- enable_bh(NET_BH);
+ end_bh_atomic();
rqstp->rq_sock = svsk;
svsk->sk_inuse++; /* N.B. where is this decremented? */
} else {
@@ -756,7 +756,7 @@ again:
*/
current->state = TASK_INTERRUPTIBLE;
add_wait_queue(&rqstp->rq_wait, &wait);
- enable_bh(NET_BH);
+ end_bh_atomic();
schedule();
if (!(svsk = rqstp->rq_sock)) {
@@ -886,7 +886,7 @@ if (svsk->sk_sk == NULL)
/*
* Create socket for RPC service.
*/
-int
+static int
svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin)
{
struct svc_sock *svsk;
@@ -969,3 +969,19 @@ svc_delete_socket(struct svc_sock *svsk)
/* svsk->sk_server = NULL; */
}
}
+
+/*
+ * Make a socket for nfsd and lockd
+ */
+int
+svc_makesock(struct svc_serv *serv, int protocol, unsigned short port)
+{
+ struct sockaddr_in sin;
+
+ dprintk("svc: creating socket proto = %d\n", protocol);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ sin.sin_port = htons(port);
+ return svc_create_socket(serv, protocol, &sin);
+}
+
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index 859d55853..a48e9c1ad 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -13,15 +13,11 @@
#include <linux/ctype.h>
#include <linux/fs.h>
#include <linux/sysctl.h>
-#if LINUX_VERSION_CODE >= 0x020100
+
#include <asm/uaccess.h>
-#else
-# include <linux/mm.h>
-# define copy_from_user memcpy_fromfs
-# define copy_to_user memcpy_tofs
-# define access_ok !verify_area
-#endif
#include <linux/sunrpc/types.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/stats.h>
/*
* Declare the debug flags here
@@ -39,17 +35,23 @@ static ctl_table sunrpc_table[];
void
rpc_register_sysctl(void)
{
- if (sunrpc_table_header)
- return;
- sunrpc_table_header = register_sysctl_table(sunrpc_table, 1);
+ if (!sunrpc_table_header) {
+ sunrpc_table_header = register_sysctl_table(sunrpc_table, 1);
+#ifdef MODULE
+ if (sunrpc_table[0].de)
+ sunrpc_table[0].de->fill_inode = rpc_modcount;
+#endif
+ }
+
}
void
rpc_unregister_sysctl(void)
{
- if (!sunrpc_table_header)
- return;
- unregister_sysctl_table(sunrpc_table_header);
+ if (sunrpc_table_header) {
+ unregister_sysctl_table(sunrpc_table_header);
+ sunrpc_table_header = NULL;
+ }
}
int
@@ -93,6 +95,10 @@ proc_dodebug(ctl_table *table, int write, struct file *file,
while (left && isspace(*p))
left--, p++;
*(unsigned int *) table->data = value;
+ /* Display the RPC tasks on writing to rpc_debug */
+ if (table->ctl_name == CTL_RPCDEBUG) {
+ rpc_show_tasks();
+ }
} else {
if (!access_ok(VERIFY_WRITE, buffer, left))
return -EFAULT;
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index c76566399..f614cfa33 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -48,11 +48,11 @@
#include <linux/udp.h>
#include <linux/unistd.h>
#include <linux/sunrpc/clnt.h>
+#include <linux/file.h>
+
#include <net/sock.h>
-#if LINUX_VERSION_CODE >= 0x020100
#include <asm/uaccess.h>
-#endif
#define SOCK_HAS_USER_DATA
@@ -319,7 +319,7 @@ xprt_close(struct rpc_xprt *xprt)
sk->write_space = xprt->old_write_space;
if (xprt->file)
- close_fp(xprt->file);
+ fput(xprt->file);
else
sock_release(xprt->sock);
}
@@ -397,14 +397,14 @@ xprt_reconnect(struct rpc_task *task)
task->tk_pid, status, xprt->connected);
task->tk_timeout = 60 * HZ;
- disable_bh(NET_BH);
+ start_bh_atomic();
if (!xprt->connected) {
rpc_sleep_on(&xprt->reconn, task,
xprt_reconn_status, xprt_reconn_timeout);
- enable_bh(NET_BH);
+ end_bh_atomic();
return;
}
- enable_bh(NET_BH);
+ end_bh_atomic();
}
xprt->connecting = 0;
@@ -870,10 +870,10 @@ xprt_transmit(struct rpc_task *task)
/* For fast networks/servers we have to put the request on
* the pending list now:
*/
- disable_bh(NET_BH);
+ start_bh_atomic();
rpc_add_wait_queue(&xprt->pending, task);
task->tk_callback = NULL;
- enable_bh(NET_BH);
+ end_bh_atomic();
/* Continue transmitting the packet/record. We must be careful
* to cope with writespace callbacks arriving _after_ we have
@@ -891,16 +891,16 @@ xprt_transmit(struct rpc_task *task)
task->tk_pid, xprt->snd_buf.io_len,
req->rq_slen);
task->tk_status = 0;
- disable_bh(NET_BH);
+ start_bh_atomic();
if (!xprt->write_space) {
/* Remove from pending */
rpc_remove_wait_queue(task);
rpc_sleep_on(&xprt->sending, task,
xprt_transmit_status, NULL);
- enable_bh(NET_BH);
+ end_bh_atomic();
return;
}
- enable_bh(NET_BH);
+ end_bh_atomic();
}
}
@@ -943,12 +943,12 @@ xprt_receive(struct rpc_task *task)
*/
task->tk_timeout = req->rq_timeout.to_current;
- disable_bh(NET_BH);
+ start_bh_atomic();
if (!req->rq_gotit) {
rpc_sleep_on(&xprt->pending, task,
xprt_receive_status, xprt_timer);
}
- enable_bh(NET_BH);
+ end_bh_atomic();
dprintk("RPC: %4d xprt_receive returns %d\n",
task->tk_pid, task->tk_status);
@@ -1079,7 +1079,7 @@ xprt_release(struct rpc_task *task)
dprintk("RPC: %4d release request %p\n", task->tk_pid, req);
/* remove slot from queue of pending */
- disable_bh(NET_BH);
+ start_bh_atomic();
if (task->tk_rpcwait) {
printk("RPC: task of released request still queued!\n");
#ifdef RPC_DEBUG
@@ -1088,7 +1088,7 @@ xprt_release(struct rpc_task *task)
rpc_del_timer(task);
rpc_remove_wait_queue(task);
}
- enable_bh(NET_BH);
+ end_bh_atomic();
/* Decrease congestion value. If congestion threshold is not yet
* reached, pass on the request slot.