diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-06-22 13:16:19 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-06-22 16:07:02 -0400 |
commit | 334ccfd545bba9690515f2c5c167d5adb161989b (patch) | |
tree | 8a06af4d40c711c578adc36d9afd3200a88a2689 | |
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>
-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 02bc029d46fe..209aaf595695 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -957,7 +957,9 @@ call_header(struct rpc_task *task) | |||
957 | *p++ = htonl(clnt->cl_prog); /* program number */ | 957 | *p++ = htonl(clnt->cl_prog); /* program number */ |
958 | *p++ = htonl(clnt->cl_vers); /* program version */ | 958 | *p++ = htonl(clnt->cl_vers); /* program version */ |
959 | *p++ = htonl(task->tk_msg.rpc_proc->p_proc); /* procedure */ | 959 | *p++ = htonl(task->tk_msg.rpc_proc->p_proc); /* procedure */ |
960 | return rpcauth_marshcred(task, p); | 960 | p = rpcauth_marshcred(task, p); |
961 | req->rq_slen = xdr_adjust_iovec(&req->rq_svec[0], p); | ||
962 | return p; | ||
961 | } | 963 | } |
962 | 964 | ||
963 | /* | 965 | /* |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index bb2d99f33315..a02d424a7409 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) | |||
281 | rqstp->rq_res.len = 0; | 281 | rqstp->rq_res.len = 0; |
282 | rqstp->rq_res.page_base = 0; | 282 | rqstp->rq_res.page_base = 0; |
283 | rqstp->rq_res.page_len = 0; | 283 | rqstp->rq_res.page_len = 0; |
284 | rqstp->rq_res.buflen = PAGE_SIZE; | ||
284 | rqstp->rq_res.tail[0].iov_len = 0; | 285 | rqstp->rq_res.tail[0].iov_len = 0; |
285 | /* tcp needs a space for the record length... */ | 286 | /* tcp needs a space for the record length... */ |
286 | if (rqstp->rq_prot == IPPROTO_TCP) | 287 | if (rqstp->rq_prot == IPPROTO_TCP) |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 67b9f035ba86..f86d1baa6302 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) | |||
616 | void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p) | 616 | void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p) |
617 | { | 617 | { |
618 | struct kvec *iov = buf->head; | 618 | struct kvec *iov = buf->head; |
619 | int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len; | ||
619 | 620 | ||
621 | BUG_ON(scratch_len < 0); | ||
620 | xdr->buf = buf; | 622 | xdr->buf = buf; |
621 | xdr->iov = iov; | 623 | xdr->iov = iov; |
622 | xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len); | 624 | xdr->p = (uint32_t *)((char *)iov->iov_base + iov->iov_len); |
623 | buf->len = iov->iov_len = (char *)p - (char *)iov->iov_base; | 625 | xdr->end = (uint32_t *)((char *)iov->iov_base + scratch_len); |
624 | xdr->p = p; | 626 | BUG_ON(iov->iov_len > scratch_len); |
627 | |||
628 | if (p != xdr->p && p != NULL) { | ||
629 | size_t len; | ||
630 | |||
631 | BUG_ON(p < xdr->p || p > xdr->end); | ||
632 | len = (char *)p - (char *)xdr->p; | ||
633 | xdr->p = p; | ||
634 | buf->len += len; | ||
635 | iov->iov_len += len; | ||
636 | } | ||
625 | } | 637 | } |
626 | EXPORT_SYMBOL(xdr_init_encode); | 638 | EXPORT_SYMBOL(xdr_init_encode); |
627 | 639 | ||