Skip to content

Commit bbdfc2f

Browse files
Jens Axboedavem330
authored andcommitted
[SPLICE]: Don't assume regular pages in splice_to_pipe()
Allow caller to pass in a release function, there might be other resources that need releasing as well. Needed for network receive. Signed-off-by: Jens Axboe <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d10f215 commit bbdfc2f

File tree

2 files changed

+9
-1
lines changed

2 files changed

+9
-1
lines changed

fs/splice.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,16 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
254254
}
255255

256256
while (page_nr < spd_pages)
257-
page_cache_release(spd->pages[page_nr++]);
257+
spd->spd_release(spd, page_nr++);
258258

259259
return ret;
260260
}
261261

262+
static void spd_release_page(struct splice_pipe_desc *spd, unsigned int i)
263+
{
264+
page_cache_release(spd->pages[i]);
265+
}
266+
262267
static int
263268
__generic_file_splice_read(struct file *in, loff_t *ppos,
264269
struct pipe_inode_info *pipe, size_t len,
@@ -277,6 +282,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
277282
.partial = partial,
278283
.flags = flags,
279284
.ops = &page_cache_pipe_buf_ops,
285+
.spd_release = spd_release_page,
280286
};
281287

282288
index = *ppos >> PAGE_CACHE_SHIFT;
@@ -1432,6 +1438,7 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
14321438
.partial = partial,
14331439
.flags = flags,
14341440
.ops = &user_page_pipe_buf_ops,
1441+
.spd_release = spd_release_page,
14351442
};
14361443

14371444
pipe = pipe_info(file->f_path.dentry->d_inode);

include/linux/splice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct splice_pipe_desc {
5353
int nr_pages; /* number of pages in map */
5454
unsigned int flags; /* splice flags */
5555
const struct pipe_buf_operations *ops;/* ops associated with output pipe */
56+
void (*spd_release)(struct splice_pipe_desc *, unsigned int);
5657
};
5758

5859
typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,

0 commit comments

Comments
 (0)