Skip to content

Commit 5191955

Browse files
committed
SUNRPC: Prepare for xdr_stream-style decoding on the server-side
A "permanent" struct xdr_stream is allocated in struct svc_rqst so that it is usable by all server-side decoders. A per-rqst scratch buffer is also allocated to handle decoding XDR data items that cross page boundaries. To demonstrate how it will be used, add the first call site for the new svcxdr_init_decode() API. As an additional part of the overall conversion, add symbolic constants for successful and failed XDR operations. Returning "0" is overloaded. Sometimes it means something failed, but sometimes it means success. To make it more clear when XDR decoding functions succeed or fail, introduce symbolic constants. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 0ae4c3e commit 5191955

File tree

3 files changed

+23
-0
lines changed

3 files changed

+23
-0
lines changed

fs/nfsd/nfssvc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,8 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
10201020
* (necessary in the NFSv4.0 compound case)
10211021
*/
10221022
rqstp->rq_cachetype = proc->pc_cachetype;
1023+
1024+
svcxdr_init_decode(rqstp);
10231025
if (!proc->pc_decode(rqstp, argv->iov_base))
10241026
goto out_decode_err;
10251027

include/linux/sunrpc/svc.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ struct svc_rqst {
247247

248248
size_t rq_xprt_hlen; /* xprt header len */
249249
struct xdr_buf rq_arg;
250+
struct xdr_stream rq_arg_stream;
251+
struct page *rq_scratch_page;
250252
struct xdr_buf rq_res;
251253
struct page *rq_pages[RPCSVC_MAXPAGES + 1];
252254
struct page * *rq_respages; /* points into rq_pages */
@@ -557,4 +559,18 @@ static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
557559
svc_reserve(rqstp, space + rqstp->rq_auth_slack);
558560
}
559561

562+
/**
563+
* svcxdr_init_decode - Prepare an xdr_stream for svc Call decoding
564+
* @rqstp: controlling server RPC transaction context
565+
*
566+
*/
567+
static inline void svcxdr_init_decode(struct svc_rqst *rqstp)
568+
{
569+
struct xdr_stream *xdr = &rqstp->rq_arg_stream;
570+
struct kvec *argv = rqstp->rq_arg.head;
571+
572+
xdr_init_decode(xdr, &rqstp->rq_arg, argv->iov_base, NULL);
573+
xdr_set_scratch_page(xdr, rqstp->rq_scratch_page);
574+
}
575+
560576
#endif /* SUNRPC_SVC_H */

net/sunrpc/svc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,10 @@ svc_rqst_alloc(struct svc_serv *serv, struct svc_pool *pool, int node)
614614
rqstp->rq_server = serv;
615615
rqstp->rq_pool = pool;
616616

617+
rqstp->rq_scratch_page = alloc_pages_node(node, GFP_KERNEL, 0);
618+
if (!rqstp->rq_scratch_page)
619+
goto out_enomem;
620+
617621
rqstp->rq_argp = kmalloc_node(serv->sv_xdrsize, GFP_KERNEL, node);
618622
if (!rqstp->rq_argp)
619623
goto out_enomem;
@@ -842,6 +846,7 @@ void
842846
svc_rqst_free(struct svc_rqst *rqstp)
843847
{
844848
svc_release_buffer(rqstp);
849+
put_page(rqstp->rq_scratch_page);
845850
kfree(rqstp->rq_resp);
846851
kfree(rqstp->rq_argp);
847852
kfree(rqstp->rq_auth_data);

0 commit comments

Comments
 (0)