Skip to content

Commit bfbfb61

Browse files
author
Al Viro
committed
nfsd_splice_actor(): handle compound pages
pipe_buffer might refer to a compound page (and contain more than a PAGE_SIZE worth of data). Theoretically it had been possible since way back, but nfsd_splice_actor() hadn't run into that until copy_page_to_iter() change. Fortunately, the only thing that changes for compound pages is that we need to stuff each relevant subpage in and convert the offset into offset in the first subpage. Acked-by: Chuck Lever <[email protected]> Tested-by: Benjamin Coddington <[email protected]> Fixes: f0f6b61 "copy_page_to_iter(): don't split high-order page in case of ITER_PIPE" Signed-off-by: Al Viro <[email protected]>
1 parent 568035b commit bfbfb61

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

fs/nfsd/vfs.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -846,10 +846,14 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
846846
struct splice_desc *sd)
847847
{
848848
struct svc_rqst *rqstp = sd->u.data;
849-
850-
svc_rqst_replace_page(rqstp, buf->page);
851-
if (rqstp->rq_res.page_len == 0)
852-
rqstp->rq_res.page_base = buf->offset;
849+
struct page *page = buf->page; // may be a compound one
850+
unsigned offset = buf->offset;
851+
852+
page += offset / PAGE_SIZE;
853+
for (int i = sd->len; i > 0; i -= PAGE_SIZE)
854+
svc_rqst_replace_page(rqstp, page++);
855+
if (rqstp->rq_res.page_len == 0) // first call
856+
rqstp->rq_res.page_base = offset % PAGE_SIZE;
853857
rqstp->rq_res.page_len += sd->len;
854858
return sd->len;
855859
}

0 commit comments

Comments
 (0)