[PATCH] RPC: Ensure XDR iovec length is initialized correctly in call_header
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 22 Jun 2005 17:16:19 +0000 (17:16 +0000)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 22 Jun 2005 20:07:02 +0000 (16:07 -0400)
 Fix up call_header() so that it calls xdr_adjust_iovec().
 Fix calculation of the scratch buffer length in xdr_init_encode().

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
net/sunrpc/clnt.c
net/sunrpc/svc.c
net/sunrpc/xdr.c

index 02bc029d46fe780caf634c6f080b5e8f84a54b79..209aaf5956958e1dfa086b7a3ba05b2e71088f47 100644 (file)
@@ -957,7 +957,9 @@ call_header(struct rpc_task *task)
        *p++ = htonl(clnt->cl_prog);    /* program number */
        *p++ = htonl(clnt->cl_vers);    /* program version */
        *p++ = htonl(task->tk_msg.rpc_proc->p_proc);    /* procedure */
-       return rpcauth_marshcred(task, p);
+       p = rpcauth_marshcred(task, p);
+       req->rq_slen = xdr_adjust_iovec(&req->rq_svec[0], p);
+       return p;
 }
 
 /*
index bb2d99f33315f3565e937c1c42eb5bf44a93d170..a02d424a74097a2c5d4eb394856a38c22d2bb19b 100644 (file)
@@ -281,6 +281,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
        rqstp->rq_res.len = 0;
        rqstp->rq_res.page_base = 0;
        rqstp->rq_res.page_len = 0;
+       rqstp->rq_res.buflen = PAGE_SIZE;
        rqstp->rq_res.tail[0].iov_len = 0;
        /* tcp needs a space for the record length... */
        if (rqstp->rq_prot == IPPROTO_TCP)
index 67b9f035ba8606d1ee1f60bf7b2deb44a86f0e66..f86d1baa63029b38524c7ef0a1c225038f7a9b9a 100644 (file)
@@ -616,12 +616,24 @@ xdr_shift_buf(struct xdr_buf *buf, size_t len)
 void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
 {
        struct kvec *iov = buf->head;
+       int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len;
 
+       BUG_ON(scratch_len < 0);
        xdr->buf = buf;
        xdr->iov = iov;
-       xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
-       buf->len = iov->iov_len = (char *)p - (char *)iov->iov_base;
-       xdr->p = p;
+       xdr->p = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
+       xdr->end = (uint32_t *)((char *)iov->iov_base + scratch_len);
+       BUG_ON(iov->iov_len > scratch_len);
+
+       if (p != xdr->p && p != NULL) {
+               size_t len;
+
+               BUG_ON(p < xdr->p || p > xdr->end);
+               len = (char *)p - (char *)xdr->p;
+               xdr->p = p;
+               buf->len += len;
+               iov->iov_len += len;
+       }
 }
 EXPORT_SYMBOL(xdr_init_encode);