Skip to content

Commit 3fd9557

Browse files
chuckleverJ. Bruce Fields
authored andcommitted
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>
1 parent 07d0ff3 commit 3fd9557

File tree

5 files changed

+13
-28
lines changed

5 files changed

+13
-28
lines changed

fs/nfsd/nfs3proc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
202202

203203
fh_copy(&resp->fh, &argp->fh);
204204
resp->committed = argp->stable;
205-
nvecs = svc_fill_write_vector(rqstp, &argp->first, cnt);
205+
nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages,
206+
&argp->first, cnt);
206207
if (!nvecs)
207208
RETURN_STATUS(nfserr_io);
208209
nfserr = nfsd_write(rqstp, &resp->fh, argp->offset,

fs/nfsd/nfs4proc.c

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -986,24 +986,6 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
986986
return status;
987987
}
988988

989-
static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write)
990-
{
991-
int i = 1;
992-
int buflen = write->wr_buflen;
993-
994-
vec[0].iov_base = write->wr_head.iov_base;
995-
vec[0].iov_len = min_t(int, buflen, write->wr_head.iov_len);
996-
buflen -= vec[0].iov_len;
997-
998-
while (buflen) {
999-
vec[i].iov_base = page_address(write->wr_pagelist[i - 1]);
1000-
vec[i].iov_len = min_t(int, PAGE_SIZE, buflen);
1001-
buflen -= vec[i].iov_len;
1002-
i++;
1003-
}
1004-
return i;
1005-
}
1006-
1007989
static __be32
1008990
nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1009991
union nfsd4_op_u *u)
@@ -1031,7 +1013,10 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
10311013
write->wr_how_written = write->wr_stable_how;
10321014
gen_boot_verifier(&write->wr_verifier, SVC_NET(rqstp));
10331015

1034-
nvecs = fill_in_write_vector(rqstp->rq_vec, write);
1016+
nvecs = svc_fill_write_vector(rqstp, write->wr_pagelist,
1017+
&write->wr_head, write->wr_buflen);
1018+
if (!nvecs)
1019+
return nfserr_io;
10351020
WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
10361021

10371022
status = nfsd_vfs_write(rqstp, &cstate->current_fh, filp,

fs/nfsd/nfsproc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@ nfsd_proc_write(struct svc_rqst *rqstp)
218218
SVCFH_fmt(&argp->fh),
219219
argp->len, argp->offset);
220220

221-
nvecs = svc_fill_write_vector(rqstp, &argp->first, cnt);
221+
nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages,
222+
&argp->first, cnt);
222223
if (!nvecs)
223224
return nfserr_io;
224225
nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh),

include/linux/sunrpc/svc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ void svc_reserve(struct svc_rqst *rqstp, int space);
496496
struct svc_pool * svc_pool_for_cpu(struct svc_serv *serv, int cpu);
497497
char * svc_print_addr(struct svc_rqst *, char *, size_t);
498498
unsigned int svc_fill_write_vector(struct svc_rqst *rqstp,
499+
struct page **pages,
499500
struct kvec *first, size_t total);
500501
char *svc_fill_symlink_pathname(struct svc_rqst *rqstp,
501502
struct kvec *first, size_t total);

net/sunrpc/svc.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,16 +1537,16 @@ EXPORT_SYMBOL_GPL(svc_max_payload);
15371537
/**
15381538
* svc_fill_write_vector - Construct data argument for VFS write call
15391539
* @rqstp: svc_rqst to operate on
1540+
* @pages: list of pages containing data payload
15401541
* @first: buffer containing first section of write payload
15411542
* @total: total number of bytes of write payload
15421543
*
1543-
* Returns the number of elements populated in the data argument array.
1544+
* Fills in rqstp::rq_vec, and returns the number of elements.
15441545
*/
1545-
unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct kvec *first,
1546-
size_t total)
1546+
unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct page **pages,
1547+
struct kvec *first, size_t total)
15471548
{
15481549
struct kvec *vec = rqstp->rq_vec;
1549-
struct page **pages;
15501550
unsigned int i;
15511551

15521552
/* 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,
15601560
++i;
15611561
}
15621562

1563-
WARN_ON_ONCE(rqstp->rq_arg.page_base != 0);
1564-
pages = rqstp->rq_arg.pages;
15651563
while (total) {
15661564
vec[i].iov_base = page_address(*pages);
15671565
vec[i].iov_len = min_t(size_t, total, PAGE_SIZE);
15681566
total -= vec[i].iov_len;
15691567
++i;
1570-
15711568
++pages;
15721569
}
15731570

0 commit comments

Comments
 (0)