aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/pipe.c')
-rw-r--r--fs/pipe.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index a932ced92a1..fec5e4ad071 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -13,6 +13,7 @@
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/log2.h> 14#include <linux/log2.h>
15#include <linux/mount.h> 15#include <linux/mount.h>
16#include <linux/magic.h>
16#include <linux/pipe_fs_i.h> 17#include <linux/pipe_fs_i.h>
17#include <linux/uio.h> 18#include <linux/uio.h>
18#include <linux/highmem.h> 19#include <linux/highmem.h>
@@ -230,7 +231,7 @@ void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
230{ 231{
231 if (atomic) { 232 if (atomic) {
232 buf->flags |= PIPE_BUF_FLAG_ATOMIC; 233 buf->flags |= PIPE_BUF_FLAG_ATOMIC;
233 return kmap_atomic(buf->page, KM_USER0); 234 return kmap_atomic(buf->page);
234 } 235 }
235 236
236 return kmap(buf->page); 237 return kmap(buf->page);
@@ -251,7 +252,7 @@ void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
251{ 252{
252 if (buf->flags & PIPE_BUF_FLAG_ATOMIC) { 253 if (buf->flags & PIPE_BUF_FLAG_ATOMIC) {
253 buf->flags &= ~PIPE_BUF_FLAG_ATOMIC; 254 buf->flags &= ~PIPE_BUF_FLAG_ATOMIC;
254 kunmap_atomic(map_data, KM_USER0); 255 kunmap_atomic(map_data);
255 } else 256 } else
256 kunmap(buf->page); 257 kunmap(buf->page);
257} 258}
@@ -345,6 +346,16 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = {
345 .get = generic_pipe_buf_get, 346 .get = generic_pipe_buf_get,
346}; 347};
347 348
349static const struct pipe_buf_operations packet_pipe_buf_ops = {
350 .can_merge = 0,
351 .map = generic_pipe_buf_map,
352 .unmap = generic_pipe_buf_unmap,
353 .confirm = generic_pipe_buf_confirm,
354 .release = anon_pipe_buf_release,
355 .steal = generic_pipe_buf_steal,
356 .get = generic_pipe_buf_get,
357};
358
348static ssize_t 359static ssize_t
349pipe_read(struct kiocb *iocb, const struct iovec *_iov, 360pipe_read(struct kiocb *iocb, const struct iovec *_iov,
350 unsigned long nr_segs, loff_t pos) 361 unsigned long nr_segs, loff_t pos)
@@ -406,6 +417,13 @@ redo:
406 ret += chars; 417 ret += chars;
407 buf->offset += chars; 418 buf->offset += chars;
408 buf->len -= chars; 419 buf->len -= chars;
420
421 /* Was it a packet buffer? Clean up and exit */
422 if (buf->flags & PIPE_BUF_FLAG_PACKET) {
423 total_len = chars;
424 buf->len = 0;
425 }
426
409 if (!buf->len) { 427 if (!buf->len) {
410 buf->ops = NULL; 428 buf->ops = NULL;
411 ops->release(pipe, buf); 429 ops->release(pipe, buf);
@@ -458,6 +476,11 @@ redo:
458 return ret; 476 return ret;
459} 477}
460 478
479static inline int is_packetized(struct file *file)
480{
481 return (file->f_flags & O_DIRECT) != 0;
482}
483
461static ssize_t 484static ssize_t
462pipe_write(struct kiocb *iocb, const struct iovec *_iov, 485pipe_write(struct kiocb *iocb, const struct iovec *_iov,
463 unsigned long nr_segs, loff_t ppos) 486 unsigned long nr_segs, loff_t ppos)
@@ -565,14 +588,14 @@ redo1:
565 iov_fault_in_pages_read(iov, chars); 588 iov_fault_in_pages_read(iov, chars);
566redo2: 589redo2:
567 if (atomic) 590 if (atomic)
568 src = kmap_atomic(page, KM_USER0); 591 src = kmap_atomic(page);
569 else 592 else
570 src = kmap(page); 593 src = kmap(page);
571 594
572 error = pipe_iov_copy_from_user(src, iov, chars, 595 error = pipe_iov_copy_from_user(src, iov, chars,
573 atomic); 596 atomic);
574 if (atomic) 597 if (atomic)
575 kunmap_atomic(src, KM_USER0); 598 kunmap_atomic(src);
576 else 599 else
577 kunmap(page); 600 kunmap(page);
578 601
@@ -592,6 +615,11 @@ redo2:
592 buf->ops = &anon_pipe_buf_ops; 615 buf->ops = &anon_pipe_buf_ops;
593 buf->offset = 0; 616 buf->offset = 0;
594 buf->len = chars; 617 buf->len = chars;
618 buf->flags = 0;
619 if (is_packetized(filp)) {
620 buf->ops = &packet_pipe_buf_ops;
621 buf->flags = PIPE_BUF_FLAG_PACKET;
622 }
595 pipe->nrbufs = ++bufs; 623 pipe->nrbufs = ++bufs;
596 pipe->tmp_page = NULL; 624 pipe->tmp_page = NULL;
597 625
@@ -1012,7 +1040,7 @@ struct file *create_write_pipe(int flags)
1012 goto err_dentry; 1040 goto err_dentry;
1013 f->f_mapping = inode->i_mapping; 1041 f->f_mapping = inode->i_mapping;
1014 1042
1015 f->f_flags = O_WRONLY | (flags & O_NONBLOCK); 1043 f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
1016 f->f_version = 0; 1044 f->f_version = 0;
1017 1045
1018 return f; 1046 return f;
@@ -1056,7 +1084,7 @@ int do_pipe_flags(int *fd, int flags)
1056 int error; 1084 int error;
1057 int fdw, fdr; 1085 int fdw, fdr;
1058 1086
1059 if (flags & ~(O_CLOEXEC | O_NONBLOCK)) 1087 if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
1060 return -EINVAL; 1088 return -EINVAL;
1061 1089
1062 fw = create_write_pipe(flags); 1090 fw = create_write_pipe(flags);