Commit 64596af0 authored by Trond Myklebust's avatar Trond Myklebust

RPC: add a field to the xdr_buf that explicitly contains the maximum buffer

     length.
RPC: make the client receive xdr_buf return the actual length of the RPC
     length.
NFSv4/RPC: improved checks to prevent XDR reading beyond the actual end of
     the RPC reply.
parent d9d762e7
...@@ -231,7 +231,7 @@ nfs_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args) ...@@ -231,7 +231,7 @@ nfs_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args)
static int static int
nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res) nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
{ {
struct iovec *iov = req->rq_rvec; struct iovec *iov = req->rq_rcv_buf.head;
int status, count, recvd, hdrlen; int status, count, recvd, hdrlen;
if ((status = ntohl(*p++))) if ((status = ntohl(*p++)))
...@@ -250,7 +250,7 @@ nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res) ...@@ -250,7 +250,7 @@ nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen); xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
} }
recvd = req->rq_received - hdrlen; recvd = req->rq_rcv_buf.len - hdrlen;
if (count > recvd) { if (count > recvd) {
printk(KERN_WARNING "NFS: server cheating in read reply: " printk(KERN_WARNING "NFS: server cheating in read reply: "
"count %d > recvd %d\n", count, recvd); "count %d > recvd %d\n", count, recvd);
...@@ -396,7 +396,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy) ...@@ -396,7 +396,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy)
} }
pglen = rcvbuf->page_len; pglen = rcvbuf->page_len;
recvd = req->rq_received - hdrlen; recvd = rcvbuf->len - hdrlen;
if (pglen > recvd) if (pglen > recvd)
pglen = recvd; pglen = recvd;
page = rcvbuf->pages; page = rcvbuf->pages;
......
...@@ -515,7 +515,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res) ...@@ -515,7 +515,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res)
} }
pglen = rcvbuf->page_len; pglen = rcvbuf->page_len;
recvd = req->rq_received - hdrlen; recvd = rcvbuf->len - hdrlen;
if (pglen > recvd) if (pglen > recvd)
pglen = recvd; pglen = recvd;
page = rcvbuf->pages; page = rcvbuf->pages;
...@@ -758,7 +758,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr) ...@@ -758,7 +758,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
static int static int
nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res) nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
{ {
struct iovec *iov = req->rq_rvec; struct iovec *iov = req->rq_rcv_buf.head;
int status, count, ocount, recvd, hdrlen; int status, count, ocount, recvd, hdrlen;
status = ntohl(*p++); status = ntohl(*p++);
...@@ -789,7 +789,7 @@ nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res) ...@@ -789,7 +789,7 @@ nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen); xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
} }
recvd = req->rq_received - hdrlen; recvd = req->rq_rcv_buf.len - hdrlen;
if (count > recvd) { if (count > recvd) {
printk(KERN_WARNING "NFS: server cheating in read reply: " printk(KERN_WARNING "NFS: server cheating in read reply: "
"count %d > recvd %d\n", count, recvd); "count %d > recvd %d\n", count, recvd);
......
...@@ -2671,7 +2671,7 @@ static int decode_putrootfh(struct xdr_stream *xdr) ...@@ -2671,7 +2671,7 @@ static int decode_putrootfh(struct xdr_stream *xdr)
static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_readres *res) static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_readres *res)
{ {
struct iovec *iov = req->rq_rvec; struct iovec *iov = req->rq_rcv_buf.head;
uint32_t *p; uint32_t *p;
uint32_t count, eof, recvd, hdrlen; uint32_t count, eof, recvd, hdrlen;
int status; int status;
...@@ -2683,7 +2683,7 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_ ...@@ -2683,7 +2683,7 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_
READ32(eof); READ32(eof);
READ32(count); READ32(count);
hdrlen = (u8 *) p - (u8 *) iov->iov_base; hdrlen = (u8 *) p - (u8 *) iov->iov_base;
recvd = req->rq_received - hdrlen; recvd = req->rq_rcv_buf.len - hdrlen;
if (count > recvd) { if (count > recvd) {
printk(KERN_WARNING "NFS: server cheating in read reply: " printk(KERN_WARNING "NFS: server cheating in read reply: "
"count %u > recvd %u\n", count, recvd); "count %u > recvd %u\n", count, recvd);
...@@ -2713,7 +2713,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n ...@@ -2713,7 +2713,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
COPYMEM(readdir->verifier.data, 8); COPYMEM(readdir->verifier.data, 8);
hdrlen = (char *) p - (char *) iov->iov_base; hdrlen = (char *) p - (char *) iov->iov_base;
recvd = req->rq_received - hdrlen; recvd = rcvbuf->len - hdrlen;
if (pglen > recvd) if (pglen > recvd)
pglen = recvd; pglen = recvd;
xdr_read_pages(xdr, pglen); xdr_read_pages(xdr, pglen);
......
...@@ -55,7 +55,8 @@ struct xdr_buf { ...@@ -55,7 +55,8 @@ struct xdr_buf {
unsigned int page_base, /* Start of page data */ unsigned int page_base, /* Start of page data */
page_len; /* Length of page data */ page_len; /* Length of page data */
unsigned int len; /* Total length of data */ unsigned int buflen, /* Total length of storage buffer */
len; /* Length of XDR encoded message */
}; };
...@@ -183,86 +184,14 @@ struct xdr_stream { ...@@ -183,86 +184,14 @@ struct xdr_stream {
struct iovec *iov; /* pointer to the current iovec */ struct iovec *iov; /* pointer to the current iovec */
}; };
/* extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
* Initialize an xdr_stream for encoding data. extern uint32_t *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
*
* Note: at the moment the RPC client only passes the length of our
* scratch buffer in the xdr_buf's header iovec. Previously this
* meant we needed to call xdr_adjust_iovec() after encoding the
* data. With the new scheme, the xdr_stream manages the details
* of the buffer length, and takes care of adjusting the iovec
* length for us.
*/
static inline void
xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
{
struct iovec *iov = buf->head;
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;
}
/*
* Check that we have enough buffer space to encode 'nbytes' more
* bytes of data. If so, update the total xdr_buf length, and
* adjust the length of the current iovec.
*/
static inline uint32_t *
xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
{
uint32_t *p = xdr->p;
uint32_t *q;
/* align nbytes on the next 32-bit boundary */
nbytes += 3;
nbytes &= ~3;
q = p + (nbytes >> 2);
if (unlikely(q > xdr->end || q < p))
return NULL;
xdr->p = q;
xdr->iov->iov_len += nbytes;
xdr->buf->len += nbytes;
return p;
}
extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
unsigned int base, unsigned int len); unsigned int base, unsigned int len);
extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len); extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
/*
* Initialize an xdr_stream for decoding data.
*/
static inline void
xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
{
struct iovec *iov = buf->head;
xdr->buf = buf;
xdr->iov = iov;
xdr->p = p;
xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
}
/*
* Check if the input buffer is long enough to enable us to decode
* 'nbytes' more bytes of data starting at the current position.
* If so return the current pointer, then update the current
* position.
*/
static inline uint32_t *
xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
{
uint32_t *p = xdr->p;
uint32_t *q = p + XDR_QUADLEN(nbytes);
if (unlikely(q > xdr->end || q < p))
return NULL;
xdr->p = q;
return p;
}
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _SUNRPC_XDR_H_ */ #endif /* _SUNRPC_XDR_H_ */
...@@ -120,8 +120,6 @@ struct rpc_rqst { ...@@ -120,8 +120,6 @@ struct rpc_rqst {
}; };
#define rq_svec rq_snd_buf.head #define rq_svec rq_snd_buf.head
#define rq_slen rq_snd_buf.len #define rq_slen rq_snd_buf.len
#define rq_rvec rq_rcv_buf.head
#define rq_rlen rq_rcv_buf.len
#define XPRT_LAST_FRAG (1 << 0) #define XPRT_LAST_FRAG (1 << 0)
#define XPRT_COPY_RECM (1 << 1) #define XPRT_COPY_RECM (1 << 1)
......
...@@ -605,11 +605,13 @@ call_encode(struct rpc_task *task) ...@@ -605,11 +605,13 @@ call_encode(struct rpc_task *task)
sndbuf->tail[0].iov_len = 0; sndbuf->tail[0].iov_len = 0;
sndbuf->page_len = 0; sndbuf->page_len = 0;
sndbuf->len = 0; sndbuf->len = 0;
sndbuf->buflen = bufsiz;
rcvbuf->head[0].iov_base = (void *)((char *)task->tk_buffer + bufsiz); rcvbuf->head[0].iov_base = (void *)((char *)task->tk_buffer + bufsiz);
rcvbuf->head[0].iov_len = bufsiz; rcvbuf->head[0].iov_len = bufsiz;
rcvbuf->tail[0].iov_len = 0; rcvbuf->tail[0].iov_len = 0;
rcvbuf->page_len = 0; rcvbuf->page_len = 0;
rcvbuf->len = bufsiz; rcvbuf->len = 0;
rcvbuf->buflen = bufsiz;
/* Encode header and provided arguments */ /* Encode header and provided arguments */
encode = task->tk_msg.rpc_proc->p_encode; encode = task->tk_msg.rpc_proc->p_encode;
...@@ -849,6 +851,8 @@ call_decode(struct rpc_task *task) ...@@ -849,6 +851,8 @@ call_decode(struct rpc_task *task)
return; return;
} }
req->rq_rcv_buf.len = req->rq_private_buf.len;
/* Check that the softirq receive buffer is valid */ /* Check that the softirq receive buffer is valid */
WARN_ON(memcmp(&req->rq_rcv_buf, &req->rq_private_buf, WARN_ON(memcmp(&req->rq_rcv_buf, &req->rq_private_buf,
sizeof(req->rq_rcv_buf)) != 0); sizeof(req->rq_rcv_buf)) != 0);
...@@ -884,7 +888,7 @@ call_decode(struct rpc_task *task) ...@@ -884,7 +888,7 @@ call_decode(struct rpc_task *task)
task->tk_status); task->tk_status);
return; return;
out_retry: out_retry:
req->rq_received = 0; req->rq_received = req->rq_private_buf.len = 0;
task->tk_status = 0; task->tk_status = 0;
} }
...@@ -956,7 +960,7 @@ call_header(struct rpc_task *task) ...@@ -956,7 +960,7 @@ call_header(struct rpc_task *task)
static u32 * static u32 *
call_verify(struct rpc_task *task) call_verify(struct rpc_task *task)
{ {
u32 *p = task->tk_rqstp->rq_rvec[0].iov_base, n; u32 *p = task->tk_rqstp->rq_rcv_buf.head[0].iov_base, n;
p += 1; /* skip XID */ p += 1; /* skip XID */
......
...@@ -128,8 +128,6 @@ EXPORT_SYMBOL(xdr_encode_netobj); ...@@ -128,8 +128,6 @@ EXPORT_SYMBOL(xdr_encode_netobj);
EXPORT_SYMBOL(xdr_encode_pages); EXPORT_SYMBOL(xdr_encode_pages);
EXPORT_SYMBOL(xdr_inline_pages); EXPORT_SYMBOL(xdr_inline_pages);
EXPORT_SYMBOL(xdr_shift_buf); EXPORT_SYMBOL(xdr_shift_buf);
EXPORT_SYMBOL(xdr_write_pages);
EXPORT_SYMBOL(xdr_read_pages);
EXPORT_SYMBOL(xdr_buf_from_iov); EXPORT_SYMBOL(xdr_buf_from_iov);
EXPORT_SYMBOL(xdr_buf_subsegment); EXPORT_SYMBOL(xdr_buf_subsegment);
EXPORT_SYMBOL(xdr_buf_read_netobj); EXPORT_SYMBOL(xdr_buf_read_netobj);
......
...@@ -160,6 +160,7 @@ xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, ...@@ -160,6 +160,7 @@ xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base,
tail->iov_len = pad; tail->iov_len = pad;
len += pad; len += pad;
} }
xdr->buflen += len;
xdr->len += len; xdr->len += len;
} }
...@@ -181,7 +182,7 @@ xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset, ...@@ -181,7 +182,7 @@ xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset,
tail->iov_base = buf + offset; tail->iov_base = buf + offset;
tail->iov_len = buflen - offset; tail->iov_len = buflen - offset;
xdr->len += len; xdr->buflen += len;
} }
/* /*
...@@ -675,7 +676,10 @@ xdr_shrink_bufhead(struct xdr_buf *buf, size_t len) ...@@ -675,7 +676,10 @@ xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
copy); copy);
} }
head->iov_len -= len; head->iov_len -= len;
buf->len -= len; buf->buflen -= len;
/* Have we truncated the message? */
if (buf->len > buf->buflen)
buf->len = buf->buflen;
} }
/* /*
...@@ -705,7 +709,7 @@ xdr_shrink_pagelen(struct xdr_buf *buf, size_t len) ...@@ -705,7 +709,7 @@ xdr_shrink_pagelen(struct xdr_buf *buf, size_t len)
copy = tail->iov_len - len; copy = tail->iov_len - len;
memmove(p, tail->iov_base, copy); memmove(p, tail->iov_base, copy);
} else } else
buf->len -= len; buf->buflen -= len;
/* Copy from the inlined pages into the tail */ /* Copy from the inlined pages into the tail */
copy = len; copy = len;
if (copy > tail->iov_len) if (copy > tail->iov_len)
...@@ -715,7 +719,10 @@ xdr_shrink_pagelen(struct xdr_buf *buf, size_t len) ...@@ -715,7 +719,10 @@ xdr_shrink_pagelen(struct xdr_buf *buf, size_t len)
copy); copy);
} }
buf->page_len -= len; buf->page_len -= len;
buf->len -= len; buf->buflen -= len;
/* Have we truncated the message? */
if (buf->len > buf->buflen)
buf->len = buf->buflen;
} }
void void
...@@ -724,8 +731,67 @@ xdr_shift_buf(struct xdr_buf *buf, size_t len) ...@@ -724,8 +731,67 @@ xdr_shift_buf(struct xdr_buf *buf, size_t len)
xdr_shrink_bufhead(buf, len); xdr_shrink_bufhead(buf, len);
} }
void /**
xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int base, * xdr_init_encode - Initialize a struct xdr_stream for sending data.
* @xdr: pointer to xdr_stream struct
* @buf: pointer to XDR buffer in which to encode data
* @p: current pointer inside XDR buffer
*
* Note: at the moment the RPC client only passes the length of our
* scratch buffer in the xdr_buf's header iovec. Previously this
* meant we needed to call xdr_adjust_iovec() after encoding the
* data. With the new scheme, the xdr_stream manages the details
* of the buffer length, and takes care of adjusting the iovec
* length for us.
*/
void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
{
struct iovec *iov = buf->head;
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;
}
EXPORT_SYMBOL(xdr_init_encode);
/**
* xdr_reserve_space - Reserve buffer space for sending
* @xdr: pointer to xdr_stream
* @nbytes: number of bytes to reserve
*
* Checks that we have enough buffer space to encode 'nbytes' more
* bytes of data. If so, update the total xdr_buf length, and
* adjust the length of the current iovec.
*/
uint32_t * xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
{
uint32_t *p = xdr->p;
uint32_t *q;
/* align nbytes on the next 32-bit boundary */
nbytes += 3;
nbytes &= ~3;
q = p + (nbytes >> 2);
if (unlikely(q > xdr->end || q < p))
return NULL;
xdr->p = q;
xdr->iov->iov_len += nbytes;
xdr->buf->len += nbytes;
return p;
}
EXPORT_SYMBOL(xdr_reserve_space);
/**
* xdr_write_pages - Insert a list of pages into an XDR buffer for sending
* @xdr: pointer to xdr_stream
* @pages: list of pages
* @base: offset of first byte
* @len: length of data in bytes
*
*/
void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int base,
unsigned int len) unsigned int len)
{ {
struct xdr_buf *buf = xdr->buf; struct xdr_buf *buf = xdr->buf;
...@@ -747,15 +813,69 @@ xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int base, ...@@ -747,15 +813,69 @@ xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int base,
len += pad; len += pad;
*xdr->p++ = 0; *xdr->p++ = 0;
} }
buf->buflen += len;
buf->len += len; buf->len += len;
} }
EXPORT_SYMBOL(xdr_write_pages);
void /**
xdr_read_pages(struct xdr_stream *xdr, unsigned int len) * xdr_init_decode - Initialize an xdr_stream for decoding data.
* @xdr: pointer to xdr_stream struct
* @buf: pointer to XDR buffer from which to decode data
* @p: current pointer inside XDR buffer
*/
void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
{
struct iovec *iov = buf->head;
unsigned int len = iov->iov_len;
if (len > buf->len)
len = buf->len;
xdr->buf = buf;
xdr->iov = iov;
xdr->p = p;
xdr->end = (uint32_t *)((char *)iov->iov_base + len);
}
EXPORT_SYMBOL(xdr_init_decode);
/**
* xdr_inline_decode - Retrieve non-page XDR data to decode
* @xdr: pointer to xdr_stream struct
* @nbytes: number of bytes of data to decode
*
* Check if the input buffer is long enough to enable us to decode
* 'nbytes' more bytes of data starting at the current position.
* If so return the current pointer, then update the current
* pointer position.
*/
uint32_t * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
{
uint32_t *p = xdr->p;
uint32_t *q = p + XDR_QUADLEN(nbytes);
if (unlikely(q > xdr->end || q < p))
return NULL;
xdr->p = q;
return p;
}
EXPORT_SYMBOL(xdr_inline_decode);
/**
* xdr_read_pages - Ensure page-based XDR data to decode is aligned at current pointer position
* @xdr: pointer to xdr_stream struct
* @len: number of bytes of page data
*
* Moves data beyond the current pointer position from the XDR head[] buffer
* into the page list. Any data that lies beyond current position + "len"
* bytes is moved into the XDR tail[]. The current pointer is then
* repositioned at the beginning of the XDR tail.
*/
void xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
{ {
struct xdr_buf *buf = xdr->buf; struct xdr_buf *buf = xdr->buf;
struct iovec *iov; struct iovec *iov;
ssize_t shift; ssize_t shift;
unsigned int end;
int padding; int padding;
/* Realign pages to current pointer position */ /* Realign pages to current pointer position */
...@@ -769,9 +889,21 @@ xdr_read_pages(struct xdr_stream *xdr, unsigned int len) ...@@ -769,9 +889,21 @@ xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
xdr_shrink_pagelen(buf, buf->page_len - len); xdr_shrink_pagelen(buf, buf->page_len - len);
padding = (XDR_QUADLEN(len) << 2) - len; padding = (XDR_QUADLEN(len) << 2) - len;
xdr->iov = iov = buf->tail; xdr->iov = iov = buf->tail;
/* Compute remaining message length. */
end = iov->iov_len;
shift = buf->buflen - buf->len;
if (shift < end)
end -= shift;
else if (shift > 0)
end = 0;
/*
* Position current pointer at beginning of tail, and
* set remaining message length.
*/
xdr->p = (uint32_t *)((char *)iov->iov_base + padding); xdr->p = (uint32_t *)((char *)iov->iov_base + padding);
xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len); xdr->end = (uint32_t *)((char *)iov->iov_base + end);
} }
EXPORT_SYMBOL(xdr_read_pages);
static struct iovec empty_iov = {.iov_base = NULL, .iov_len = 0}; static struct iovec empty_iov = {.iov_base = NULL, .iov_len = 0};
...@@ -781,7 +913,7 @@ xdr_buf_from_iov(struct iovec *iov, struct xdr_buf *buf) ...@@ -781,7 +913,7 @@ xdr_buf_from_iov(struct iovec *iov, struct xdr_buf *buf)
buf->head[0] = *iov; buf->head[0] = *iov;
buf->tail[0] = empty_iov; buf->tail[0] = empty_iov;
buf->page_len = 0; buf->page_len = 0;
buf->len = iov->iov_len; buf->buflen = buf->len = iov->iov_len;
} }
/* Sets subiov to the intersection of iov with the buffer of length len /* Sets subiov to the intersection of iov with the buffer of length len
...@@ -811,7 +943,7 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, ...@@ -811,7 +943,7 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf,
{ {
int i; int i;
subbuf->len = len; subbuf->buflen = subbuf->len = len;
iov_subsegment(buf->head, subbuf->head, &base, &len); iov_subsegment(buf->head, subbuf->head, &base, &len);
if (base < buf->page_len) { if (base < buf->page_len) {
......
...@@ -647,8 +647,8 @@ xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied) ...@@ -647,8 +647,8 @@ xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied)
#endif #endif
dprintk("RPC: %4d has input (%d bytes)\n", task->tk_pid, copied); dprintk("RPC: %4d has input (%d bytes)\n", task->tk_pid, copied);
req->rq_received = copied;
list_del_init(&req->rq_list); list_del_init(&req->rq_list);
req->rq_received = req->rq_private_buf.len = copied;
/* ... and wake up the process. */ /* ... and wake up the process. */
rpc_wake_up_task(task); rpc_wake_up_task(task);
...@@ -765,7 +765,7 @@ udp_data_ready(struct sock *sk, int len) ...@@ -765,7 +765,7 @@ udp_data_ready(struct sock *sk, int len)
dprintk("RPC: %4d received reply\n", task->tk_pid); dprintk("RPC: %4d received reply\n", task->tk_pid);
if ((copied = rovr->rq_private_buf.len) > repsize) if ((copied = rovr->rq_private_buf.buflen) > repsize)
copied = repsize; copied = repsize;
/* Suck it into the iovec, verify checksum if not done by hw. */ /* Suck it into the iovec, verify checksum if not done by hw. */
...@@ -908,7 +908,7 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc) ...@@ -908,7 +908,7 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
xprt->tcp_copied += len; xprt->tcp_copied += len;
xprt->tcp_offset += len; xprt->tcp_offset += len;
if (xprt->tcp_copied == req->rq_private_buf.len) if (xprt->tcp_copied == req->rq_private_buf.buflen)
xprt->tcp_flags &= ~XPRT_COPY_DATA; xprt->tcp_flags &= ~XPRT_COPY_DATA;
else if (xprt->tcp_offset == xprt->tcp_reclen) { else if (xprt->tcp_offset == xprt->tcp_reclen) {
if (xprt->tcp_flags & XPRT_LAST_FRAG) if (xprt->tcp_flags & XPRT_LAST_FRAG)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment