[PATCH 3/3] nfsd: use rq_bvec in nfsd_iter_read

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Using a bvec array vs a kvec one slightly simplifies the logic, and allow
to remove the rq_vecs array.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>
---
 fs/nfsd/vfs.c              | 27 ++++++++++++++++-----------
 include/linux/sunrpc/svc.h |  1 -
 2 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 0cc9639fba79..1804aed0739b 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1078,26 +1078,31 @@ __be32 nfsd_iter_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
 		      struct file *file, loff_t offset, unsigned long *count,
 		      unsigned int base, u32 *eof)
 {
-	unsigned long v, total;
+	unsigned long total = *count;
 	struct iov_iter iter;
 	loff_t ppos = offset;
-	struct page *page;
+	unsigned int v = 0;
 	ssize_t host_err;
 
-	v = 0;
-	total = *count;
+	/*
+	 * Note: if this request is served through the socket transport, rq_bvec
+	 * will be rebuilt again in the transport, including the XDR header and
+	 * trailer.  It would be nice to fully build it in one place, but that
+	 * needs more work.
+	 */
 	while (total) {
-		page = *(rqstp->rq_next_page++);
-		rqstp->rq_vec[v].iov_base = page_address(page) + base;
-		rqstp->rq_vec[v].iov_len = min_t(size_t, total, PAGE_SIZE - base);
-		total -= rqstp->rq_vec[v].iov_len;
-		++v;
+		unsigned int len = min(total, PAGE_SIZE - base);
+		struct page *page = *(rqstp->rq_next_page++);
+
+		bvec_set_page(&rqstp->rq_bvec[v++], page, len, base);
+		if (WARN_ON_ONCE(v > ARRAY_SIZE(rqstp->rq_bvec)))
+			return -EIO;
+		total -= len;
 		base = 0;
 	}
-	WARN_ON_ONCE(v > ARRAY_SIZE(rqstp->rq_vec));
 
 	trace_nfsd_read_vector(rqstp, fhp, offset, *count);
-	iov_iter_kvec(&iter, ITER_DEST, rqstp->rq_vec, v, *count);
+	iov_iter_bvec(&iter, ITER_DEST, rqstp->rq_bvec, v, *count);
 	host_err = vfs_iter_read(file, &iter, &ppos, 0);
 	return nfsd_finish_read(rqstp, fhp, file, offset, count, eof, host_err);
 }
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index c25456738315..a040583a29da 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -194,7 +194,6 @@ struct svc_rqst {
 	struct page *		*rq_page_end;  /* one past the last page */
 
 	struct folio_batch	rq_fbatch;
-	struct kvec		rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */
 	struct bio_vec		rq_bvec[RPCSVC_MAXPAGES];
 
 	__be32			rq_xid;		/* transmission id */
-- 
2.47.2





[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux