git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
eCryptfs: Revert to a writethrough cache model
[pandora-kernel.git]
/
fs
/
splice.c
diff --git
a/fs/splice.c
b/fs/splice.c
index
fa2defa
..
014fcb4
100644
(file)
--- a/
fs/splice.c
+++ b/
fs/splice.c
@@
-31,6
+31,7
@@
#include <linux/uio.h>
#include <linux/security.h>
#include <linux/gfp.h>
#include <linux/uio.h>
#include <linux/security.h>
#include <linux/gfp.h>
+#include <linux/socket.h>
/*
* Attempt to steal a page from a pipe buffer. This should perhaps go into
/*
* Attempt to steal a page from a pipe buffer. This should perhaps go into
@@
-273,13
+274,16
@@
void spd_release_page(struct splice_pipe_desc *spd, unsigned int i)
* Check if we need to grow the arrays holding pages and partial page
* descriptions.
*/
* Check if we need to grow the arrays holding pages and partial page
* descriptions.
*/
-int splice_grow_spd(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd)
+int splice_grow_spd(
const
struct pipe_inode_info *pipe, struct splice_pipe_desc *spd)
{
{
- if (pipe->buffers <= PIPE_DEF_BUFFERS)
+ unsigned int buffers = ACCESS_ONCE(pipe->buffers);
+
+ spd->nr_pages_max = buffers;
+ if (buffers <= PIPE_DEF_BUFFERS)
return 0;
return 0;
- spd->pages = kmalloc(
pipe->
buffers * sizeof(struct page *), GFP_KERNEL);
- spd->partial = kmalloc(
pipe->
buffers * sizeof(struct partial_page), GFP_KERNEL);
+ spd->pages = kmalloc(buffers * sizeof(struct page *), GFP_KERNEL);
+ spd->partial = kmalloc(buffers * sizeof(struct partial_page), GFP_KERNEL);
if (spd->pages && spd->partial)
return 0;
if (spd->pages && spd->partial)
return 0;
@@
-289,10
+293,9
@@
int splice_grow_spd(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd)
return -ENOMEM;
}
return -ENOMEM;
}
-void splice_shrink_spd(struct pipe_inode_info *pipe,
- struct splice_pipe_desc *spd)
+void splice_shrink_spd(struct splice_pipe_desc *spd)
{
{
- if (
pipe->buffers
<= PIPE_DEF_BUFFERS)
+ if (
spd->nr_pages_max
<= PIPE_DEF_BUFFERS)
return;
kfree(spd->pages);
return;
kfree(spd->pages);
@@
-315,6
+318,7
@@
__generic_file_splice_read(struct file *in, loff_t *ppos,
struct splice_pipe_desc spd = {
.pages = pages,
.partial = partial,
struct splice_pipe_desc spd = {
.pages = pages,
.partial = partial,
+ .nr_pages_max = PIPE_DEF_BUFFERS,
.flags = flags,
.ops = &page_cache_pipe_buf_ops,
.spd_release = spd_release_page,
.flags = flags,
.ops = &page_cache_pipe_buf_ops,
.spd_release = spd_release_page,
@@
-326,7
+330,7
@@
__generic_file_splice_read(struct file *in, loff_t *ppos,
index = *ppos >> PAGE_CACHE_SHIFT;
loff = *ppos & ~PAGE_CACHE_MASK;
req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
index = *ppos >> PAGE_CACHE_SHIFT;
loff = *ppos & ~PAGE_CACHE_MASK;
req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
- nr_pages = min(req_pages,
pipe->buffers
);
+ nr_pages = min(req_pages,
spd.nr_pages_max
);
/*
* Lookup the (hopefully) full range of pages we need.
/*
* Lookup the (hopefully) full range of pages we need.
@@
-497,7
+501,7
@@
fill_it:
if (spd.nr_pages)
error = splice_to_pipe(pipe, &spd);
if (spd.nr_pages)
error = splice_to_pipe(pipe, &spd);
- splice_shrink_spd(
pipe,
&spd);
+ splice_shrink_spd(&spd);
return error;
}
return error;
}
@@
-598,6
+602,7
@@
ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
struct splice_pipe_desc spd = {
.pages = pages,
.partial = partial,
struct splice_pipe_desc spd = {
.pages = pages,
.partial = partial,
+ .nr_pages_max = PIPE_DEF_BUFFERS,
.flags = flags,
.ops = &default_pipe_buf_ops,
.spd_release = spd_release_page,
.flags = flags,
.ops = &default_pipe_buf_ops,
.spd_release = spd_release_page,
@@
-608,8
+613,8
@@
ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
res = -ENOMEM;
vec = __vec;
res = -ENOMEM;
vec = __vec;
- if (
pipe->buffers
> PIPE_DEF_BUFFERS) {
- vec = kmalloc(
pipe->buffers
* sizeof(struct iovec), GFP_KERNEL);
+ if (
spd.nr_pages_max
> PIPE_DEF_BUFFERS) {
+ vec = kmalloc(
spd.nr_pages_max
* sizeof(struct iovec), GFP_KERNEL);
if (!vec)
goto shrink_ret;
}
if (!vec)
goto shrink_ret;
}
@@
-617,7
+622,7
@@
ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
offset = *ppos & ~PAGE_CACHE_MASK;
nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
offset = *ppos & ~PAGE_CACHE_MASK;
nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
- for (i = 0; i < nr_pages && i <
pipe->buffers
&& len; i++) {
+ for (i = 0; i < nr_pages && i <
spd.nr_pages_max
&& len; i++) {
struct page *page;
page = alloc_page(GFP_USER);
struct page *page;
page = alloc_page(GFP_USER);
@@
-665,7
+670,7
@@
ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
shrink_ret:
if (vec != __vec)
kfree(vec);
shrink_ret:
if (vec != __vec)
kfree(vec);
- splice_shrink_spd(
pipe,
&spd);
+ splice_shrink_spd(&spd);
return res;
err:
return res;
err:
@@
-691,7
+696,9
@@
static int pipe_to_sendpage(struct pipe_inode_info *pipe,
if (!likely(file->f_op && file->f_op->sendpage))
return -EINVAL;
if (!likely(file->f_op && file->f_op->sendpage))
return -EINVAL;
- more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
+ more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
+ if (sd->len < sd->total_len)
+ more |= MSG_SENDPAGE_NOTLAST;
return file->f_op->sendpage(file, buf->page, buf->offset,
sd->len, &pos, more);
}
return file->f_op->sendpage(file, buf->page, buf->offset,
sd->len, &pos, more);
}
@@
-1613,6
+1620,7
@@
static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
struct splice_pipe_desc spd = {
.pages = pages,
.partial = partial,
struct splice_pipe_desc spd = {
.pages = pages,
.partial = partial,
+ .nr_pages_max = PIPE_DEF_BUFFERS,
.flags = flags,
.ops = &user_page_pipe_buf_ops,
.spd_release = spd_release_page,
.flags = flags,
.ops = &user_page_pipe_buf_ops,
.spd_release = spd_release_page,
@@
-1628,13
+1636,13
@@
static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
spd.nr_pages = get_iovec_page_array(iov, nr_segs, spd.pages,
spd.partial, flags & SPLICE_F_GIFT,
spd.nr_pages = get_iovec_page_array(iov, nr_segs, spd.pages,
spd.partial, flags & SPLICE_F_GIFT,
-
pipe->buffers
);
+
spd.nr_pages_max
);
if (spd.nr_pages <= 0)
ret = spd.nr_pages;
else
ret = splice_to_pipe(pipe, &spd);
if (spd.nr_pages <= 0)
ret = spd.nr_pages;
else
ret = splice_to_pipe(pipe, &spd);
- splice_shrink_spd(
pipe,
&spd);
+ splice_shrink_spd(&spd);
return ret;
}
return ret;
}