diff options
| -rw-r--r-- | include/linux/sunrpc/svc.h | 4 | ||||
| -rw-r--r-- | net/sunrpc/svc.c | 1 | ||||
| -rw-r--r-- | net/sunrpc/svc_xprt.c | 8 |
3 files changed, 12 insertions, 1 deletions
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index c3399cf64524..669c944eaf7f 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -152,6 +152,10 @@ extern u32 svc_max_payload(const struct svc_rqst *rqstp); * still in transport use, and set rq_pages_nfree to the count. * svc_alloc_arg() refills only that many rq_pages entries. * + * For rq_respages, svc_rqst_release_pages() NULLs entries in + * [rq_respages, rq_next_page) after each RPC. svc_alloc_arg() + * refills only that range. + * * xdr_buf holds responses; the structure fits NFS read responses * (header, data pages, optional tail) and enables sharing of * client-side routines. diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 6e57e35fa6d6..5e0b5ec2fd52 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -656,6 +656,7 @@ svc_init_buffer(struct svc_rqst *rqstp, const struct svc_serv *serv, int node) } rqstp->rq_pages_nfree = rqstp->rq_maxpages; + rqstp->rq_next_page = rqstp->rq_respages + rqstp->rq_maxpages; return true; } diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 795b5729525f..b16e710926c1 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -686,8 +686,14 @@ static bool svc_alloc_arg(struct svc_rqst *rqstp) rqstp->rq_pages_nfree = 0; } - if (!svc_fill_pages(rqstp, rqstp->rq_respages, pages)) + if (WARN_ON_ONCE(rqstp->rq_next_page < rqstp->rq_respages)) return false; + nfree = rqstp->rq_next_page - rqstp->rq_respages; + if (nfree) { + if (!svc_fill_pages(rqstp, rqstp->rq_respages, nfree)) + return false; + } + rqstp->rq_next_page = rqstp->rq_respages; rqstp->rq_page_end = &rqstp->rq_respages[pages]; /* svc_rqst_replace_page() dereferences *rq_next_page even |
