summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0117-pipes-add-a-packetized-pipe-mode-for-writing.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0117-pipes-add-a-packetized-pipe-mode-for-writing.patch')
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0117-pipes-add-a-packetized-pipe-mode-for-writing.patch143
1 files changed, 143 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0117-pipes-add-a-packetized-pipe-mode-for-writing.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0117-pipes-add-a-packetized-pipe-mode-for-writing.patch
new file mode 100644
index 00000000..e25c9d0e
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.17/0117-pipes-add-a-packetized-pipe-mode-for-writing.patch
@@ -0,0 +1,143 @@
1From 458c33bdfc9d408f94038a4db0544ab348d0d96d Mon Sep 17 00:00:00 2001
2From: Linus Torvalds <torvalds@linux-foundation.org>
3Date: Sun, 29 Apr 2012 13:12:42 -0700
4Subject: [PATCH 117/165] pipes: add a "packetized pipe" mode for writing
5
6commit 9883035ae7edef3ec62ad215611cb8e17d6a1a5d upstream.
7
8The actual internal pipe implementation is already really about
9individual packets (called "pipe buffers"), and this simply exposes that
10as a special packetized mode.
11
12When we are in the packetized mode (marked by O_DIRECT as suggested by
13Alan Cox), a write() on a pipe will not merge the new data with previous
14writes, so each write will get a pipe buffer of its own. The pipe
15buffer is then marked with the PIPE_BUF_FLAG_PACKET flag, which in turn
16will tell the reader side to break the read at that boundary (and throw
17away any partial packet contents that do not fit in the read buffer).
18
19End result: as long as you do writes less than PIPE_BUF in size (so that
20the pipe doesn't have to split them up), you can now treat the pipe as a
21packet interface, where each read() system call will read one packet at
22a time. You can just use a sufficiently big read buffer (PIPE_BUF is
23sufficient, since bigger than that doesn't guarantee atomicity anyway),
24and the return value of the read() will naturally give you the size of
25the packet.
26
27NOTE! We do not support zero-sized packets, and zero-sized reads and
28writes to a pipe continue to be no-ops. Also note that big packets will
29currently be split at write time, but that the size at which that
30happens is not really specified (except that it's bigger than PIPE_BUF).
31Currently that limit is the system page size, but we might want to
32explicitly support bigger packets some day.
33
34The main user for this is going to be the autofs packet interface,
35allowing us to stop having to care so deeply about exact packet sizes
36(which have had bugs with 32/64-bit compatibility modes). But user
37space can create packetized pipes with "pipe2(fd, O_DIRECT)", which will
38fail with an EINVAL on kernels that do not support this interface.
39
40Tested-by: Michael Tokarev <mjt@tls.msk.ru>
41Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
42Cc: David Miller <davem@davemloft.net>
43Cc: Ian Kent <raven@themaw.net>
44Cc: Thomas Meyer <thomas@m3y3r.de>
45Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
46Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
47---
48 fs/pipe.c | 31 +++++++++++++++++++++++++++++--
49 include/linux/pipe_fs_i.h | 1 +
50 2 files changed, 30 insertions(+), 2 deletions(-)
51
52diff --git a/fs/pipe.c b/fs/pipe.c
53index 4065f07..05ed5ca 100644
54--- a/fs/pipe.c
55+++ b/fs/pipe.c
56@@ -345,6 +345,16 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = {
57 .get = generic_pipe_buf_get,
58 };
59
60+static const struct pipe_buf_operations packet_pipe_buf_ops = {
61+ .can_merge = 0,
62+ .map = generic_pipe_buf_map,
63+ .unmap = generic_pipe_buf_unmap,
64+ .confirm = generic_pipe_buf_confirm,
65+ .release = anon_pipe_buf_release,
66+ .steal = generic_pipe_buf_steal,
67+ .get = generic_pipe_buf_get,
68+};
69+
70 static ssize_t
71 pipe_read(struct kiocb *iocb, const struct iovec *_iov,
72 unsigned long nr_segs, loff_t pos)
73@@ -406,6 +416,13 @@ redo:
74 ret += chars;
75 buf->offset += chars;
76 buf->len -= chars;
77+
78+ /* Was it a packet buffer? Clean up and exit */
79+ if (buf->flags & PIPE_BUF_FLAG_PACKET) {
80+ total_len = chars;
81+ buf->len = 0;
82+ }
83+
84 if (!buf->len) {
85 buf->ops = NULL;
86 ops->release(pipe, buf);
87@@ -458,6 +475,11 @@ redo:
88 return ret;
89 }
90
91+static inline int is_packetized(struct file *file)
92+{
93+ return (file->f_flags & O_DIRECT) != 0;
94+}
95+
96 static ssize_t
97 pipe_write(struct kiocb *iocb, const struct iovec *_iov,
98 unsigned long nr_segs, loff_t ppos)
99@@ -592,6 +614,11 @@ redo2:
100 buf->ops = &anon_pipe_buf_ops;
101 buf->offset = 0;
102 buf->len = chars;
103+ buf->flags = 0;
104+ if (is_packetized(filp)) {
105+ buf->ops = &packet_pipe_buf_ops;
106+ buf->flags = PIPE_BUF_FLAG_PACKET;
107+ }
108 pipe->nrbufs = ++bufs;
109 pipe->tmp_page = NULL;
110
111@@ -1012,7 +1039,7 @@ struct file *create_write_pipe(int flags)
112 goto err_dentry;
113 f->f_mapping = inode->i_mapping;
114
115- f->f_flags = O_WRONLY | (flags & O_NONBLOCK);
116+ f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
117 f->f_version = 0;
118
119 return f;
120@@ -1056,7 +1083,7 @@ int do_pipe_flags(int *fd, int flags)
121 int error;
122 int fdw, fdr;
123
124- if (flags & ~(O_CLOEXEC | O_NONBLOCK))
125+ if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
126 return -EINVAL;
127
128 fw = create_write_pipe(flags);
129diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
130index 77257c9..0072a53 100644
131--- a/include/linux/pipe_fs_i.h
132+++ b/include/linux/pipe_fs_i.h
133@@ -8,6 +8,7 @@
134 #define PIPE_BUF_FLAG_LRU 0x01 /* page is on the LRU */
135 #define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */
136 #define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */
137+#define PIPE_BUF_FLAG_PACKET 0x08 /* read() as a packet */
138
139 /**
140 * struct pipe_buffer - a linux kernel pipe buffer
141--
1421.7.7.6
143