Commit 7bb0dfb2 authored by Chuck Lever's avatar Chuck Lever
Browse files

SUNRPC: Convert unwrap data paths to use xdr_stream for replies



We're now moving svcxdr_init_encode() to /before/ the flavor's
->accept method has set rq_auth_slack. Add a helper that can
set rq_auth_slack /after/ svcxdr_init_encode() has been called.

Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent df18f9cc
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -577,12 +577,34 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp)
	xdr->buf = buf;
	xdr->iov = resv;
	xdr->p   = resv->iov_base + resv->iov_len;
	xdr->end = resv->iov_base + PAGE_SIZE - rqstp->rq_auth_slack;
	xdr->end = resv->iov_base + PAGE_SIZE;
	buf->len = resv->iov_len;
	xdr->page_ptr = buf->pages - 1;
	buf->buflen = PAGE_SIZE * (rqstp->rq_page_end - buf->pages);
	buf->buflen -= rqstp->rq_auth_slack;
	xdr->rqst = NULL;
}

/**
 * svcxdr_set_auth_slack -
 * @rqstp: RPC transaction
 * @slack: buffer space to reserve for the transaction's security flavor
 *
 * Set the request's slack space requirement, and set aside that much
 * space in the rqstp's rq_res.head for use when the auth wraps the Reply.
 */
static inline void svcxdr_set_auth_slack(struct svc_rqst *rqstp, int slack)
{
	struct xdr_stream *xdr = &rqstp->rq_res_stream;
	struct xdr_buf *buf = &rqstp->rq_res;
	struct kvec *resv = buf->head;

	rqstp->rq_auth_slack = slack;

	xdr->end -= XDR_QUADLEN(slack);
	buf->buflen -= rqstp->rq_auth_slack;

	WARN_ON(xdr->iov != resv);
	WARN_ON(xdr->p > xdr->end);
}

#endif /* SUNRPC_SVC_H */
+8 −10
Original line number Diff line number Diff line
@@ -1685,24 +1685,22 @@ svcauth_gss_accept(struct svc_rqst *rqstp)
			svcxdr_init_encode(rqstp);
			break;
		case RPC_GSS_SVC_INTEGRITY:
			/* placeholders for length and seq. number: */
			svc_putnl(resv, 0);
			svc_putnl(resv, 0);
			svcxdr_init_encode(rqstp);
			/* placeholders for body length and seq. number: */
			xdr_reserve_space(&rqstp->rq_res_stream, XDR_UNIT * 2);
			if (svcauth_gss_unwrap_integ(rqstp, gc->gc_seq,
						     rsci->mechctx))
				goto garbage_args;
			rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE;
			svcxdr_init_encode(rqstp);
			svcxdr_set_auth_slack(rqstp, RPC_MAX_AUTH_SIZE);
			break;
		case RPC_GSS_SVC_PRIVACY:
			/* placeholders for length and seq. number: */
			svc_putnl(resv, 0);
			svc_putnl(resv, 0);
			svcxdr_init_encode(rqstp);
			/* placeholders for body length and seq. number: */
			xdr_reserve_space(&rqstp->rq_res_stream, XDR_UNIT * 2);
			if (svcauth_gss_unwrap_priv(rqstp, gc->gc_seq,
						    rsci->mechctx))
				goto garbage_args;
			rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE * 2;
			svcxdr_init_encode(rqstp);
			svcxdr_set_auth_slack(rqstp, RPC_MAX_AUTH_SIZE * 2);
			break;
		default:
			goto auth_err;