@@ -1669,6 +1669,7 @@ static __be32 svcxdr_stream_init_from_resp(struct svcxdr_stream *xdr, struct nfs
buf->head[0].iov_len = (char *)resp->p - (char *)buf->head[0].iov_base;
buf->len = buf->head[0].iov_len;
+ xdr->maxbytes = INT_MAX;
xdr->buf = buf;
xdr->this_iov = buf->head;
xdr->ptr.p = resp->p;
@@ -1683,6 +1684,7 @@ static __be32 svcxdr_stream_init_from_resp(struct svcxdr_stream *xdr, struct nfs
*/
static void svcxdr_stream_init_from_buffer(struct svcxdr_stream *xdr, __be32 *buf, int len)
{
+ xdr->maxbytes = INT_MAX;
xdr->ptr.p = buf;
xdr->ptr.end = buf + len;
xdr->ptr.next_page = NULL;
@@ -1724,8 +1726,12 @@ static bool svcxdr_reserve_space(struct svcxdr_stream *xdr, struct svcxdr_ptr *p
*ptr = xdr->ptr;
bytes = roundup(bytes, 4);
-
- return svcxdr_seek(&xdr->ptr, bytes);
+ if (bytes > xdr->maxbytes)
+ return false;
+ if (!svcxdr_seek(&xdr->ptr, bytes))
+ return false;
+ xdr->maxbytes -= bytes;
+ return true;
}
/* XXX: basic idea here:
@@ -1827,6 +1833,7 @@ static int svcxdr_byte_offset(struct svcxdr_ptr *from, struct svcxdr_ptr *to)
static void svcxdr_reset(struct svcxdr_stream *xdr, struct svcxdr_ptr *to)
{
WARN_ON_ONCE(svcxdr_ptr_misordered(&xdr->last_commit, to));
+ xdr->maxbytes += svcxdr_byte_offset(to, &xdr->ptr);
xdr->ptr = *to;
}
@@ -54,6 +54,7 @@ struct svcxdr_stream {
struct svcxdr_ptr ptr;
struct xdr_buf *buf;
struct kvec *this_iov;
+ int maxbytes;
};
#define CURRENT_STATE_ID_FLAG (1<<0)