Skip to content

Commit e8680a2

Browse files
chuckleveramschuma-ntap
authored andcommitted
SUNRPC: Use struct xdr_stream when constructing RPC Call header
Modernize and harden the code path that constructs each RPC Call message. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent fe9a270 commit e8680a2

File tree

8 files changed

+266
-181
lines changed

8 files changed

+266
-181
lines changed

include/linux/sunrpc/auth.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,12 @@ struct rpc_credops {
131131
void (*crdestroy)(struct rpc_cred *);
132132

133133
int (*crmatch)(struct auth_cred *, struct rpc_cred *, int);
134-
__be32 * (*crmarshal)(struct rpc_task *, __be32 *);
134+
int (*crmarshal)(struct rpc_task *task,
135+
struct xdr_stream *xdr);
135136
int (*crrefresh)(struct rpc_task *);
136137
__be32 * (*crvalidate)(struct rpc_task *, __be32 *);
137-
int (*crwrap_req)(struct rpc_task *, kxdreproc_t,
138-
void *, __be32 *, void *);
138+
int (*crwrap_req)(struct rpc_task *task,
139+
struct xdr_stream *xdr);
139140
int (*crunwrap_resp)(struct rpc_task *, kxdrdproc_t,
140141
void *, __be32 *, void *);
141142
int (*crkey_timeout)(struct rpc_cred *);
@@ -165,9 +166,13 @@ struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *
165166
void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
166167
struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int);
167168
void put_rpccred(struct rpc_cred *);
168-
__be32 * rpcauth_marshcred(struct rpc_task *, __be32 *);
169+
int rpcauth_marshcred(struct rpc_task *task,
170+
struct xdr_stream *xdr);
169171
__be32 * rpcauth_checkverf(struct rpc_task *, __be32 *);
170-
int rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp, __be32 *data, void *obj);
172+
int rpcauth_wrap_req_encode(struct rpc_task *task,
173+
struct xdr_stream *xdr);
174+
int rpcauth_wrap_req(struct rpc_task *task,
175+
struct xdr_stream *xdr);
171176
int rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp, __be32 *data, void *obj);
172177
bool rpcauth_xmit_need_reencode(struct rpc_task *task);
173178
int rpcauth_refreshcred(struct rpc_task *);

include/linux/sunrpc/xdr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ xdr_buf_init(struct xdr_buf *buf, void *start, size_t len)
8787
#define xdr_one cpu_to_be32(1)
8888
#define xdr_two cpu_to_be32(2)
8989

90+
#define rpc_auth_null cpu_to_be32(RPC_AUTH_NULL)
91+
#define rpc_auth_unix cpu_to_be32(RPC_AUTH_UNIX)
92+
#define rpc_auth_gss cpu_to_be32(RPC_AUTH_GSS)
93+
94+
#define rpc_call cpu_to_be32(RPC_CALL)
95+
9096
#define rpc_success cpu_to_be32(RPC_SUCCESS)
9197
#define rpc_prog_unavail cpu_to_be32(RPC_PROG_UNAVAIL)
9298
#define rpc_prog_mismatch cpu_to_be32(RPC_PROG_MISMATCH)

include/trace/events/sunrpc.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,35 @@ DECLARE_EVENT_CLASS(rpc_task_queued,
213213
DEFINE_RPC_QUEUED_EVENT(sleep);
214214
DEFINE_RPC_QUEUED_EVENT(wakeup);
215215

216+
DECLARE_EVENT_CLASS(rpc_failure,
217+
218+
TP_PROTO(const struct rpc_task *task),
219+
220+
TP_ARGS(task),
221+
222+
TP_STRUCT__entry(
223+
__field(unsigned int, task_id)
224+
__field(unsigned int, client_id)
225+
),
226+
227+
TP_fast_assign(
228+
__entry->task_id = task->tk_pid;
229+
__entry->client_id = task->tk_client->cl_clid;
230+
),
231+
232+
TP_printk("task:%u@%u",
233+
__entry->task_id, __entry->client_id)
234+
);
235+
236+
#define DEFINE_RPC_FAILURE(name) \
237+
DEFINE_EVENT(rpc_failure, rpc_bad_##name, \
238+
TP_PROTO( \
239+
const struct rpc_task *task \
240+
), \
241+
TP_ARGS(task))
242+
243+
DEFINE_RPC_FAILURE(callhdr);
244+
216245
TRACE_EVENT(rpc_stats_latency,
217246

218247
TP_PROTO(

net/sunrpc/auth.c

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -756,12 +756,21 @@ put_rpccred(struct rpc_cred *cred)
756756
}
757757
EXPORT_SYMBOL_GPL(put_rpccred);
758758

759-
__be32 *
760-
rpcauth_marshcred(struct rpc_task *task, __be32 *p)
759+
/**
760+
* rpcauth_marshcred - Append RPC credential to end of @xdr
761+
* @task: controlling RPC task
762+
* @xdr: xdr_stream containing initial portion of RPC Call header
763+
*
764+
* On success, an appropriate verifier is added to @xdr, @xdr is
765+
* updated to point past the verifier, and zero is returned.
766+
* Otherwise, @xdr is in an undefined state and a negative errno
767+
* is returned.
768+
*/
769+
int rpcauth_marshcred(struct rpc_task *task, struct xdr_stream *xdr)
761770
{
762-
struct rpc_cred *cred = task->tk_rqstp->rq_cred;
771+
const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops;
763772

764-
return cred->cr_ops->crmarshal(task, p);
773+
return ops->crmarshal(task, xdr);
765774
}
766775

767776
__be32 *
@@ -772,26 +781,37 @@ rpcauth_checkverf(struct rpc_task *task, __be32 *p)
772781
return cred->cr_ops->crvalidate(task, p);
773782
}
774783

775-
static void rpcauth_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
776-
__be32 *data, void *obj)
784+
/**
785+
* rpcauth_wrap_req_encode - XDR encode the RPC procedure
786+
* @task: controlling RPC task
787+
* @xdr: stream where on-the-wire bytes are to be marshalled
788+
*
789+
* On success, @xdr contains the encoded and wrapped message.
790+
* Otherwise, @xdr is in an undefined state.
791+
*/
792+
int rpcauth_wrap_req_encode(struct rpc_task *task, struct xdr_stream *xdr)
777793
{
778-
struct xdr_stream xdr;
794+
kxdreproc_t encode = task->tk_msg.rpc_proc->p_encode;
779795

780-
xdr_init_encode(&xdr, &rqstp->rq_snd_buf, data, rqstp);
781-
encode(rqstp, &xdr, obj);
796+
encode(task->tk_rqstp, xdr, task->tk_msg.rpc_argp);
797+
return 0;
782798
}
799+
EXPORT_SYMBOL_GPL(rpcauth_wrap_req_encode);
783800

784-
int
785-
rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp,
786-
__be32 *data, void *obj)
801+
/**
802+
* rpcauth_wrap_req - XDR encode and wrap the RPC procedure
803+
* @task: controlling RPC task
804+
* @xdr: stream where on-the-wire bytes are to be marshalled
805+
*
806+
* On success, @xdr contains the encoded and wrapped message,
807+
* and zero is returned. Otherwise, @xdr is in an undefined
808+
* state and a negative errno is returned.
809+
*/
810+
int rpcauth_wrap_req(struct rpc_task *task, struct xdr_stream *xdr)
787811
{
788-
struct rpc_cred *cred = task->tk_rqstp->rq_cred;
812+
const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops;
789813

790-
if (cred->cr_ops->crwrap_req)
791-
return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj);
792-
/* By default, we encode the arguments normally. */
793-
rpcauth_wrap_req_encode(encode, rqstp, data, obj);
794-
return 0;
814+
return ops->crwrap_req(task, xdr);
795815
}
796816

797817
static int

0 commit comments

Comments
 (0)