diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-06-22 17:16:19 +0000 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-06-22 16:07:02 -0400 |
commit | 334ccfd545bba9690515f2c5c167d5adb161989b (patch) | |
tree | 8a06af4d40c711c578adc36d9afd3200a88a2689 /net | |
parent | d05fdb0cec75415b2d9eb95748386e67414e49c3 (diff) |
[PATCH] RPC: Ensure XDR iovec length is initialized correctly in call_header
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/clnt.c | 4 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 1 | ||||
-rw-r--r-- | net/sunrpc/xdr.c | 18 |
3 files changed, 19 insertions, 4 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 02bc029d46f..209aaf59569 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -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; } /* diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index bb2d99f3331..a02d424a740 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -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) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 67b9f035ba8..f86d1baa630 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -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); |