Commit bbdfc2f70610bebb841d0874dc901c648308e43a

Authored by Jens Axboe
Committed by David S. Miller
1 parent d10f2150ea

[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>

Showing 2 changed files with 9 additions and 1 deletions Side-by-side Diff

... ... @@ -254,11 +254,16 @@
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 260 }
261 261  
  262 +static void spd_release_page(struct splice_pipe_desc *spd, unsigned int i)
  263 +{
  264 + page_cache_release(spd->pages[i]);
  265 +}
  266 +
262 267 static int
263 268 __generic_file_splice_read(struct file *in, loff_t *ppos,
264 269 struct pipe_inode_info *pipe, size_t len,
... ... @@ -277,6 +282,7 @@
277 282 .partial = partial,
278 283 .flags = flags,
279 284 .ops = &page_cache_pipe_buf_ops,
  285 + .spd_release = spd_release_page,
280 286 };
281 287  
282 288 index = *ppos >> PAGE_CACHE_SHIFT;
... ... @@ -1432,6 +1438,7 @@
1432 1438 .partial = partial,
1433 1439 .flags = flags,
1434 1440 .ops = &user_page_pipe_buf_ops,
  1441 + .spd_release = spd_release_page,
1435 1442 };
1436 1443  
1437 1444 pipe = pipe_info(file->f_path.dentry->d_inode);
include/linux/splice.h
... ... @@ -53,6 +53,7 @@
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 *,