Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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 <jens.axboe@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jens Axboe and committed by
David S. Miller
bbdfc2f7 d10f2150

+9 -1
+8 -1
fs/splice.c
··· 254 254 } 255 255 256 256 while (page_nr < spd_pages) 257 - page_cache_release(spd->pages[page_nr++]); 257 + spd->spd_release(spd, page_nr++); 258 258 259 259 return ret; 260 + } 261 + 262 + static void spd_release_page(struct splice_pipe_desc *spd, unsigned int i) 263 + { 264 + page_cache_release(spd->pages[i]); 260 265 } 261 266 262 267 static int ··· 282 277 .partial = partial, 283 278 .flags = flags, 284 279 .ops = &page_cache_pipe_buf_ops, 280 + .spd_release = spd_release_page, 285 281 }; 286 282 287 283 index = *ppos >> PAGE_CACHE_SHIFT; ··· 1438 1432 .partial = partial, 1439 1433 .flags = flags, 1440 1434 .ops = &user_page_pipe_buf_ops, 1435 + .spd_release = spd_release_page, 1441 1436 }; 1442 1437 1443 1438 pipe = pipe_info(file->f_path.dentry->d_inode);
+1
include/linux/splice.h
··· 53 53 int nr_pages; /* number of pages in map */ 54 54 unsigned int flags; /* splice flags */ 55 55 const struct pipe_buf_operations *ops;/* ops associated with output pipe */ 56 + void (*spd_release)(struct splice_pipe_desc *, unsigned int); 56 57 }; 57 58 58 59 typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,