@@ -309,17 +309,6 @@ static inline struct sockaddr *svc_daddr(const struct svc_rqst *rqst)
return (struct sockaddr *) &rqst->rq_daddr;
}
-static inline void svc_free_res_pages(struct svc_rqst *rqstp)
-{
- while (rqstp->rq_next_page != rqstp->rq_respages) {
- struct page **pp = --rqstp->rq_next_page;
- if (*pp) {
- put_page(*pp);
- *pp = NULL;
- }
- }
-}
-
struct svc_deferred_req {
u32 prot; /* protocol (UDP or TCP) */
struct svc_xprt *xprt;
@@ -424,6 +413,7 @@ struct svc_rqst *svc_rqst_alloc(struct svc_serv *serv,
struct svc_pool *pool, int node);
bool svc_rqst_replace_page(struct svc_rqst *rqstp,
struct page *page);
+void svc_rqst_release_pages(struct svc_rqst *rqstp);
void svc_rqst_free(struct svc_rqst *);
void svc_exit_thread(struct svc_rqst *);
struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
@@ -869,6 +869,25 @@ bool svc_rqst_replace_page(struct svc_rqst *rqstp, struct page *page)
}
EXPORT_SYMBOL_GPL(svc_rqst_replace_page);
+/**
+ * svc_rqst_release_pages - Release Reply buffer pages
+ * @rqstp: RPC transaction context
+ *
+ * Release response pages that might still be in flight after
+ * svc_send, and any spliced filesystem-owned pages.
+ */
+void svc_rqst_release_pages(struct svc_rqst *rqstp)
+{
+ while (rqstp->rq_next_page != rqstp->rq_respages) {
+ struct page **pp = --rqstp->rq_next_page;
+
+ if (*pp) {
+ put_page(*pp);
+ *pp = NULL;
+ }
+ }
+}
+
/*
* Called from a server thread as it's exiting. Caller must hold the "service
* mutex" for the service.
@@ -542,7 +542,7 @@ static void svc_xprt_release(struct svc_rqst *rqstp)
rqstp->rq_deferred = NULL;
pagevec_release(&rqstp->rq_pvec);
- svc_free_res_pages(rqstp);
+ svc_rqst_release_pages(rqstp);
rqstp->rq_res.page_len = 0;
rqstp->rq_res.page_base = 0;