aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/pipe.c')
-rw-r--r--fs/pipe.c52
1 files changed, 41 insertions, 11 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index 8aada8e426f4..109a102c150d 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -15,6 +15,7 @@
15#include <linux/pipe_fs_i.h> 15#include <linux/pipe_fs_i.h>
16#include <linux/uio.h> 16#include <linux/uio.h>
17#include <linux/highmem.h> 17#include <linux/highmem.h>
18#include <linux/pagemap.h>
18 19
19#include <asm/uaccess.h> 20#include <asm/uaccess.h>
20#include <asm/ioctls.h> 21#include <asm/ioctls.h>
@@ -94,11 +95,20 @@ static void anon_pipe_buf_release(struct pipe_inode_info *info, struct pipe_buff
94{ 95{
95 struct page *page = buf->page; 96 struct page *page = buf->page;
96 97
97 if (info->tmp_page) { 98 /*
98 __free_page(page); 99 * If nobody else uses this page, and we don't already have a
100 * temporary page, let's keep track of it as a one-deep
101 * allocation cache
102 */
103 if (page_count(page) == 1 && !info->tmp_page) {
104 info->tmp_page = page;
99 return; 105 return;
100 } 106 }
101 info->tmp_page = page; 107
108 /*
109 * Otherwise just release our reference to it
110 */
111 page_cache_release(page);
102} 112}
103 113
104static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *info, struct pipe_buffer *buf) 114static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *info, struct pipe_buffer *buf)
@@ -111,11 +121,19 @@ static void anon_pipe_buf_unmap(struct pipe_inode_info *info, struct pipe_buffer
111 kunmap(buf->page); 121 kunmap(buf->page);
112} 122}
113 123
124static int anon_pipe_buf_steal(struct pipe_inode_info *info,
125 struct pipe_buffer *buf)
126{
127 buf->stolen = 1;
128 return 0;
129}
130
114static struct pipe_buf_operations anon_pipe_buf_ops = { 131static struct pipe_buf_operations anon_pipe_buf_ops = {
115 .can_merge = 1, 132 .can_merge = 1,
116 .map = anon_pipe_buf_map, 133 .map = anon_pipe_buf_map,
117 .unmap = anon_pipe_buf_unmap, 134 .unmap = anon_pipe_buf_unmap,
118 .release = anon_pipe_buf_release, 135 .release = anon_pipe_buf_release,
136 .steal = anon_pipe_buf_steal,
119}; 137};
120 138
121static ssize_t 139static ssize_t
@@ -152,6 +170,11 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
152 chars = total_len; 170 chars = total_len;
153 171
154 addr = ops->map(filp, info, buf); 172 addr = ops->map(filp, info, buf);
173 if (IS_ERR(addr)) {
174 if (!ret)
175 ret = PTR_ERR(addr);
176 break;
177 }
155 error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars); 178 error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars);
156 ops->unmap(info, buf); 179 ops->unmap(info, buf);
157 if (unlikely(error)) { 180 if (unlikely(error)) {
@@ -254,8 +277,16 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
254 struct pipe_buf_operations *ops = buf->ops; 277 struct pipe_buf_operations *ops = buf->ops;
255 int offset = buf->offset + buf->len; 278 int offset = buf->offset + buf->len;
256 if (ops->can_merge && offset + chars <= PAGE_SIZE) { 279 if (ops->can_merge && offset + chars <= PAGE_SIZE) {
257 void *addr = ops->map(filp, info, buf); 280 void *addr;
258 int error = pipe_iov_copy_from_user(offset + addr, iov, chars); 281 int error;
282
283 addr = ops->map(filp, info, buf);
284 if (IS_ERR(addr)) {
285 error = PTR_ERR(addr);
286 goto out;
287 }
288 error = pipe_iov_copy_from_user(offset + addr, iov,
289 chars);
259 ops->unmap(info, buf); 290 ops->unmap(info, buf);
260 ret = error; 291 ret = error;
261 do_wakeup = 1; 292 do_wakeup = 1;
@@ -568,7 +599,7 @@ pipe_rdwr_open(struct inode *inode, struct file *filp)
568 * The file_operations structs are not static because they 599 * The file_operations structs are not static because they
569 * are also used in linux/fs/fifo.c to do operations on FIFOs. 600 * are also used in linux/fs/fifo.c to do operations on FIFOs.
570 */ 601 */
571struct file_operations read_fifo_fops = { 602const struct file_operations read_fifo_fops = {
572 .llseek = no_llseek, 603 .llseek = no_llseek,
573 .read = pipe_read, 604 .read = pipe_read,
574 .readv = pipe_readv, 605 .readv = pipe_readv,
@@ -580,7 +611,7 @@ struct file_operations read_fifo_fops = {
580 .fasync = pipe_read_fasync, 611 .fasync = pipe_read_fasync,
581}; 612};
582 613
583struct file_operations write_fifo_fops = { 614const struct file_operations write_fifo_fops = {
584 .llseek = no_llseek, 615 .llseek = no_llseek,
585 .read = bad_pipe_r, 616 .read = bad_pipe_r,
586 .write = pipe_write, 617 .write = pipe_write,
@@ -592,7 +623,7 @@ struct file_operations write_fifo_fops = {
592 .fasync = pipe_write_fasync, 623 .fasync = pipe_write_fasync,
593}; 624};
594 625
595struct file_operations rdwr_fifo_fops = { 626const struct file_operations rdwr_fifo_fops = {
596 .llseek = no_llseek, 627 .llseek = no_llseek,
597 .read = pipe_read, 628 .read = pipe_read,
598 .readv = pipe_readv, 629 .readv = pipe_readv,
@@ -662,10 +693,9 @@ struct inode* pipe_new(struct inode* inode)
662{ 693{
663 struct pipe_inode_info *info; 694 struct pipe_inode_info *info;
664 695
665 info = kmalloc(sizeof(struct pipe_inode_info), GFP_KERNEL); 696 info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
666 if (!info) 697 if (!info)
667 goto fail_page; 698 goto fail_page;
668 memset(info, 0, sizeof(*info));
669 inode->i_pipe = info; 699 inode->i_pipe = info;
670 700
671 init_waitqueue_head(PIPE_WAIT(*inode)); 701 init_waitqueue_head(PIPE_WAIT(*inode));
@@ -676,7 +706,7 @@ fail_page:
676 return NULL; 706 return NULL;
677} 707}
678 708
679static struct vfsmount *pipe_mnt; 709static struct vfsmount *pipe_mnt __read_mostly;
680static int pipefs_delete_dentry(struct dentry *dentry) 710static int pipefs_delete_dentry(struct dentry *dentry)
681{ 711{
682 return 1; 712 return 1;