Commit 82078b98 authored by Chuck Lever's avatar Chuck Lever
Browse files

NFSD: Ensure that xdr_write_pages updates rq_next_page



All other NFSv[23] procedures manage to keep page_ptr and
rq_next_page in lock step.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 66a21db7
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -828,7 +828,8 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
			return false;
		if (xdr_stream_encode_u32(xdr, resp->len) < 0)
			return false;
		xdr_write_pages(xdr, resp->pages, 0, resp->len);
		svcxdr_encode_opaque_pages(rqstp, xdr, resp->pages, 0,
					   resp->len);
		if (svc_encode_result_payload(rqstp, head->iov_len, resp->len) < 0)
			return false;
		break;
@@ -859,7 +860,8 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
			return false;
		if (xdr_stream_encode_u32(xdr, resp->count) < 0)
			return false;
		xdr_write_pages(xdr, resp->pages, rqstp->rq_res.page_base,
		svcxdr_encode_opaque_pages(rqstp, xdr, resp->pages,
					   rqstp->rq_res.page_base,
					   resp->count);
		if (svc_encode_result_payload(rqstp, head->iov_len, resp->count) < 0)
			return false;
@@ -961,7 +963,8 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
			return false;
		if (!svcxdr_encode_cookieverf3(xdr, resp->verf))
			return false;
		xdr_write_pages(xdr, dirlist->pages, 0, dirlist->len);
		svcxdr_encode_opaque_pages(rqstp, xdr, dirlist->pages, 0,
					   dirlist->len);
		/* no more entries */
		if (xdr_stream_encode_item_absent(xdr) < 0)
			return false;
+7 −4
Original line number Diff line number Diff line
@@ -468,7 +468,8 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
	case nfs_ok:
		if (xdr_stream_encode_u32(xdr, resp->len) < 0)
			return false;
		xdr_write_pages(xdr, &resp->page, 0, resp->len);
		svcxdr_encode_opaque_pages(rqstp, xdr, &resp->page, 0,
					   resp->len);
		if (svc_encode_result_payload(rqstp, head->iov_len, resp->len) < 0)
			return false;
		break;
@@ -491,7 +492,8 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
			return false;
		if (xdr_stream_encode_u32(xdr, resp->count) < 0)
			return false;
		xdr_write_pages(xdr, resp->pages, rqstp->rq_res.page_base,
		svcxdr_encode_opaque_pages(rqstp, xdr, resp->pages,
					   rqstp->rq_res.page_base,
					   resp->count);
		if (svc_encode_result_payload(rqstp, head->iov_len, resp->count) < 0)
			return false;
@@ -511,7 +513,8 @@ nfssvc_encode_readdirres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
		return false;
	switch (resp->status) {
	case nfs_ok:
		xdr_write_pages(xdr, dirlist->pages, 0, dirlist->len);
		svcxdr_encode_opaque_pages(rqstp, xdr, dirlist->pages, 0,
					   dirlist->len);
		/* no more entries */
		if (xdr_stream_encode_item_absent(xdr) < 0)
			return false;
+21 −0
Original line number Diff line number Diff line
@@ -508,6 +508,27 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp)
	xdr->rqst = NULL;
}

/**
 * svcxdr_encode_opaque_pages - Insert pages into an xdr_stream
 * @xdr: xdr_stream to be updated
 * @pages: array of pages to insert
 * @base: starting offset of first data byte in @pages
 * @len: number of data bytes in @pages to insert
 *
 * After the @pages are added, the tail iovec is instantiated pointing
 * to end of the head buffer, and the stream is set up to encode
 * subsequent items into the tail.
 */
static inline void svcxdr_encode_opaque_pages(struct svc_rqst *rqstp,
					      struct xdr_stream *xdr,
					      struct page **pages,
					      unsigned int base,
					      unsigned int len)
{
	xdr_write_pages(xdr, pages, base, len);
	xdr->page_ptr = rqstp->rq_next_page - 1;
}

/**
 * svcxdr_set_auth_slack -
 * @rqstp: RPC transaction