NFSD: Refactor the generic write vector fill helper

fill_in_write_vector() is nearly the same logic as
svc_fill_write_vector(), but there are a few differences so that
the former can handle multiple WRITE payloads in a single COMPOUND.

svc_fill_write_vector() can be adjusted so that it can be used in
the NFSv4 WRITE code path too. Instead of assuming the pages are
coming from rq_args.pages, have the caller pass in the page list.

The immediate benefit is a reduction of code duplication. It also
prevents the NFSv4 WRITE decoder from passing an empty vector
element when the transport has provided the payload in the xdr_buf's
page array.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
Chuck Lever 2018-07-27 11:19:05 -04:00 committed by J. Bruce Fields
parent 07d0ff3b0c
commit 3fd9557aec
5 changed files with 13 additions and 28 deletions

View file

@ -1537,16 +1537,16 @@ EXPORT_SYMBOL_GPL(svc_max_payload);
/**
* svc_fill_write_vector - Construct data argument for VFS write call
* @rqstp: svc_rqst to operate on
* @pages: list of pages containing data payload
* @first: buffer containing first section of write payload
* @total: total number of bytes of write payload
*
* Returns the number of elements populated in the data argument array.
* Fills in rqstp::rq_vec, and returns the number of elements.
*/
unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct kvec *first,
size_t total)
unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct page **pages,
struct kvec *first, size_t total)
{
struct kvec *vec = rqstp->rq_vec;
struct page **pages;
unsigned int i;
/* Some types of transport can present the write payload
@ -1560,14 +1560,11 @@ unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct kvec *first,
++i;
}
WARN_ON_ONCE(rqstp->rq_arg.page_base != 0);
pages = rqstp->rq_arg.pages;
while (total) {
vec[i].iov_base = page_address(*pages);
vec[i].iov_len = min_t(size_t, total, PAGE_SIZE);
total -= vec[i].iov_len;
++i;
++pages;
}