[NFS] another race.

From: Trond Myklebust (trond.myklebust@fys.uio.no)
Date: Mon Jun 12 2000 - 11:36:33 EST


The following patch separates the buffer areas for the RPC
message/reply. The reason for this is that we have a small race when
resending a request: If the reply to the original sent request comes
in while we're in sleeping on the socket lock in xprt_sendmsg() then
it can clobber our resend.

Cheers,
  Trond

--- linux/net/sunrpc/clnt.c.orig Mon Apr 3 22:24:06 2000
+++ linux/net/sunrpc/clnt.c Wed Jun 7 08:44:32 2000
@@ -35,7 +35,7 @@
 #include <linux/nfs.h>
 
 
-#define RPC_SLACK_SPACE 1024 /* total overkill */
+#define RPC_SLACK_SPACE 512 /* total overkill */
 
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY RPCDBG_CALL
@@ -446,7 +446,7 @@
          * auth->au_wslack */
         bufsiz = rpcproc_bufsiz(clnt, task->tk_msg.rpc_proc) + RPC_SLACK_SPACE;
 
- if ((task->tk_buffer = rpc_malloc(task, bufsiz)) != NULL)
+ if ((task->tk_buffer = rpc_malloc(task, bufsiz << 1)) != NULL)
                 return;
         printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task);
 
@@ -480,11 +480,11 @@
 
         /* Default buffer setup */
         bufsiz = rpcproc_bufsiz(clnt, task->tk_msg.rpc_proc)+RPC_SLACK_SPACE;
- req->rq_svec[0].iov_base = task->tk_buffer;
+ req->rq_svec[0].iov_base = (void *)task->tk_buffer;
         req->rq_svec[0].iov_len = bufsiz;
         req->rq_slen = 0;
         req->rq_snr = 1;
- req->rq_rvec[0].iov_base = task->tk_buffer;
+ req->rq_rvec[0].iov_base = (void *)((char *)task->tk_buffer + bufsiz);
         req->rq_rvec[0].iov_len = bufsiz;
         req->rq_rlen = bufsiz;
         req->rq_rnr = 1;
@@ -774,12 +774,13 @@
 {
         struct rpc_clnt *clnt = task->tk_client;
         struct rpc_xprt *xprt = clnt->cl_xprt;
- u32 *p = task->tk_buffer;
+ struct rpc_rqst *req = task->tk_rqstp;
+ u32 *p = req->rq_svec[0].iov_base;
 
         /* FIXME: check buffer size? */
         if (xprt->stream)
                 *p++ = 0; /* fill in later */
- *p++ = task->tk_rqstp->rq_xid; /* XID */
+ *p++ = req->rq_xid; /* XID */
         *p++ = htonl(RPC_CALL); /* CALL */
         *p++ = htonl(RPC_VERSION); /* RPC version */
         *p++ = htonl(clnt->cl_prog); /* program number */
@@ -794,7 +795,7 @@
 static u32 *
 call_verify(struct rpc_task *task)
 {
- u32 *p = task->tk_buffer, n;
+ u32 *p = task->tk_rqstp->rq_rvec[0].iov_base, n;
 
         p += 1; /* skip XID */
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Jun 15 2000 - 21:00:26 EST