Blame view

fs/pipe.c 27.7 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
9
10
11
12
13
14
  /*
   *  linux/fs/pipe.c
   *
   *  Copyright (C) 1991, 1992, 1999  Linus Torvalds
   */
  
  #include <linux/mm.h>
  #include <linux/file.h>
  #include <linux/poll.h>
  #include <linux/slab.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/fs.h>
35f3d14db   Jens Axboe   pipe: add support...
15
  #include <linux/log2.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
  #include <linux/mount.h>
b502bd115   Muthu Kumar   magic.h: move som...
17
  #include <linux/magic.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
  #include <linux/pipe_fs_i.h>
  #include <linux/uio.h>
  #include <linux/highmem.h>
5274f052e   Jens Axboe   [PATCH] Introduce...
21
  #include <linux/pagemap.h>
db3495099   Al Viro   [PATCH] AUDIT_FD_...
22
  #include <linux/audit.h>
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
23
  #include <linux/syscalls.h>
b492e95be   Jens Axboe   pipe: set lower a...
24
  #include <linux/fcntl.h>
d86133bd3   Vladimir Davydov   pipe: account to ...
25
  #include <linux/memcontrol.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26

7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
27
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
  #include <asm/ioctls.h>
599a0ac14   Al Viro   pipe: fold file_o...
29
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  /*
b492e95be   Jens Axboe   pipe: set lower a...
31
   * The max size that a non-root user is allowed to grow the pipe. Can
ff9da691c   Jens Axboe   pipe: change /pro...
32
   * be set by root in /proc/sys/fs/pipe-max-size
b492e95be   Jens Axboe   pipe: set lower a...
33
   */
ff9da691c   Jens Axboe   pipe: change /pro...
34
35
36
37
38
39
  unsigned int pipe_max_size = 1048576;
  
  /*
   * Minimum pipe size, as required by POSIX
   */
  unsigned int pipe_min_size = PAGE_SIZE;
b492e95be   Jens Axboe   pipe: set lower a...
40

759c01142   Willy Tarreau   pipe: limit the p...
41
42
43
44
45
  /* Maximum allocatable pages per user. Hard limit is unset by default, soft
   * matches default values.
   */
  unsigned long pipe_user_pages_hard;
  unsigned long pipe_user_pages_soft = PIPE_DEF_BUFFERS * INR_OPEN_CUR;
b492e95be   Jens Axboe   pipe: set lower a...
46
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47
48
49
50
51
52
53
54
55
56
57
58
59
   * We use a start+len construction, which provides full use of the 
   * allocated memory.
   * -- Florian Coosmann (FGC)
   * 
   * Reads with count = 0 should always return 0.
   * -- Julian Bradfield 1999-06-07.
   *
   * FIFOs and Pipes now generate SIGIO for both readers and writers.
   * -- Jeremy Elson <jelson@circlemud.org> 2001-08-16
   *
   * pipe_read & write cleanup
   * -- Manfred Spraul <manfred@colorfullife.com> 2002-05-09
   */
61e0d47c3   Miklos Szeredi   splice: add helpe...
60
61
  static void pipe_lock_nested(struct pipe_inode_info *pipe, int subclass)
  {
6447a3cf1   Al Viro   get rid of pipe->...
62
  	if (pipe->files)
72b0d9aac   Al Viro   pipe: don't use -...
63
  		mutex_lock_nested(&pipe->mutex, subclass);
61e0d47c3   Miklos Szeredi   splice: add helpe...
64
65
66
67
68
69
70
71
72
73
74
75
76
  }
  
  void pipe_lock(struct pipe_inode_info *pipe)
  {
  	/*
  	 * pipe_lock() nests non-pipe inode locks (for writing to a file)
  	 */
  	pipe_lock_nested(pipe, I_MUTEX_PARENT);
  }
  EXPORT_SYMBOL(pipe_lock);
  
  void pipe_unlock(struct pipe_inode_info *pipe)
  {
6447a3cf1   Al Viro   get rid of pipe->...
77
  	if (pipe->files)
72b0d9aac   Al Viro   pipe: don't use -...
78
  		mutex_unlock(&pipe->mutex);
61e0d47c3   Miklos Szeredi   splice: add helpe...
79
80
  }
  EXPORT_SYMBOL(pipe_unlock);
ebec73f47   Al Viro   introduce variant...
81
82
83
84
85
86
87
88
89
  static inline void __pipe_lock(struct pipe_inode_info *pipe)
  {
  	mutex_lock_nested(&pipe->mutex, I_MUTEX_PARENT);
  }
  
  static inline void __pipe_unlock(struct pipe_inode_info *pipe)
  {
  	mutex_unlock(&pipe->mutex);
  }
61e0d47c3   Miklos Szeredi   splice: add helpe...
90
91
92
93
94
95
96
97
98
  void pipe_double_lock(struct pipe_inode_info *pipe1,
  		      struct pipe_inode_info *pipe2)
  {
  	BUG_ON(pipe1 == pipe2);
  
  	if (pipe1 < pipe2) {
  		pipe_lock_nested(pipe1, I_MUTEX_PARENT);
  		pipe_lock_nested(pipe2, I_MUTEX_CHILD);
  	} else {
023d43c7b   Peter Zijlstra   lockdep: Fix lock...
99
100
  		pipe_lock_nested(pipe2, I_MUTEX_PARENT);
  		pipe_lock_nested(pipe1, I_MUTEX_CHILD);
61e0d47c3   Miklos Szeredi   splice: add helpe...
101
102
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
  /* Drop the inode semaphore and wait for a pipe event, atomically */
3a326a2ce   Ingo Molnar   [PATCH] introduce...
104
  void pipe_wait(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
106
  {
  	DEFINE_WAIT(wait);
d79fc0fc6   Ingo Molnar   [PATCH] sched: TA...
107
108
109
110
  	/*
  	 * Pipes are system-local resources, so sleeping on them
  	 * is considered a noninteractive wait:
  	 */
af9272326   Mike Galbraith   sched: cleanup, r...
111
  	prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE);
61e0d47c3   Miklos Szeredi   splice: add helpe...
112
  	pipe_unlock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
  	schedule();
3a326a2ce   Ingo Molnar   [PATCH] introduce...
114
  	finish_wait(&pipe->wait, &wait);
61e0d47c3   Miklos Szeredi   splice: add helpe...
115
  	pipe_lock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  }
341b446bc   Ingo Molnar   [PATCH] another r...
117
118
  static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
  				  struct pipe_buffer *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
  {
  	struct page *page = buf->page;
5274f052e   Jens Axboe   [PATCH] Introduce...
121
122
123
  	/*
  	 * If nobody else uses this page, and we don't already have a
  	 * temporary page, let's keep track of it as a one-deep
341b446bc   Ingo Molnar   [PATCH] another r...
124
  	 * allocation cache. (Otherwise just release our reference to it)
5274f052e   Jens Axboe   [PATCH] Introduce...
125
  	 */
341b446bc   Ingo Molnar   [PATCH] another r...
126
  	if (page_count(page) == 1 && !pipe->tmp_page)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
127
  		pipe->tmp_page = page;
341b446bc   Ingo Molnar   [PATCH] another r...
128
  	else
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
129
  		put_page(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
  }
d86133bd3   Vladimir Davydov   pipe: account to ...
131
132
133
134
135
136
  static int anon_pipe_buf_steal(struct pipe_inode_info *pipe,
  			       struct pipe_buffer *buf)
  {
  	struct page *page = buf->page;
  
  	if (page_count(page) == 1) {
c4159a75b   Vladimir Davydov   mm: memcontrol: o...
137
  		if (memcg_kmem_enabled())
d86133bd3   Vladimir Davydov   pipe: account to ...
138
  			memcg_kmem_uncharge(page, 0);
d86133bd3   Vladimir Davydov   pipe: account to ...
139
140
141
142
143
  		__SetPageLocked(page);
  		return 0;
  	}
  	return 1;
  }
0845718da   Jens Axboe   pipe: add documen...
144
  /**
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
145
   * generic_pipe_buf_steal - attempt to take ownership of a &pipe_buffer
0845718da   Jens Axboe   pipe: add documen...
146
147
148
149
   * @pipe:	the pipe that the buffer belongs to
   * @buf:	the buffer to attempt to steal
   *
   * Description:
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
150
   *	This function attempts to steal the &struct page attached to
0845718da   Jens Axboe   pipe: add documen...
151
152
   *	@buf. If successful, this function returns 0 and returns with
   *	the page locked. The caller may then reuse the page for whatever
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
153
   *	he wishes; the typical use is insertion into a different file
0845718da   Jens Axboe   pipe: add documen...
154
155
   *	page cache.
   */
330ab7161   Jens Axboe   [PATCH] vmsplice:...
156
157
  int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
  			   struct pipe_buffer *buf)
5abc97aa2   Jens Axboe   [PATCH] splice: a...
158
  {
46e678c96   Jens Axboe   [PATCH] splice: f...
159
  	struct page *page = buf->page;
0845718da   Jens Axboe   pipe: add documen...
160
161
162
163
164
  	/*
  	 * A reference of one is golden, that means that the owner of this
  	 * page is the only one holding a reference to it. lock the page
  	 * and return OK.
  	 */
46e678c96   Jens Axboe   [PATCH] splice: f...
165
  	if (page_count(page) == 1) {
46e678c96   Jens Axboe   [PATCH] splice: f...
166
167
168
169
170
  		lock_page(page);
  		return 0;
  	}
  
  	return 1;
5abc97aa2   Jens Axboe   [PATCH] splice: a...
171
  }
51921cb74   Miklos Szeredi   mm: export generi...
172
  EXPORT_SYMBOL(generic_pipe_buf_steal);
5abc97aa2   Jens Axboe   [PATCH] splice: a...
173

0845718da   Jens Axboe   pipe: add documen...
174
  /**
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
175
   * generic_pipe_buf_get - get a reference to a &struct pipe_buffer
0845718da   Jens Axboe   pipe: add documen...
176
177
178
179
180
181
182
183
184
   * @pipe:	the pipe that the buffer belongs to
   * @buf:	the buffer to get a reference to
   *
   * Description:
   *	This function grabs an extra reference to @buf. It's used in
   *	in the tee() system call, when we duplicate the buffers in one
   *	pipe into another.
   */
  void generic_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
70524490e   Jens Axboe   [PATCH] splice: a...
185
  {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
186
  	get_page(buf->page);
70524490e   Jens Axboe   [PATCH] splice: a...
187
  }
51921cb74   Miklos Szeredi   mm: export generi...
188
  EXPORT_SYMBOL(generic_pipe_buf_get);
70524490e   Jens Axboe   [PATCH] splice: a...
189

0845718da   Jens Axboe   pipe: add documen...
190
191
  /**
   * generic_pipe_buf_confirm - verify contents of the pipe buffer
79685b8de   Randy Dunlap   docbook: add pipe...
192
   * @info:	the pipe that the buffer belongs to
0845718da   Jens Axboe   pipe: add documen...
193
194
195
196
197
198
   * @buf:	the buffer to confirm
   *
   * Description:
   *	This function does nothing, because the generic pipe code uses
   *	pages that are always good when inserted into the pipe.
   */
cac36bb06   Jens Axboe   pipe: change the ...
199
200
  int generic_pipe_buf_confirm(struct pipe_inode_info *info,
  			     struct pipe_buffer *buf)
f84d75199   Jens Axboe   [PATCH] pipe: int...
201
202
203
  {
  	return 0;
  }
51921cb74   Miklos Szeredi   mm: export generi...
204
  EXPORT_SYMBOL(generic_pipe_buf_confirm);
f84d75199   Jens Axboe   [PATCH] pipe: int...
205

6818173bd   Miklos Szeredi   splice: implement...
206
207
208
209
210
211
212
213
214
215
216
  /**
   * generic_pipe_buf_release - put a reference to a &struct pipe_buffer
   * @pipe:	the pipe that the buffer belongs to
   * @buf:	the buffer to put a reference to
   *
   * Description:
   *	This function releases a reference to @buf.
   */
  void generic_pipe_buf_release(struct pipe_inode_info *pipe,
  			      struct pipe_buffer *buf)
  {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
217
  	put_page(buf->page);
6818173bd   Miklos Szeredi   splice: implement...
218
  }
51921cb74   Miklos Szeredi   mm: export generi...
219
  EXPORT_SYMBOL(generic_pipe_buf_release);
6818173bd   Miklos Szeredi   splice: implement...
220

d4c3cca94   Eric Dumazet   [PATCH] constify ...
221
  static const struct pipe_buf_operations anon_pipe_buf_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
  	.can_merge = 1,
cac36bb06   Jens Axboe   pipe: change the ...
223
  	.confirm = generic_pipe_buf_confirm,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
  	.release = anon_pipe_buf_release,
d86133bd3   Vladimir Davydov   pipe: account to ...
225
  	.steal = anon_pipe_buf_steal,
f84d75199   Jens Axboe   [PATCH] pipe: int...
226
  	.get = generic_pipe_buf_get,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227
  };
9883035ae   Linus Torvalds   pipes: add a "pac...
228
229
  static const struct pipe_buf_operations packet_pipe_buf_ops = {
  	.can_merge = 0,
9883035ae   Linus Torvalds   pipes: add a "pac...
230
231
  	.confirm = generic_pipe_buf_confirm,
  	.release = anon_pipe_buf_release,
d86133bd3   Vladimir Davydov   pipe: account to ...
232
  	.steal = anon_pipe_buf_steal,
9883035ae   Linus Torvalds   pipes: add a "pac...
233
234
  	.get = generic_pipe_buf_get,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
  static ssize_t
fb9096a34   Al Viro   pipe: switch to -...
236
  pipe_read(struct kiocb *iocb, struct iov_iter *to)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
  {
fb9096a34   Al Viro   pipe: switch to -...
238
  	size_t total_len = iov_iter_count(to);
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
239
  	struct file *filp = iocb->ki_filp;
de32ec4cf   Al Viro   pipe: set file->p...
240
  	struct pipe_inode_info *pipe = filp->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
242
  	int do_wakeup;
  	ssize_t ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
245
246
247
248
249
  	/* Null read succeeds. */
  	if (unlikely(total_len == 0))
  		return 0;
  
  	do_wakeup = 0;
  	ret = 0;
ebec73f47   Al Viro   introduce variant...
250
  	__pipe_lock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
  	for (;;) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
252
  		int bufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
  		if (bufs) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
254
255
  			int curbuf = pipe->curbuf;
  			struct pipe_buffer *buf = pipe->bufs + curbuf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
  			size_t chars = buf->len;
637b58c28   Al Viro   switch pipe_read(...
257
258
  			size_t written;
  			int error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
260
261
  
  			if (chars > total_len)
  				chars = total_len;
fba597db4   Miklos Szeredi   pipe: add pipe_bu...
262
  			error = pipe_buf_confirm(pipe, buf);
f84d75199   Jens Axboe   [PATCH] pipe: int...
263
  			if (error) {
5274f052e   Jens Axboe   [PATCH] Introduce...
264
  				if (!ret)
e5953cbdf   Nicolas Kaiser   pipe: fix failure...
265
  					ret = error;
5274f052e   Jens Axboe   [PATCH] Introduce...
266
267
  				break;
  			}
f84d75199   Jens Axboe   [PATCH] pipe: int...
268

fb9096a34   Al Viro   pipe: switch to -...
269
  			written = copy_page_to_iter(buf->page, buf->offset, chars, to);
637b58c28   Al Viro   switch pipe_read(...
270
  			if (unlikely(written < chars)) {
341b446bc   Ingo Molnar   [PATCH] another r...
271
  				if (!ret)
637b58c28   Al Viro   switch pipe_read(...
272
  					ret = -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273
274
275
276
277
  				break;
  			}
  			ret += chars;
  			buf->offset += chars;
  			buf->len -= chars;
9883035ae   Linus Torvalds   pipes: add a "pac...
278
279
280
281
282
283
  
  			/* Was it a packet buffer? Clean up and exit */
  			if (buf->flags & PIPE_BUF_FLAG_PACKET) {
  				total_len = chars;
  				buf->len = 0;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
  			if (!buf->len) {
a779638cf   Miklos Szeredi   pipe: add pipe_bu...
285
  				pipe_buf_release(pipe, buf);
35f3d14db   Jens Axboe   pipe: add support...
286
  				curbuf = (curbuf + 1) & (pipe->buffers - 1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
287
288
  				pipe->curbuf = curbuf;
  				pipe->nrbufs = --bufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
290
291
292
293
294
295
296
  				do_wakeup = 1;
  			}
  			total_len -= chars;
  			if (!total_len)
  				break;	/* common path: read succeeded */
  		}
  		if (bufs)	/* More to do? */
  			continue;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
297
  		if (!pipe->writers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
  			break;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
299
  		if (!pipe->waiting_writers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
301
302
303
304
305
306
307
308
309
310
311
312
  			/* syscall merging: Usually we must not sleep
  			 * if O_NONBLOCK is set, or if we got some data.
  			 * But if a writer sleeps in kernel space, then
  			 * we can wait for that data without violating POSIX.
  			 */
  			if (ret)
  				break;
  			if (filp->f_flags & O_NONBLOCK) {
  				ret = -EAGAIN;
  				break;
  			}
  		}
  		if (signal_pending(current)) {
341b446bc   Ingo Molnar   [PATCH] another r...
313
314
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
317
  			break;
  		}
  		if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
318
  			wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
319
   			kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
321
  		pipe_wait(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
  	}
ebec73f47   Al Viro   introduce variant...
323
  	__pipe_unlock(pipe);
341b446bc   Ingo Molnar   [PATCH] another r...
324
325
  
  	/* Signal writers asynchronously that there is more room. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
  	if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
327
  		wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
328
  		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
330
331
332
333
  	}
  	if (ret > 0)
  		file_accessed(filp);
  	return ret;
  }
9883035ae   Linus Torvalds   pipes: add a "pac...
334
335
336
337
  static inline int is_packetized(struct file *file)
  {
  	return (file->f_flags & O_DIRECT) != 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
  static ssize_t
f0d1bec9d   Al Viro   new helper: copy_...
339
  pipe_write(struct kiocb *iocb, struct iov_iter *from)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
  {
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
341
  	struct file *filp = iocb->ki_filp;
de32ec4cf   Al Viro   pipe: set file->p...
342
  	struct pipe_inode_info *pipe = filp->private_data;
f0d1bec9d   Al Viro   new helper: copy_...
343
344
345
  	ssize_t ret = 0;
  	int do_wakeup = 0;
  	size_t total_len = iov_iter_count(from);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
  	ssize_t chars;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
348
349
  	/* Null write succeeds. */
  	if (unlikely(total_len == 0))
  		return 0;
ebec73f47   Al Viro   introduce variant...
350
  	__pipe_lock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
352
  	if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
354
355
356
357
358
359
  		send_sig(SIGPIPE, current, 0);
  		ret = -EPIPE;
  		goto out;
  	}
  
  	/* We try to merge small writes */
  	chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
360
  	if (pipe->nrbufs && chars != 0) {
341b446bc   Ingo Molnar   [PATCH] another r...
361
  		int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
35f3d14db   Jens Axboe   pipe: add support...
362
  							(pipe->buffers - 1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
363
  		struct pipe_buffer *buf = pipe->bufs + lastbuf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
  		int offset = buf->offset + buf->len;
341b446bc   Ingo Molnar   [PATCH] another r...
365

fba597db4   Miklos Szeredi   pipe: add pipe_bu...
366
367
  		if (buf->ops->can_merge && offset + chars <= PAGE_SIZE) {
  			ret = pipe_buf_confirm(pipe, buf);
6ae080699   Eric Biggers   fs/pipe.c: return...
368
  			if (ret)
5274f052e   Jens Axboe   [PATCH] Introduce...
369
  				goto out;
f84d75199   Jens Axboe   [PATCH] pipe: int...
370

f0d1bec9d   Al Viro   new helper: copy_...
371
372
  			ret = copy_page_from_iter(buf->page, offset, chars, from);
  			if (unlikely(ret < chars)) {
6ae080699   Eric Biggers   fs/pipe.c: return...
373
  				ret = -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
  				goto out;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
375
  			}
f0d1bec9d   Al Viro   new helper: copy_...
376
  			do_wakeup = 1;
6ae080699   Eric Biggers   fs/pipe.c: return...
377
  			buf->len += ret;
f0d1bec9d   Al Viro   new helper: copy_...
378
  			if (!iov_iter_count(from))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
380
381
382
383
384
  				goto out;
  		}
  	}
  
  	for (;;) {
  		int bufs;
341b446bc   Ingo Molnar   [PATCH] another r...
385

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
386
  		if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
  			send_sig(SIGPIPE, current, 0);
341b446bc   Ingo Molnar   [PATCH] another r...
388
389
  			if (!ret)
  				ret = -EPIPE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
391
  			break;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
392
  		bufs = pipe->nrbufs;
35f3d14db   Jens Axboe   pipe: add support...
393
394
  		if (bufs < pipe->buffers) {
  			int newbuf = (pipe->curbuf + bufs) & (pipe->buffers-1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
395
396
  			struct pipe_buffer *buf = pipe->bufs + newbuf;
  			struct page *page = pipe->tmp_page;
f0d1bec9d   Al Viro   new helper: copy_...
397
  			int copied;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
399
  
  			if (!page) {
d86133bd3   Vladimir Davydov   pipe: account to ...
400
  				page = alloc_page(GFP_HIGHUSER | __GFP_ACCOUNT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
404
  				if (unlikely(!page)) {
  					ret = ret ? : -ENOMEM;
  					break;
  				}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
405
  				pipe->tmp_page = page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
  			}
341b446bc   Ingo Molnar   [PATCH] another r...
407
  			/* Always wake up, even if the copy fails. Otherwise
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
409
410
411
412
  			 * we lock up (O_NONBLOCK-)readers that sleep due to
  			 * syscall merging.
  			 * FIXME! Is this really true?
  			 */
  			do_wakeup = 1;
f0d1bec9d   Al Viro   new helper: copy_...
413
414
  			copied = copy_page_from_iter(page, 0, PAGE_SIZE, from);
  			if (unlikely(copied < PAGE_SIZE && iov_iter_count(from))) {
341b446bc   Ingo Molnar   [PATCH] another r...
415
  				if (!ret)
f0d1bec9d   Al Viro   new helper: copy_...
416
  					ret = -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417
418
  				break;
  			}
f0d1bec9d   Al Viro   new helper: copy_...
419
  			ret += copied;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
421
422
423
424
  
  			/* Insert it into the buffer array */
  			buf->page = page;
  			buf->ops = &anon_pipe_buf_ops;
  			buf->offset = 0;
f0d1bec9d   Al Viro   new helper: copy_...
425
  			buf->len = copied;
9883035ae   Linus Torvalds   pipes: add a "pac...
426
427
428
429
430
  			buf->flags = 0;
  			if (is_packetized(filp)) {
  				buf->ops = &packet_pipe_buf_ops;
  				buf->flags = PIPE_BUF_FLAG_PACKET;
  			}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
431
432
  			pipe->nrbufs = ++bufs;
  			pipe->tmp_page = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433

f0d1bec9d   Al Viro   new helper: copy_...
434
  			if (!iov_iter_count(from))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
436
  				break;
  		}
35f3d14db   Jens Axboe   pipe: add support...
437
  		if (bufs < pipe->buffers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
439
  			continue;
  		if (filp->f_flags & O_NONBLOCK) {
341b446bc   Ingo Molnar   [PATCH] another r...
440
441
  			if (!ret)
  				ret = -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
443
444
  			break;
  		}
  		if (signal_pending(current)) {
341b446bc   Ingo Molnar   [PATCH] another r...
445
446
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
448
449
  			break;
  		}
  		if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
450
  			wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
451
  			kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
452
453
  			do_wakeup = 0;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
454
455
456
  		pipe->waiting_writers++;
  		pipe_wait(pipe);
  		pipe->waiting_writers--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
458
  	}
  out:
ebec73f47   Al Viro   introduce variant...
459
  	__pipe_unlock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
  	if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
461
  		wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
462
  		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
  	}
7e775f46a   Dmitry Monakhov   fs/pipe.c: skip f...
464
  	if (ret > 0 && sb_start_write_trylock(file_inode(filp)->i_sb)) {
c3b2da314   Josef Bacik   fs: introduce ino...
465
466
467
  		int err = file_update_time(filp);
  		if (err)
  			ret = err;
7e775f46a   Dmitry Monakhov   fs/pipe.c: skip f...
468
  		sb_end_write(file_inode(filp)->i_sb);
c3b2da314   Josef Bacik   fs: introduce ino...
469
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
470
471
  	return ret;
  }
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
472
  static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
473
  {
de32ec4cf   Al Viro   pipe: set file->p...
474
  	struct pipe_inode_info *pipe = filp->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
476
477
478
  	int count, buf, nrbufs;
  
  	switch (cmd) {
  		case FIONREAD:
ebec73f47   Al Viro   introduce variant...
479
  			__pipe_lock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
  			count = 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
481
482
  			buf = pipe->curbuf;
  			nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
  			while (--nrbufs >= 0) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
484
  				count += pipe->bufs[buf].len;
35f3d14db   Jens Axboe   pipe: add support...
485
  				buf = (buf+1) & (pipe->buffers - 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
486
  			}
ebec73f47   Al Viro   introduce variant...
487
  			__pipe_unlock(pipe);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
488

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
490
  			return put_user(count, (int __user *)arg);
  		default:
46ce341b2   Will Deacon   pipe: return -ENO...
491
  			return -ENOIOCTLCMD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
493
494
495
496
497
498
499
  	}
  }
  
  /* No kernel lock held - fine */
  static unsigned int
  pipe_poll(struct file *filp, poll_table *wait)
  {
  	unsigned int mask;
de32ec4cf   Al Viro   pipe: set file->p...
500
  	struct pipe_inode_info *pipe = filp->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
  	int nrbufs;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
502
  	poll_wait(filp, &pipe->wait, wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
504
  
  	/* Reading only -- no need for acquiring the semaphore.  */
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
505
  	nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
507
508
  	mask = 0;
  	if (filp->f_mode & FMODE_READ) {
  		mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
509
  		if (!pipe->writers && filp->f_version != pipe->w_counter)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
511
512
513
  			mask |= POLLHUP;
  	}
  
  	if (filp->f_mode & FMODE_WRITE) {
35f3d14db   Jens Axboe   pipe: add support...
514
  		mask |= (nrbufs < pipe->buffers) ? POLLOUT | POLLWRNORM : 0;
5e5d7a222   Pekka Enberg   [PATCH] pipe: rem...
515
516
517
518
  		/*
  		 * Most Unices do not set POLLERR for FIFOs but on Linux they
  		 * behave exactly like pipes for poll().
  		 */
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
519
  		if (!pipe->readers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
521
522
523
524
  			mask |= POLLERR;
  	}
  
  	return mask;
  }
b0d8d2292   Linus Torvalds   vfs: fix subtle u...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
  static void put_pipe_info(struct inode *inode, struct pipe_inode_info *pipe)
  {
  	int kill = 0;
  
  	spin_lock(&inode->i_lock);
  	if (!--pipe->files) {
  		inode->i_pipe = NULL;
  		kill = 1;
  	}
  	spin_unlock(&inode->i_lock);
  
  	if (kill)
  		free_pipe_info(pipe);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
  static int
599a0ac14   Al Viro   pipe: fold file_o...
540
  pipe_release(struct inode *inode, struct file *file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
  {
b0d8d2292   Linus Torvalds   vfs: fix subtle u...
542
  	struct pipe_inode_info *pipe = file->private_data;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
543

ebec73f47   Al Viro   introduce variant...
544
  	__pipe_lock(pipe);
599a0ac14   Al Viro   pipe: fold file_o...
545
546
547
548
  	if (file->f_mode & FMODE_READ)
  		pipe->readers--;
  	if (file->f_mode & FMODE_WRITE)
  		pipe->writers--;
341b446bc   Ingo Molnar   [PATCH] another r...
549

ba5bb1473   Al Viro   pipe: take alloca...
550
  	if (pipe->readers || pipe->writers) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
551
  		wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM | POLLERR | POLLHUP);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
552
553
  		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
  		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
554
  	}
ebec73f47   Al Viro   introduce variant...
555
  	__pipe_unlock(pipe);
ba5bb1473   Al Viro   pipe: take alloca...
556

b0d8d2292   Linus Torvalds   vfs: fix subtle u...
557
  	put_pipe_info(inode, pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
559
560
561
  	return 0;
  }
  
  static int
599a0ac14   Al Viro   pipe: fold file_o...
562
  pipe_fasync(int fd, struct file *filp, int on)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
  {
de32ec4cf   Al Viro   pipe: set file->p...
564
  	struct pipe_inode_info *pipe = filp->private_data;
599a0ac14   Al Viro   pipe: fold file_o...
565
  	int retval = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566

ebec73f47   Al Viro   introduce variant...
567
  	__pipe_lock(pipe);
599a0ac14   Al Viro   pipe: fold file_o...
568
569
570
  	if (filp->f_mode & FMODE_READ)
  		retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
  	if ((filp->f_mode & FMODE_WRITE) && retval >= 0) {
341b446bc   Ingo Molnar   [PATCH] another r...
571
  		retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
599a0ac14   Al Viro   pipe: fold file_o...
572
573
  		if (retval < 0 && (filp->f_mode & FMODE_READ))
  			/* this can happen only if on == T */
e5bc49ba7   Oleg Nesterov   pipe_rdwr_fasync:...
574
575
  			fasync_helper(-1, filp, 0, &pipe->fasync_readers);
  	}
ebec73f47   Al Viro   introduce variant...
576
  	__pipe_unlock(pipe);
60aa49243   Jonathan Corbet   Rationalize fasyn...
577
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
578
  }
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
579
  static unsigned long account_pipe_buffers(struct user_struct *user,
759c01142   Willy Tarreau   pipe: limit the p...
580
581
                                   unsigned long old, unsigned long new)
  {
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
582
  	return atomic_long_add_return(new - old, &user->pipe_bufs);
759c01142   Willy Tarreau   pipe: limit the p...
583
  }
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
584
  static bool too_many_pipe_buffers_soft(unsigned long user_bufs)
759c01142   Willy Tarreau   pipe: limit the p...
585
  {
703b37d84   Eric Biggers   pipe: fix off-by-...
586
  	return pipe_user_pages_soft && user_bufs > pipe_user_pages_soft;
759c01142   Willy Tarreau   pipe: limit the p...
587
  }
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
588
  static bool too_many_pipe_buffers_hard(unsigned long user_bufs)
759c01142   Willy Tarreau   pipe: limit the p...
589
  {
703b37d84   Eric Biggers   pipe: fix off-by-...
590
  	return pipe_user_pages_hard && user_bufs > pipe_user_pages_hard;
759c01142   Willy Tarreau   pipe: limit the p...
591
  }
a125e9a42   Eric Biggers   pipe: actually al...
592
593
594
595
  static bool is_unprivileged_user(void)
  {
  	return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
  }
7bee130e2   Al Viro   get rid of alloc_...
596
  struct pipe_inode_info *alloc_pipe_info(void)
3a326a2ce   Ingo Molnar   [PATCH] introduce...
597
  {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
598
  	struct pipe_inode_info *pipe;
09b4d1990   Michael Kerrisk (man-pages)   pipe: simplify lo...
599
600
  	unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
  	struct user_struct *user = get_current_user();
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
601
  	unsigned long user_bufs;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
602

d86133bd3   Vladimir Davydov   pipe: account to ...
603
  	pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL_ACCOUNT);
09b4d1990   Michael Kerrisk (man-pages)   pipe: simplify lo...
604
605
  	if (pipe == NULL)
  		goto out_free_uid;
086e774a5   Michael Kerrisk (man-pages)   pipe: cap initial...
606
607
  	if (pipe_bufs * PAGE_SIZE > pipe_max_size && !capable(CAP_SYS_RESOURCE))
  		pipe_bufs = pipe_max_size >> PAGE_SHIFT;
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
608
  	user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
a005ca0e6   Michael Kerrisk (man-pages)   pipe: fix limit c...
609

a125e9a42   Eric Biggers   pipe: actually al...
610
  	if (too_many_pipe_buffers_soft(user_bufs) && is_unprivileged_user()) {
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
611
  		user_bufs = account_pipe_buffers(user, pipe_bufs, 1);
a005ca0e6   Michael Kerrisk (man-pages)   pipe: fix limit c...
612
  		pipe_bufs = 1;
09b4d1990   Michael Kerrisk (man-pages)   pipe: simplify lo...
613
  	}
759c01142   Willy Tarreau   pipe: limit the p...
614

a125e9a42   Eric Biggers   pipe: actually al...
615
  	if (too_many_pipe_buffers_hard(user_bufs) && is_unprivileged_user())
a005ca0e6   Michael Kerrisk (man-pages)   pipe: fix limit c...
616
617
618
619
  		goto out_revert_acct;
  
  	pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer),
  			     GFP_KERNEL_ACCOUNT);
09b4d1990   Michael Kerrisk (man-pages)   pipe: simplify lo...
620
621
622
623
624
  	if (pipe->bufs) {
  		init_waitqueue_head(&pipe->wait);
  		pipe->r_counter = pipe->w_counter = 1;
  		pipe->buffers = pipe_bufs;
  		pipe->user = user;
09b4d1990   Michael Kerrisk (man-pages)   pipe: simplify lo...
625
626
  		mutex_init(&pipe->mutex);
  		return pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
627
  	}
a005ca0e6   Michael Kerrisk (man-pages)   pipe: fix limit c...
628
  out_revert_acct:
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
629
  	(void) account_pipe_buffers(user, pipe_bufs, 0);
09b4d1990   Michael Kerrisk (man-pages)   pipe: simplify lo...
630
631
632
  	kfree(pipe);
  out_free_uid:
  	free_uid(user);
35f3d14db   Jens Axboe   pipe: add support...
633
  	return NULL;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
634
  }
4b8a8f1e4   Al Viro   get rid of the la...
635
  void free_pipe_info(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
637
  {
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638

9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
639
  	(void) account_pipe_buffers(pipe->user, pipe->buffers, 0);
759c01142   Willy Tarreau   pipe: limit the p...
640
  	free_uid(pipe->user);
35f3d14db   Jens Axboe   pipe: add support...
641
  	for (i = 0; i < pipe->buffers; i++) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
642
  		struct pipe_buffer *buf = pipe->bufs + i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643
  		if (buf->ops)
a779638cf   Miklos Szeredi   pipe: add pipe_bu...
644
  			pipe_buf_release(pipe, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
645
  	}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
646
647
  	if (pipe->tmp_page)
  		__free_page(pipe->tmp_page);
35f3d14db   Jens Axboe   pipe: add support...
648
  	kfree(pipe->bufs);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
649
  	kfree(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
  }
fa3536cc1   Eric Dumazet   [PATCH] Use __rea...
651
  static struct vfsmount *pipe_mnt __read_mostly;
341b446bc   Ingo Molnar   [PATCH] another r...
652

c23fbb6bc   Eric Dumazet   VFS: delay the de...
653
654
655
656
657
658
  /*
   * pipefs_dname() is called from d_path().
   */
  static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen)
  {
  	return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
75c3cfa85   David Howells   VFS: assorted wei...
659
  				d_inode(dentry)->i_ino);
c23fbb6bc   Eric Dumazet   VFS: delay the de...
660
  }
3ba13d179   Al Viro   constify dentry_o...
661
  static const struct dentry_operations pipefs_dentry_operations = {
c23fbb6bc   Eric Dumazet   VFS: delay the de...
662
  	.d_dname	= pipefs_dname,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
663
664
665
666
  };
  
  static struct inode * get_pipe_inode(void)
  {
a209dfc7b   Eric Dumazet   vfs: dont chain p...
667
  	struct inode *inode = new_inode_pseudo(pipe_mnt->mnt_sb);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
668
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
669
670
671
  
  	if (!inode)
  		goto fail_inode;
85fe4025c   Christoph Hellwig   fs: do not assign...
672
  	inode->i_ino = get_next_ino();
7bee130e2   Al Viro   get rid of alloc_...
673
  	pipe = alloc_pipe_info();
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
674
  	if (!pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
675
  		goto fail_iput;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
676

ba5bb1473   Al Viro   pipe: take alloca...
677
678
  	inode->i_pipe = pipe;
  	pipe->files = 2;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
679
  	pipe->readers = pipe->writers = 1;
599a0ac14   Al Viro   pipe: fold file_o...
680
  	inode->i_fop = &pipefifo_fops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
682
683
684
685
686
687
688
689
  
  	/*
  	 * Mark the inode dirty from the very beginning,
  	 * that way it will never be moved to the dirty
  	 * list because "mark_inode_dirty()" will think
  	 * that it already _is_ on the dirty list.
  	 */
  	inode->i_state = I_DIRTY;
  	inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR;
da9592ede   David Howells   CRED: Wrap task c...
690
691
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
078cd8279   Deepa Dinamani   fs: Replace CURRE...
692
  	inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
693

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
694
695
696
697
  	return inode;
  
  fail_iput:
  	iput(inode);
341b446bc   Ingo Molnar   [PATCH] another r...
698

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
699
700
701
  fail_inode:
  	return NULL;
  }
e4fad8e5d   Al Viro   consolidate pipe ...
702
  int create_pipe_files(struct file **res, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703
  {
d6cbd281d   Andi Kleen   [PATCH] Some clea...
704
  	int err;
e4fad8e5d   Al Viro   consolidate pipe ...
705
  	struct inode *inode = get_pipe_inode();
d6cbd281d   Andi Kleen   [PATCH] Some clea...
706
  	struct file *f;
2c48b9c45   Al Viro   switch alloc_file...
707
  	struct path path;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
709
  	if (!inode)
e4fad8e5d   Al Viro   consolidate pipe ...
710
  		return -ENFILE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
711

d6cbd281d   Andi Kleen   [PATCH] Some clea...
712
  	err = -ENOMEM;
cdf01226b   David Howells   VFS: Provide empt...
713
  	path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &empty_name);
2c48b9c45   Al Viro   switch alloc_file...
714
  	if (!path.dentry)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
715
  		goto err_inode;
2c48b9c45   Al Viro   switch alloc_file...
716
  	path.mnt = mntget(pipe_mnt);
341b446bc   Ingo Molnar   [PATCH] another r...
717

2c48b9c45   Al Viro   switch alloc_file...
718
  	d_instantiate(path.dentry, inode);
430e285e0   Dave Hansen   [PATCH] fix up ne...
719

599a0ac14   Al Viro   pipe: fold file_o...
720
  	f = alloc_file(&path, FMODE_WRITE, &pipefifo_fops);
e9bb1f9b1   Eric Biggers   fs/pipe.c: preser...
721
722
  	if (IS_ERR(f)) {
  		err = PTR_ERR(f);
430e285e0   Dave Hansen   [PATCH] fix up ne...
723
  		goto err_dentry;
e9bb1f9b1   Eric Biggers   fs/pipe.c: preser...
724
  	}
341b446bc   Ingo Molnar   [PATCH] another r...
725

9883035ae   Linus Torvalds   pipes: add a "pac...
726
  	f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
de32ec4cf   Al Viro   pipe: set file->p...
727
  	f->private_data = inode->i_pipe;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
728

599a0ac14   Al Viro   pipe: fold file_o...
729
  	res[0] = alloc_file(&path, FMODE_READ, &pipefifo_fops);
e9bb1f9b1   Eric Biggers   fs/pipe.c: preser...
730
731
  	if (IS_ERR(res[0])) {
  		err = PTR_ERR(res[0]);
e4fad8e5d   Al Viro   consolidate pipe ...
732
  		goto err_file;
e9bb1f9b1   Eric Biggers   fs/pipe.c: preser...
733
  	}
e4fad8e5d   Al Viro   consolidate pipe ...
734
735
  
  	path_get(&path);
de32ec4cf   Al Viro   pipe: set file->p...
736
  	res[0]->private_data = inode->i_pipe;
e4fad8e5d   Al Viro   consolidate pipe ...
737
738
739
  	res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK);
  	res[1] = f;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
740

e4fad8e5d   Al Viro   consolidate pipe ...
741
742
743
  err_file:
  	put_filp(f);
  err_dentry:
4b8a8f1e4   Al Viro   get rid of the la...
744
  	free_pipe_info(inode->i_pipe);
2c48b9c45   Al Viro   switch alloc_file...
745
  	path_put(&path);
e4fad8e5d   Al Viro   consolidate pipe ...
746
  	return err;
ed1524371   Al Viro   [PATCH] double-fr...
747

e4fad8e5d   Al Viro   consolidate pipe ...
748
  err_inode:
4b8a8f1e4   Al Viro   get rid of the la...
749
  	free_pipe_info(inode->i_pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750
  	iput(inode);
e4fad8e5d   Al Viro   consolidate pipe ...
751
  	return err;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
752
  }
5b249b1b0   Al Viro   pipe(2) - race-fr...
753
  static int __do_pipe_flags(int *fd, struct file **files, int flags)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
754
  {
d6cbd281d   Andi Kleen   [PATCH] Some clea...
755
756
  	int error;
  	int fdw, fdr;
9883035ae   Linus Torvalds   pipes: add a "pac...
757
  	if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
ed8cae8ba   Ulrich Drepper   flag parameters: ...
758
  		return -EINVAL;
e4fad8e5d   Al Viro   consolidate pipe ...
759
760
761
  	error = create_pipe_files(files, flags);
  	if (error)
  		return error;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
762

ed8cae8ba   Ulrich Drepper   flag parameters: ...
763
  	error = get_unused_fd_flags(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
764
765
766
  	if (error < 0)
  		goto err_read_pipe;
  	fdr = error;
ed8cae8ba   Ulrich Drepper   flag parameters: ...
767
  	error = get_unused_fd_flags(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
768
769
770
  	if (error < 0)
  		goto err_fdr;
  	fdw = error;
157cf649a   Al Viro   sanitize audit_fd...
771
  	audit_fd_pair(fdr, fdw);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
772
773
  	fd[0] = fdr;
  	fd[1] = fdw;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
774
775
776
777
778
  	return 0;
  
   err_fdr:
  	put_unused_fd(fdr);
   err_read_pipe:
e4fad8e5d   Al Viro   consolidate pipe ...
779
780
  	fput(files[0]);
  	fput(files[1]);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
781
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
782
  }
5b249b1b0   Al Viro   pipe(2) - race-fr...
783
784
785
786
787
788
789
790
791
792
  int do_pipe_flags(int *fd, int flags)
  {
  	struct file *files[2];
  	int error = __do_pipe_flags(fd, files, flags);
  	if (!error) {
  		fd_install(fd[0], files[0]);
  		fd_install(fd[1], files[1]);
  	}
  	return error;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
793
  /*
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
794
795
796
   * sys_pipe() is the normal C calling standard for creating
   * a pipe. It's not the way Unix traditionally does this, though.
   */
d4e82042c   Heiko Carstens   [CVE-2009-0029] S...
797
  SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
798
  {
5b249b1b0   Al Viro   pipe(2) - race-fr...
799
  	struct file *files[2];
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
800
801
  	int fd[2];
  	int error;
5b249b1b0   Al Viro   pipe(2) - race-fr...
802
  	error = __do_pipe_flags(fd, files, flags);
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
803
  	if (!error) {
5b249b1b0   Al Viro   pipe(2) - race-fr...
804
805
806
807
808
  		if (unlikely(copy_to_user(fildes, fd, sizeof(fd)))) {
  			fput(files[0]);
  			fput(files[1]);
  			put_unused_fd(fd[0]);
  			put_unused_fd(fd[1]);
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
809
  			error = -EFAULT;
5b249b1b0   Al Viro   pipe(2) - race-fr...
810
811
812
  		} else {
  			fd_install(fd[0], files[0]);
  			fd_install(fd[1], files[1]);
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
813
  		}
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
814
815
816
  	}
  	return error;
  }
2b6642199   Heiko Carstens   [CVE-2009-0029] S...
817
  SYSCALL_DEFINE1(pipe, int __user *, fildes)
ed8cae8ba   Ulrich Drepper   flag parameters: ...
818
819
820
  {
  	return sys_pipe2(fildes, 0);
  }
fc7478a2b   Al Viro   pipe: switch wait...
821
  static int wait_for_partner(struct pipe_inode_info *pipe, unsigned int *cnt)
f776c7388   Al Viro   fold fifo.c into ...
822
823
824
825
  {
  	int cur = *cnt;	
  
  	while (cur == *cnt) {
fc7478a2b   Al Viro   pipe: switch wait...
826
  		pipe_wait(pipe);
f776c7388   Al Viro   fold fifo.c into ...
827
828
829
830
831
  		if (signal_pending(current))
  			break;
  	}
  	return cur == *cnt ? -ERESTARTSYS : 0;
  }
fc7478a2b   Al Viro   pipe: switch wait...
832
  static void wake_up_partner(struct pipe_inode_info *pipe)
f776c7388   Al Viro   fold fifo.c into ...
833
  {
fc7478a2b   Al Viro   pipe: switch wait...
834
  	wake_up_interruptible(&pipe->wait);
f776c7388   Al Viro   fold fifo.c into ...
835
836
837
838
839
  }
  
  static int fifo_open(struct inode *inode, struct file *filp)
  {
  	struct pipe_inode_info *pipe;
599a0ac14   Al Viro   pipe: fold file_o...
840
  	bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC;
f776c7388   Al Viro   fold fifo.c into ...
841
  	int ret;
ba5bb1473   Al Viro   pipe: take alloca...
842
843
844
845
846
847
848
849
850
  	filp->f_version = 0;
  
  	spin_lock(&inode->i_lock);
  	if (inode->i_pipe) {
  		pipe = inode->i_pipe;
  		pipe->files++;
  		spin_unlock(&inode->i_lock);
  	} else {
  		spin_unlock(&inode->i_lock);
7bee130e2   Al Viro   get rid of alloc_...
851
  		pipe = alloc_pipe_info();
f776c7388   Al Viro   fold fifo.c into ...
852
  		if (!pipe)
ba5bb1473   Al Viro   pipe: take alloca...
853
854
855
856
857
858
  			return -ENOMEM;
  		pipe->files = 1;
  		spin_lock(&inode->i_lock);
  		if (unlikely(inode->i_pipe)) {
  			inode->i_pipe->files++;
  			spin_unlock(&inode->i_lock);
4b8a8f1e4   Al Viro   get rid of the la...
859
  			free_pipe_info(pipe);
ba5bb1473   Al Viro   pipe: take alloca...
860
861
862
863
864
  			pipe = inode->i_pipe;
  		} else {
  			inode->i_pipe = pipe;
  			spin_unlock(&inode->i_lock);
  		}
f776c7388   Al Viro   fold fifo.c into ...
865
  	}
de32ec4cf   Al Viro   pipe: set file->p...
866
  	filp->private_data = pipe;
ba5bb1473   Al Viro   pipe: take alloca...
867
  	/* OK, we have a pipe and it's pinned down */
ebec73f47   Al Viro   introduce variant...
868
  	__pipe_lock(pipe);
f776c7388   Al Viro   fold fifo.c into ...
869
870
871
872
873
874
875
876
877
878
879
  
  	/* We can only do regular read/write on fifos */
  	filp->f_mode &= (FMODE_READ | FMODE_WRITE);
  
  	switch (filp->f_mode) {
  	case FMODE_READ:
  	/*
  	 *  O_RDONLY
  	 *  POSIX.1 says that O_NONBLOCK means return with the FIFO
  	 *  opened, even when there is no process writing the FIFO.
  	 */
f776c7388   Al Viro   fold fifo.c into ...
880
881
  		pipe->r_counter++;
  		if (pipe->readers++ == 0)
fc7478a2b   Al Viro   pipe: switch wait...
882
  			wake_up_partner(pipe);
f776c7388   Al Viro   fold fifo.c into ...
883

599a0ac14   Al Viro   pipe: fold file_o...
884
  		if (!is_pipe && !pipe->writers) {
f776c7388   Al Viro   fold fifo.c into ...
885
886
887
888
889
  			if ((filp->f_flags & O_NONBLOCK)) {
  				/* suppress POLLHUP until we have
  				 * seen a writer */
  				filp->f_version = pipe->w_counter;
  			} else {
fc7478a2b   Al Viro   pipe: switch wait...
890
  				if (wait_for_partner(pipe, &pipe->w_counter))
f776c7388   Al Viro   fold fifo.c into ...
891
892
893
894
895
896
897
898
899
900
901
902
  					goto err_rd;
  			}
  		}
  		break;
  	
  	case FMODE_WRITE:
  	/*
  	 *  O_WRONLY
  	 *  POSIX.1 says that O_NONBLOCK means return -1 with
  	 *  errno=ENXIO when there is no process reading the FIFO.
  	 */
  		ret = -ENXIO;
599a0ac14   Al Viro   pipe: fold file_o...
903
  		if (!is_pipe && (filp->f_flags & O_NONBLOCK) && !pipe->readers)
f776c7388   Al Viro   fold fifo.c into ...
904
  			goto err;
f776c7388   Al Viro   fold fifo.c into ...
905
906
  		pipe->w_counter++;
  		if (!pipe->writers++)
fc7478a2b   Al Viro   pipe: switch wait...
907
  			wake_up_partner(pipe);
f776c7388   Al Viro   fold fifo.c into ...
908

599a0ac14   Al Viro   pipe: fold file_o...
909
  		if (!is_pipe && !pipe->readers) {
fc7478a2b   Al Viro   pipe: switch wait...
910
  			if (wait_for_partner(pipe, &pipe->r_counter))
f776c7388   Al Viro   fold fifo.c into ...
911
912
913
914
915
916
917
918
919
920
921
  				goto err_wr;
  		}
  		break;
  	
  	case FMODE_READ | FMODE_WRITE:
  	/*
  	 *  O_RDWR
  	 *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
  	 *  This implementation will NEVER block on a O_RDWR open, since
  	 *  the process can at least talk to itself.
  	 */
f776c7388   Al Viro   fold fifo.c into ...
922
923
924
925
926
927
  
  		pipe->readers++;
  		pipe->writers++;
  		pipe->r_counter++;
  		pipe->w_counter++;
  		if (pipe->readers == 1 || pipe->writers == 1)
fc7478a2b   Al Viro   pipe: switch wait...
928
  			wake_up_partner(pipe);
f776c7388   Al Viro   fold fifo.c into ...
929
930
931
932
933
934
935
936
  		break;
  
  	default:
  		ret = -EINVAL;
  		goto err;
  	}
  
  	/* Ok! */
ebec73f47   Al Viro   introduce variant...
937
  	__pipe_unlock(pipe);
f776c7388   Al Viro   fold fifo.c into ...
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
  	return 0;
  
  err_rd:
  	if (!--pipe->readers)
  		wake_up_interruptible(&pipe->wait);
  	ret = -ERESTARTSYS;
  	goto err;
  
  err_wr:
  	if (!--pipe->writers)
  		wake_up_interruptible(&pipe->wait);
  	ret = -ERESTARTSYS;
  	goto err;
  
  err:
ebec73f47   Al Viro   introduce variant...
953
  	__pipe_unlock(pipe);
b0d8d2292   Linus Torvalds   vfs: fix subtle u...
954
955
  
  	put_pipe_info(inode, pipe);
f776c7388   Al Viro   fold fifo.c into ...
956
957
  	return ret;
  }
599a0ac14   Al Viro   pipe: fold file_o...
958
959
960
  const struct file_operations pipefifo_fops = {
  	.open		= fifo_open,
  	.llseek		= no_llseek,
fb9096a34   Al Viro   pipe: switch to -...
961
  	.read_iter	= pipe_read,
f0d1bec9d   Al Viro   new helper: copy_...
962
  	.write_iter	= pipe_write,
599a0ac14   Al Viro   pipe: fold file_o...
963
964
965
966
  	.poll		= pipe_poll,
  	.unlocked_ioctl	= pipe_ioctl,
  	.release	= pipe_release,
  	.fasync		= pipe_fasync,
f776c7388   Al Viro   fold fifo.c into ...
967
  };
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
968
  /*
f491bd711   Michael Kerrisk (man-pages)   pipe: relocate ro...
969
   * Currently we rely on the pipe array holding a power-of-2 number
e109607e1   Joe Lawrence   pipe: avoid round...
970
   * of pages. Returns 0 on error.
f491bd711   Michael Kerrisk (man-pages)   pipe: relocate ro...
971
972
973
974
   */
  static inline unsigned int round_pipe_size(unsigned int size)
  {
  	unsigned long nr_pages;
e109607e1   Joe Lawrence   pipe: avoid round...
975
976
  	if (size < pipe_min_size)
  		size = pipe_min_size;
f491bd711   Michael Kerrisk (man-pages)   pipe: relocate ro...
977
  	nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
e109607e1   Joe Lawrence   pipe: avoid round...
978
979
  	if (nr_pages == 0)
  		return 0;
f491bd711   Michael Kerrisk (man-pages)   pipe: relocate ro...
980
981
982
983
  	return roundup_pow_of_two(nr_pages) << PAGE_SHIFT;
  }
  
  /*
35f3d14db   Jens Axboe   pipe: add support...
984
985
986
   * Allocate a new array of pipe buffers and copy the info over. Returns the
   * pipe size if successful, or return -ERROR on error.
   */
d37d41666   Michael Kerrisk (man-pages)   pipe: move limit ...
987
  static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
35f3d14db   Jens Axboe   pipe: add support...
988
989
  {
  	struct pipe_buffer *bufs;
d37d41666   Michael Kerrisk (man-pages)   pipe: move limit ...
990
  	unsigned int size, nr_pages;
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
991
  	unsigned long user_bufs;
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
992
  	long ret = 0;
d37d41666   Michael Kerrisk (man-pages)   pipe: move limit ...
993
994
  
  	size = round_pipe_size(arg);
e109607e1   Joe Lawrence   pipe: avoid round...
995
996
  	if (size == 0)
  		return -EINVAL;
d37d41666   Michael Kerrisk (man-pages)   pipe: move limit ...
997
998
999
1000
  	nr_pages = size >> PAGE_SHIFT;
  
  	if (!nr_pages)
  		return -EINVAL;
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1001
1002
1003
1004
1005
1006
1007
1008
1009
  	/*
  	 * If trying to increase the pipe capacity, check that an
  	 * unprivileged user is not trying to exceed various limits
  	 * (soft limit check here, hard limit check just below).
  	 * Decreasing the pipe capacity is always permitted, even
  	 * if the user is currently over a limit.
  	 */
  	if (nr_pages > pipe->buffers &&
  			size > pipe_max_size && !capable(CAP_SYS_RESOURCE))
d37d41666   Michael Kerrisk (man-pages)   pipe: move limit ...
1010
  		return -EPERM;
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
1011
  	user_bufs = account_pipe_buffers(pipe->user, pipe->buffers, nr_pages);
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1012
1013
  
  	if (nr_pages > pipe->buffers &&
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
1014
1015
  			(too_many_pipe_buffers_hard(user_bufs) ||
  			 too_many_pipe_buffers_soft(user_bufs)) &&
a125e9a42   Eric Biggers   pipe: actually al...
1016
  			is_unprivileged_user()) {
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1017
1018
1019
  		ret = -EPERM;
  		goto out_revert_acct;
  	}
35f3d14db   Jens Axboe   pipe: add support...
1020
1021
  
  	/*
35f3d14db   Jens Axboe   pipe: add support...
1022
1023
1024
1025
1026
  	 * We can shrink the pipe, if arg >= pipe->nrbufs. Since we don't
  	 * expect a lot of shrink+grow operations, just free and allocate
  	 * again like we would do for growing. If the pipe currently
  	 * contains more buffers than arg, then return busy.
  	 */
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1027
1028
1029
1030
  	if (nr_pages < pipe->nrbufs) {
  		ret = -EBUSY;
  		goto out_revert_acct;
  	}
35f3d14db   Jens Axboe   pipe: add support...
1031

d86133bd3   Vladimir Davydov   pipe: account to ...
1032
1033
  	bufs = kcalloc(nr_pages, sizeof(*bufs),
  		       GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1034
1035
1036
1037
  	if (unlikely(!bufs)) {
  		ret = -ENOMEM;
  		goto out_revert_acct;
  	}
35f3d14db   Jens Axboe   pipe: add support...
1038
1039
1040
1041
1042
1043
  
  	/*
  	 * The pipe array wraps around, so just start the new one at zero
  	 * and adjust the indexes.
  	 */
  	if (pipe->nrbufs) {
1d862f412   Miklos Szeredi   pipe: fix pipe bu...
1044
1045
  		unsigned int tail;
  		unsigned int head;
35f3d14db   Jens Axboe   pipe: add support...
1046

1d862f412   Miklos Szeredi   pipe: fix pipe bu...
1047
1048
1049
1050
1051
1052
1053
  		tail = pipe->curbuf + pipe->nrbufs;
  		if (tail < pipe->buffers)
  			tail = 0;
  		else
  			tail &= (pipe->buffers - 1);
  
  		head = pipe->nrbufs - tail;
35f3d14db   Jens Axboe   pipe: add support...
1054
1055
1056
  		if (head)
  			memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer));
  		if (tail)
1d862f412   Miklos Szeredi   pipe: fix pipe bu...
1057
  			memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer));
35f3d14db   Jens Axboe   pipe: add support...
1058
1059
1060
1061
1062
  	}
  
  	pipe->curbuf = 0;
  	kfree(pipe->bufs);
  	pipe->bufs = bufs;
b9598db34   Jens Axboe   pipe: make F_{GET...
1063
1064
  	pipe->buffers = nr_pages;
  	return nr_pages * PAGE_SIZE;
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1065
1066
  
  out_revert_acct:
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
1067
  	(void) account_pipe_buffers(pipe->user, nr_pages, pipe->buffers);
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1068
  	return ret;
35f3d14db   Jens Axboe   pipe: add support...
1069
  }
ff9da691c   Jens Axboe   pipe: change /pro...
1070
  /*
ff9da691c   Jens Axboe   pipe: change /pro...
1071
1072
1073
1074
1075
1076
   * This should work even if CONFIG_PROC_FS isn't set, as proc_dointvec_minmax
   * will return an error.
   */
  int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
  		 size_t *lenp, loff_t *ppos)
  {
e109607e1   Joe Lawrence   pipe: avoid round...
1077
  	unsigned int rounded_pipe_max_size;
ff9da691c   Jens Axboe   pipe: change /pro...
1078
  	int ret;
30c2f774e   Joe Lawrence   pipe: match pipe_...
1079
  	ret = proc_douintvec_minmax(table, write, buf, lenp, ppos);
ff9da691c   Jens Axboe   pipe: change /pro...
1080
1081
  	if (ret < 0 || !write)
  		return ret;
e109607e1   Joe Lawrence   pipe: avoid round...
1082
1083
1084
1085
1086
  	rounded_pipe_max_size = round_pipe_size(pipe_max_size);
  	if (rounded_pipe_max_size == 0)
  		return -EINVAL;
  
  	pipe_max_size = rounded_pipe_max_size;
ff9da691c   Jens Axboe   pipe: change /pro...
1087
1088
  	return ret;
  }
720836465   Linus Torvalds   Un-inline get_pip...
1089
1090
1091
1092
1093
1094
1095
  /*
   * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
   * location, so checking ->i_pipe is not enough to verify that this is a
   * pipe.
   */
  struct pipe_inode_info *get_pipe_info(struct file *file)
  {
de32ec4cf   Al Viro   pipe: set file->p...
1096
  	return file->f_op == &pipefifo_fops ? file->private_data : NULL;
720836465   Linus Torvalds   Un-inline get_pip...
1097
  }
35f3d14db   Jens Axboe   pipe: add support...
1098
1099
1100
1101
  long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
  {
  	struct pipe_inode_info *pipe;
  	long ret;
c66fb3479   Linus Torvalds   Export 'get_pipe_...
1102
  	pipe = get_pipe_info(file);
35f3d14db   Jens Axboe   pipe: add support...
1103
1104
  	if (!pipe)
  		return -EBADF;
ebec73f47   Al Viro   introduce variant...
1105
  	__pipe_lock(pipe);
35f3d14db   Jens Axboe   pipe: add support...
1106
1107
  
  	switch (cmd) {
d37d41666   Michael Kerrisk (man-pages)   pipe: move limit ...
1108
1109
  	case F_SETPIPE_SZ:
  		ret = pipe_set_size(pipe, arg);
35f3d14db   Jens Axboe   pipe: add support...
1110
1111
  		break;
  	case F_GETPIPE_SZ:
b9598db34   Jens Axboe   pipe: make F_{GET...
1112
  		ret = pipe->buffers * PAGE_SIZE;
35f3d14db   Jens Axboe   pipe: add support...
1113
1114
1115
1116
1117
  		break;
  	default:
  		ret = -EINVAL;
  		break;
  	}
ebec73f47   Al Viro   introduce variant...
1118
  	__pipe_unlock(pipe);
35f3d14db   Jens Axboe   pipe: add support...
1119
1120
  	return ret;
  }
ff0c7d15f   Nick Piggin   fs: avoid inode R...
1121
1122
  static const struct super_operations pipefs_ops = {
  	.destroy_inode = free_inode_nonrcu,
d70ef97ba   Pavel Emelyanov   fs/pipe.c: add ->...
1123
  	.statfs = simple_statfs,
ff0c7d15f   Nick Piggin   fs: avoid inode R...
1124
  };
35f3d14db   Jens Axboe   pipe: add support...
1125
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1126
1127
1128
1129
1130
   * pipefs should _never_ be mounted by userland - too much of security hassle,
   * no real gain from having the whole whorehouse mounted. So we don't need
   * any operations on the root directory. However, we need a non-trivial
   * d_name - pipe: will go nicely and kill the special-casing in procfs.
   */
51139adac   Al Viro   convert get_sb_ps...
1131
1132
  static struct dentry *pipefs_mount(struct file_system_type *fs_type,
  			 int flags, const char *dev_name, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1133
  {
c74a1cbb3   Al Viro   pass default dent...
1134
1135
  	return mount_pseudo(fs_type, "pipe:", &pipefs_ops,
  			&pipefs_dentry_operations, PIPEFS_MAGIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1136
1137
1138
1139
  }
  
  static struct file_system_type pipe_fs_type = {
  	.name		= "pipefs",
51139adac   Al Viro   convert get_sb_ps...
1140
  	.mount		= pipefs_mount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1141
1142
1143
1144
1145
1146
  	.kill_sb	= kill_anon_super,
  };
  
  static int __init init_pipe_fs(void)
  {
  	int err = register_filesystem(&pipe_fs_type);
341b446bc   Ingo Molnar   [PATCH] another r...
1147

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1148
1149
1150
1151
1152
1153
1154
1155
1156
  	if (!err) {
  		pipe_mnt = kern_mount(&pipe_fs_type);
  		if (IS_ERR(pipe_mnt)) {
  			err = PTR_ERR(pipe_mnt);
  			unregister_filesystem(&pipe_fs_type);
  		}
  	}
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1157
  fs_initcall(init_pipe_fs);