summaryrefslogtreecommitdiffstats
path: root/fs/nfsd/vfs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-09-13 15:11:38 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2022-09-13 15:11:38 +0200
commitd1221cea11fca0f6946bdd032a45b22cecfc0f99 (patch)
tree0e0cd9c571295be76aded7c3429ad6fc4327786c /fs/nfsd/vfs.c
parente839a756012b6cad7a4eeb67b0598ac3f349f863 (diff)
parentbfbfb6182ad1d7d184b16f25165faad879147f79 (diff)
downloadlinux-d1221cea11fca0f6946bdd032a45b22cecfc0f99.tar.bz2
Merge tag 'pull-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull iov_iter fix from Al Viro: "Fix for a nfsd regression caused by the iov_iter stuff this window" * tag 'pull-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: nfsd_splice_actor(): handle compound pages
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r--fs/nfsd/vfs.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 19f28c33e44d..fc17b0ac8729 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -845,10 +845,14 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
struct splice_desc *sd)
{
struct svc_rqst *rqstp = sd->u.data;
-
- svc_rqst_replace_page(rqstp, buf->page);
- if (rqstp->rq_res.page_len == 0)
- rqstp->rq_res.page_base = buf->offset;
+ struct page *page = buf->page; // may be a compound one
+ unsigned offset = buf->offset;
+
+ page += offset / PAGE_SIZE;
+ for (int i = sd->len; i > 0; i -= PAGE_SIZE)
+ svc_rqst_replace_page(rqstp, page++);
+ if (rqstp->rq_res.page_len == 0) // first call
+ rqstp->rq_res.page_base = offset % PAGE_SIZE;
rqstp->rq_res.page_len += sd->len;
return sd->len;
}