There is no benefit in using a kvec vs a bvec for in-kernel writes, but phasing out the kvec here will allow us to eventually remove that array. Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- fs/nfsd/vfs.c | 10 +++++++--- include/linux/sunrpc/svc.h | 2 -- net/sunrpc/svc.c | 40 -------------------------------------- 3 files changed, 7 insertions(+), 45 deletions(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index da62082d06dc..0cc9639fba79 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1161,8 +1161,12 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, trace_nfsd_write_opened(rqstp, fhp, offset, *cnt); - nvecs = svc_fill_write_vector(rqstp, payload); - if (WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec))) + if (WARN_ON_ONCE(payload->tail->iov_len)) + return -EIO; + + nvecs = xdr_buf_to_bvec(rqstp->rq_bvec, ARRAY_SIZE(rqstp->rq_bvec), + payload); + if (WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_bvec))) return -EIO; if (sb->s_export_op) @@ -1189,7 +1193,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, if (stable && !fhp->fh_use_wgather) flags |= RWF_SYNC; - iov_iter_kvec(&iter, ITER_SOURCE, rqstp->rq_vec, nvecs, *cnt); + iov_iter_bvec(&iter, ITER_SOURCE, rqstp->rq_bvec, nvecs, *cnt); since = READ_ONCE(file->f_wb_err); if (verf) nfsd_copy_write_verifier(verf, nn); diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 74658cca0f38..c25456738315 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -452,8 +452,6 @@ const char * svc_proc_name(const struct svc_rqst *rqstp); int svc_encode_result_payload(struct svc_rqst *rqstp, unsigned int offset, unsigned int length); -unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, - struct xdr_buf *payload); char *svc_fill_symlink_pathname(struct svc_rqst *rqstp, struct kvec *first, void *p, size_t total); diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index e7f9c295d13c..9fd370d6676c 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -1713,46 +1713,6 @@ int svc_encode_result_payload(struct svc_rqst *rqstp, unsigned int offset, } EXPORT_SYMBOL_GPL(svc_encode_result_payload); -/** - * svc_fill_write_vector - Construct data argument for VFS write call - * @rqstp: svc_rqst to operate on - * @payload: xdr_buf containing only the write data payload - * - * Fills in rqstp::rq_vec, and returns the number of elements. - */ -unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, - struct xdr_buf *payload) -{ - struct page **pages = payload->pages; - struct kvec *first = payload->head; - struct kvec *vec = rqstp->rq_vec; - size_t total = payload->len; - unsigned int i; - - /* Some types of transport can present the write payload - * entirely in rq_arg.pages. In this case, @first is empty. - */ - i = 0; - if (first->iov_len) { - vec[i].iov_base = first->iov_base; - vec[i].iov_len = min_t(size_t, total, first->iov_len); - total -= vec[i].iov_len; - ++i; - } - - 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; - } - - WARN_ON_ONCE(i > ARRAY_SIZE(rqstp->rq_vec)); - return i; -} -EXPORT_SYMBOL_GPL(svc_fill_write_vector); - /** * svc_fill_symlink_pathname - Construct pathname argument for VFS symlink call * @rqstp: svc_rqst to operate on -- 2.47.2