Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 299841
b: refs/heads/master
c: 9883035
h: refs/heads/master
i:
  299839: 33e819c
v: v3
  • Loading branch information
Linus Torvalds committed Apr 29, 2012
1 parent 94516e2 commit 790829e
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: de9e24eda331bbefb9195a4d646c786bdcbba7d4
refs/heads/master: 9883035ae7edef3ec62ad215611cb8e17d6a1a5d
31 changes: 29 additions & 2 deletions trunk/fs/pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,16 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = {
.get = generic_pipe_buf_get,
};

static const struct pipe_buf_operations packet_pipe_buf_ops = {
.can_merge = 0,
.map = generic_pipe_buf_map,
.unmap = generic_pipe_buf_unmap,
.confirm = generic_pipe_buf_confirm,
.release = anon_pipe_buf_release,
.steal = generic_pipe_buf_steal,
.get = generic_pipe_buf_get,
};

static ssize_t
pipe_read(struct kiocb *iocb, const struct iovec *_iov,
unsigned long nr_segs, loff_t pos)
Expand Down Expand Up @@ -407,6 +417,13 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov,
ret += chars;
buf->offset += chars;
buf->len -= chars;

/* Was it a packet buffer? Clean up and exit */
if (buf->flags & PIPE_BUF_FLAG_PACKET) {
total_len = chars;
buf->len = 0;
}

if (!buf->len) {
buf->ops = NULL;
ops->release(pipe, buf);
Expand Down Expand Up @@ -459,6 +476,11 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov,
return ret;
}

static inline int is_packetized(struct file *file)
{
return (file->f_flags & O_DIRECT) != 0;
}

static ssize_t
pipe_write(struct kiocb *iocb, const struct iovec *_iov,
unsigned long nr_segs, loff_t ppos)
Expand Down Expand Up @@ -593,6 +615,11 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
buf->ops = &anon_pipe_buf_ops;
buf->offset = 0;
buf->len = chars;
buf->flags = 0;
if (is_packetized(filp)) {
buf->ops = &packet_pipe_buf_ops;
buf->flags = PIPE_BUF_FLAG_PACKET;
}
pipe->nrbufs = ++bufs;
pipe->tmp_page = NULL;

Expand Down Expand Up @@ -1013,7 +1040,7 @@ struct file *create_write_pipe(int flags)
goto err_dentry;
f->f_mapping = inode->i_mapping;

f->f_flags = O_WRONLY | (flags & O_NONBLOCK);
f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
f->f_version = 0;

return f;
Expand Down Expand Up @@ -1057,7 +1084,7 @@ int do_pipe_flags(int *fd, int flags)
int error;
int fdw, fdr;

if (flags & ~(O_CLOEXEC | O_NONBLOCK))
if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
return -EINVAL;

fw = create_write_pipe(flags);
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/pipe_fs_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define PIPE_BUF_FLAG_LRU 0x01 /* page is on the LRU */
#define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */
#define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */
#define PIPE_BUF_FLAG_PACKET 0x08 /* read() as a packet */

/**
* struct pipe_buffer - a linux kernel pipe buffer
Expand Down

0 comments on commit 790829e

Please sign in to comment.