Blame view

fs/pipe.c 27.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   *  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...
14
  #include <linux/log2.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
  #include <linux/mount.h>
b502bd115   Muthu Kumar   magic.h: move som...
16
  #include <linux/magic.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
  #include <linux/pipe_fs_i.h>
  #include <linux/uio.h>
  #include <linux/highmem.h>
5274f052e   Jens Axboe   [PATCH] Introduce...
20
  #include <linux/pagemap.h>
db3495099   Al Viro   [PATCH] AUDIT_FD_...
21
  #include <linux/audit.h>
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
22
  #include <linux/syscalls.h>
b492e95be   Jens Axboe   pipe: set lower a...
23
  #include <linux/fcntl.h>
d86133bd3   Vladimir Davydov   pipe: account to ...
24
  #include <linux/memcontrol.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
27
  
  #include <asm/uaccess.h>
  #include <asm/ioctls.h>
599a0ac14   Al Viro   pipe: fold file_o...
28
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
  /*
b492e95be   Jens Axboe   pipe: set lower a...
30
   * The max size that a non-root user is allowed to grow the pipe. Can
ff9da691c   Jens Axboe   pipe: change /pro...
31
   * be set by root in /proc/sys/fs/pipe-max-size
b492e95be   Jens Axboe   pipe: set lower a...
32
   */
ff9da691c   Jens Axboe   pipe: change /pro...
33
34
35
36
37
38
  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...
39

759c01142   Willy Tarreau   pipe: limit the p...
40
41
42
43
44
  /* 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...
45
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
49
50
51
52
53
54
55
56
57
58
   * 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...
59
60
  static void pipe_lock_nested(struct pipe_inode_info *pipe, int subclass)
  {
6447a3cf1   Al Viro   get rid of pipe->...
61
  	if (pipe->files)
72b0d9aac   Al Viro   pipe: don't use -...
62
  		mutex_lock_nested(&pipe->mutex, subclass);
61e0d47c3   Miklos Szeredi   splice: add helpe...
63
64
65
66
67
68
69
70
71
72
73
74
75
  }
  
  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->...
76
  	if (pipe->files)
72b0d9aac   Al Viro   pipe: don't use -...
77
  		mutex_unlock(&pipe->mutex);
61e0d47c3   Miklos Szeredi   splice: add helpe...
78
79
  }
  EXPORT_SYMBOL(pipe_unlock);
ebec73f47   Al Viro   introduce variant...
80
81
82
83
84
85
86
87
88
  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...
89
90
91
92
93
94
95
96
97
  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...
98
99
  		pipe_lock_nested(pipe2, I_MUTEX_PARENT);
  		pipe_lock_nested(pipe1, I_MUTEX_CHILD);
61e0d47c3   Miklos Szeredi   splice: add helpe...
100
101
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
  /* Drop the inode semaphore and wait for a pipe event, atomically */
3a326a2ce   Ingo Molnar   [PATCH] introduce...
103
  void pipe_wait(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
  {
  	DEFINE_WAIT(wait);
d79fc0fc6   Ingo Molnar   [PATCH] sched: TA...
106
107
108
109
  	/*
  	 * Pipes are system-local resources, so sleeping on them
  	 * is considered a noninteractive wait:
  	 */
af9272326   Mike Galbraith   sched: cleanup, r...
110
  	prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE);
61e0d47c3   Miklos Szeredi   splice: add helpe...
111
  	pipe_unlock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
  	schedule();
3a326a2ce   Ingo Molnar   [PATCH] introduce...
113
  	finish_wait(&pipe->wait, &wait);
61e0d47c3   Miklos Szeredi   splice: add helpe...
114
  	pipe_lock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115
  }
341b446bc   Ingo Molnar   [PATCH] another r...
116
117
  static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
  				  struct pipe_buffer *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
  {
  	struct page *page = buf->page;
5274f052e   Jens Axboe   [PATCH] Introduce...
120
121
122
  	/*
  	 * 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...
123
  	 * allocation cache. (Otherwise just release our reference to it)
5274f052e   Jens Axboe   [PATCH] Introduce...
124
  	 */
341b446bc   Ingo Molnar   [PATCH] another r...
125
  	if (page_count(page) == 1 && !pipe->tmp_page)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
126
  		pipe->tmp_page = page;
341b446bc   Ingo Molnar   [PATCH] another r...
127
  	else
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
128
  		put_page(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
  }
d86133bd3   Vladimir Davydov   pipe: account to ...
130
131
132
133
134
135
  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...
136
  		if (memcg_kmem_enabled())
d86133bd3   Vladimir Davydov   pipe: account to ...
137
  			memcg_kmem_uncharge(page, 0);
d86133bd3   Vladimir Davydov   pipe: account to ...
138
139
140
141
142
  		__SetPageLocked(page);
  		return 0;
  	}
  	return 1;
  }
0845718da   Jens Axboe   pipe: add documen...
143
  /**
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
144
   * generic_pipe_buf_steal - attempt to take ownership of a &pipe_buffer
0845718da   Jens Axboe   pipe: add documen...
145
146
147
148
   * @pipe:	the pipe that the buffer belongs to
   * @buf:	the buffer to attempt to steal
   *
   * Description:
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
149
   *	This function attempts to steal the &struct page attached to
0845718da   Jens Axboe   pipe: add documen...
150
151
   *	@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...
152
   *	he wishes; the typical use is insertion into a different file
0845718da   Jens Axboe   pipe: add documen...
153
154
   *	page cache.
   */
330ab7161   Jens Axboe   [PATCH] vmsplice:...
155
156
  int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
  			   struct pipe_buffer *buf)
5abc97aa2   Jens Axboe   [PATCH] splice: a...
157
  {
46e678c96   Jens Axboe   [PATCH] splice: f...
158
  	struct page *page = buf->page;
0845718da   Jens Axboe   pipe: add documen...
159
160
161
162
163
  	/*
  	 * 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...
164
  	if (page_count(page) == 1) {
46e678c96   Jens Axboe   [PATCH] splice: f...
165
166
167
168
169
  		lock_page(page);
  		return 0;
  	}
  
  	return 1;
5abc97aa2   Jens Axboe   [PATCH] splice: a...
170
  }
51921cb74   Miklos Szeredi   mm: export generi...
171
  EXPORT_SYMBOL(generic_pipe_buf_steal);
5abc97aa2   Jens Axboe   [PATCH] splice: a...
172

0845718da   Jens Axboe   pipe: add documen...
173
  /**
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
174
   * generic_pipe_buf_get - get a reference to a &struct pipe_buffer
0845718da   Jens Axboe   pipe: add documen...
175
176
177
178
179
180
181
182
183
   * @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...
184
  {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
185
  	get_page(buf->page);
70524490e   Jens Axboe   [PATCH] splice: a...
186
  }
51921cb74   Miklos Szeredi   mm: export generi...
187
  EXPORT_SYMBOL(generic_pipe_buf_get);
70524490e   Jens Axboe   [PATCH] splice: a...
188

0845718da   Jens Axboe   pipe: add documen...
189
190
  /**
   * generic_pipe_buf_confirm - verify contents of the pipe buffer
79685b8de   Randy Dunlap   docbook: add pipe...
191
   * @info:	the pipe that the buffer belongs to
0845718da   Jens Axboe   pipe: add documen...
192
193
194
195
196
197
   * @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 ...
198
199
  int generic_pipe_buf_confirm(struct pipe_inode_info *info,
  			     struct pipe_buffer *buf)
f84d75199   Jens Axboe   [PATCH] pipe: int...
200
201
202
  {
  	return 0;
  }
51921cb74   Miklos Szeredi   mm: export generi...
203
  EXPORT_SYMBOL(generic_pipe_buf_confirm);
f84d75199   Jens Axboe   [PATCH] pipe: int...
204

6818173bd   Miklos Szeredi   splice: implement...
205
206
207
208
209
210
211
212
213
214
215
  /**
   * 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...
216
  	put_page(buf->page);
6818173bd   Miklos Szeredi   splice: implement...
217
  }
51921cb74   Miklos Szeredi   mm: export generi...
218
  EXPORT_SYMBOL(generic_pipe_buf_release);
6818173bd   Miklos Szeredi   splice: implement...
219

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

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

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

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
351
  	if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
354
355
356
357
358
  		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...
359
  	if (pipe->nrbufs && chars != 0) {
341b446bc   Ingo Molnar   [PATCH] another r...
360
  		int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
35f3d14db   Jens Axboe   pipe: add support...
361
  							(pipe->buffers - 1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
362
  		struct pipe_buffer *buf = pipe->bufs + lastbuf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
363
  		int offset = buf->offset + buf->len;
341b446bc   Ingo Molnar   [PATCH] another r...
364

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

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

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

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

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

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

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

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

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

d86133bd3   Vladimir Davydov   pipe: account to ...
598
  	pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL_ACCOUNT);
09b4d1990   Michael Kerrisk (man-pages)   pipe: simplify lo...
599
600
  	if (pipe == NULL)
  		goto out_free_uid;
086e774a5   Michael Kerrisk (man-pages)   pipe: cap initial...
601
602
  	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...
603
  	user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
a005ca0e6   Michael Kerrisk (man-pages)   pipe: fix limit c...
604

9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
605
606
  	if (too_many_pipe_buffers_soft(user_bufs)) {
  		user_bufs = account_pipe_buffers(user, pipe_bufs, 1);
a005ca0e6   Michael Kerrisk (man-pages)   pipe: fix limit c...
607
  		pipe_bufs = 1;
09b4d1990   Michael Kerrisk (man-pages)   pipe: simplify lo...
608
  	}
759c01142   Willy Tarreau   pipe: limit the p...
609

9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
610
  	if (too_many_pipe_buffers_hard(user_bufs))
a005ca0e6   Michael Kerrisk (man-pages)   pipe: fix limit c...
611
612
613
614
  		goto out_revert_acct;
  
  	pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer),
  			     GFP_KERNEL_ACCOUNT);
09b4d1990   Michael Kerrisk (man-pages)   pipe: simplify lo...
615
616
617
618
619
  	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...
620
621
  		mutex_init(&pipe->mutex);
  		return pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
622
  	}
a005ca0e6   Michael Kerrisk (man-pages)   pipe: fix limit c...
623
  out_revert_acct:
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
624
  	(void) account_pipe_buffers(user, pipe_bufs, 0);
09b4d1990   Michael Kerrisk (man-pages)   pipe: simplify lo...
625
626
627
  	kfree(pipe);
  out_free_uid:
  	free_uid(user);
35f3d14db   Jens Axboe   pipe: add support...
628
  	return NULL;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
629
  }
4b8a8f1e4   Al Viro   get rid of the la...
630
  void free_pipe_info(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631
632
  {
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633

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

c23fbb6bc   Eric Dumazet   VFS: delay the de...
648
649
650
651
652
653
  /*
   * 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...
654
  				d_inode(dentry)->i_ino);
c23fbb6bc   Eric Dumazet   VFS: delay the de...
655
  }
3ba13d179   Al Viro   constify dentry_o...
656
  static const struct dentry_operations pipefs_dentry_operations = {
c23fbb6bc   Eric Dumazet   VFS: delay the de...
657
  	.d_dname	= pipefs_dname,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
659
660
661
  };
  
  static struct inode * get_pipe_inode(void)
  {
a209dfc7b   Eric Dumazet   vfs: dont chain p...
662
  	struct inode *inode = new_inode_pseudo(pipe_mnt->mnt_sb);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
663
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
664
665
666
  
  	if (!inode)
  		goto fail_inode;
85fe4025c   Christoph Hellwig   fs: do not assign...
667
  	inode->i_ino = get_next_ino();
7bee130e2   Al Viro   get rid of alloc_...
668
  	pipe = alloc_pipe_info();
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
669
  	if (!pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
  		goto fail_iput;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
671

ba5bb1473   Al Viro   pipe: take alloca...
672
673
  	inode->i_pipe = pipe;
  	pipe->files = 2;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
674
  	pipe->readers = pipe->writers = 1;
599a0ac14   Al Viro   pipe: fold file_o...
675
  	inode->i_fop = &pipefifo_fops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
676
677
678
679
680
681
682
683
684
  
  	/*
  	 * 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...
685
686
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
078cd8279   Deepa Dinamani   fs: Replace CURRE...
687
  	inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
688

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
689
690
691
692
  	return inode;
  
  fail_iput:
  	iput(inode);
341b446bc   Ingo Molnar   [PATCH] another r...
693

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
705
  	if (!inode)
e4fad8e5d   Al Viro   consolidate pipe ...
706
  		return -ENFILE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
707

d6cbd281d   Andi Kleen   [PATCH] Some clea...
708
  	err = -ENOMEM;
4b936885a   Nick Piggin   fs: improve scala...
709
  	path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name);
2c48b9c45   Al Viro   switch alloc_file...
710
  	if (!path.dentry)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
711
  		goto err_inode;
2c48b9c45   Al Viro   switch alloc_file...
712
  	path.mnt = mntget(pipe_mnt);
341b446bc   Ingo Molnar   [PATCH] another r...
713

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

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

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

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

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

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

ed8cae8ba   Ulrich Drepper   flag parameters: ...
759
  	error = get_unused_fd_flags(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
760
761
762
  	if (error < 0)
  		goto err_read_pipe;
  	fdr = error;
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_fdr;
  	fdw = error;
157cf649a   Al Viro   sanitize audit_fd...
767
  	audit_fd_pair(fdr, fdw);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
768
769
  	fd[0] = fdr;
  	fd[1] = fdw;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
770
771
772
773
774
  	return 0;
  
   err_fdr:
  	put_unused_fd(fdr);
   err_read_pipe:
e4fad8e5d   Al Viro   consolidate pipe ...
775
776
  	fput(files[0]);
  	fput(files[1]);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
777
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
778
  }
5b249b1b0   Al Viro   pipe(2) - race-fr...
779
780
781
782
783
784
785
786
787
788
  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
789
  /*
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
790
791
792
   * 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...
793
  SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
794
  {
5b249b1b0   Al Viro   pipe(2) - race-fr...
795
  	struct file *files[2];
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
796
797
  	int fd[2];
  	int error;
5b249b1b0   Al Viro   pipe(2) - race-fr...
798
  	error = __do_pipe_flags(fd, files, flags);
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
799
  	if (!error) {
5b249b1b0   Al Viro   pipe(2) - race-fr...
800
801
802
803
804
  		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...
805
  			error = -EFAULT;
5b249b1b0   Al Viro   pipe(2) - race-fr...
806
807
808
  		} else {
  			fd_install(fd[0], files[0]);
  			fd_install(fd[1], files[1]);
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
809
  		}
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
810
811
812
  	}
  	return error;
  }
2b6642199   Heiko Carstens   [CVE-2009-0029] S...
813
  SYSCALL_DEFINE1(pipe, int __user *, fildes)
ed8cae8ba   Ulrich Drepper   flag parameters: ...
814
815
816
  {
  	return sys_pipe2(fildes, 0);
  }
fc7478a2b   Al Viro   pipe: switch wait...
817
  static int wait_for_partner(struct pipe_inode_info *pipe, unsigned int *cnt)
f776c7388   Al Viro   fold fifo.c into ...
818
819
820
821
  {
  	int cur = *cnt;	
  
  	while (cur == *cnt) {
fc7478a2b   Al Viro   pipe: switch wait...
822
  		pipe_wait(pipe);
f776c7388   Al Viro   fold fifo.c into ...
823
824
825
826
827
  		if (signal_pending(current))
  			break;
  	}
  	return cur == *cnt ? -ERESTARTSYS : 0;
  }
fc7478a2b   Al Viro   pipe: switch wait...
828
  static void wake_up_partner(struct pipe_inode_info *pipe)
f776c7388   Al Viro   fold fifo.c into ...
829
  {
fc7478a2b   Al Viro   pipe: switch wait...
830
  	wake_up_interruptible(&pipe->wait);
f776c7388   Al Viro   fold fifo.c into ...
831
832
833
834
835
  }
  
  static int fifo_open(struct inode *inode, struct file *filp)
  {
  	struct pipe_inode_info *pipe;
599a0ac14   Al Viro   pipe: fold file_o...
836
  	bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC;
f776c7388   Al Viro   fold fifo.c into ...
837
  	int ret;
ba5bb1473   Al Viro   pipe: take alloca...
838
839
840
841
842
843
844
845
846
  	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_...
847
  		pipe = alloc_pipe_info();
f776c7388   Al Viro   fold fifo.c into ...
848
  		if (!pipe)
ba5bb1473   Al Viro   pipe: take alloca...
849
850
851
852
853
854
  			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...
855
  			free_pipe_info(pipe);
ba5bb1473   Al Viro   pipe: take alloca...
856
857
858
859
860
  			pipe = inode->i_pipe;
  		} else {
  			inode->i_pipe = pipe;
  			spin_unlock(&inode->i_lock);
  		}
f776c7388   Al Viro   fold fifo.c into ...
861
  	}
de32ec4cf   Al Viro   pipe: set file->p...
862
  	filp->private_data = pipe;
ba5bb1473   Al Viro   pipe: take alloca...
863
  	/* OK, we have a pipe and it's pinned down */
ebec73f47   Al Viro   introduce variant...
864
  	__pipe_lock(pipe);
f776c7388   Al Viro   fold fifo.c into ...
865
866
867
868
869
870
871
872
873
874
875
  
  	/* 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 ...
876
877
  		pipe->r_counter++;
  		if (pipe->readers++ == 0)
fc7478a2b   Al Viro   pipe: switch wait...
878
  			wake_up_partner(pipe);
f776c7388   Al Viro   fold fifo.c into ...
879

599a0ac14   Al Viro   pipe: fold file_o...
880
  		if (!is_pipe && !pipe->writers) {
f776c7388   Al Viro   fold fifo.c into ...
881
882
883
884
885
  			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...
886
  				if (wait_for_partner(pipe, &pipe->w_counter))
f776c7388   Al Viro   fold fifo.c into ...
887
888
889
890
891
892
893
894
895
896
897
898
  					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...
899
  		if (!is_pipe && (filp->f_flags & O_NONBLOCK) && !pipe->readers)
f776c7388   Al Viro   fold fifo.c into ...
900
  			goto err;
f776c7388   Al Viro   fold fifo.c into ...
901
902
  		pipe->w_counter++;
  		if (!pipe->writers++)
fc7478a2b   Al Viro   pipe: switch wait...
903
  			wake_up_partner(pipe);
f776c7388   Al Viro   fold fifo.c into ...
904

599a0ac14   Al Viro   pipe: fold file_o...
905
  		if (!is_pipe && !pipe->readers) {
fc7478a2b   Al Viro   pipe: switch wait...
906
  			if (wait_for_partner(pipe, &pipe->r_counter))
f776c7388   Al Viro   fold fifo.c into ...
907
908
909
910
911
912
913
914
915
916
917
  				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 ...
918
919
920
921
922
923
  
  		pipe->readers++;
  		pipe->writers++;
  		pipe->r_counter++;
  		pipe->w_counter++;
  		if (pipe->readers == 1 || pipe->writers == 1)
fc7478a2b   Al Viro   pipe: switch wait...
924
  			wake_up_partner(pipe);
f776c7388   Al Viro   fold fifo.c into ...
925
926
927
928
929
930
931
932
  		break;
  
  	default:
  		ret = -EINVAL;
  		goto err;
  	}
  
  	/* Ok! */
ebec73f47   Al Viro   introduce variant...
933
  	__pipe_unlock(pipe);
f776c7388   Al Viro   fold fifo.c into ...
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
  	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...
949
  	__pipe_unlock(pipe);
b0d8d2292   Linus Torvalds   vfs: fix subtle u...
950
951
  
  	put_pipe_info(inode, pipe);
f776c7388   Al Viro   fold fifo.c into ...
952
953
  	return ret;
  }
599a0ac14   Al Viro   pipe: fold file_o...
954
955
956
  const struct file_operations pipefifo_fops = {
  	.open		= fifo_open,
  	.llseek		= no_llseek,
fb9096a34   Al Viro   pipe: switch to -...
957
  	.read_iter	= pipe_read,
f0d1bec9d   Al Viro   new helper: copy_...
958
  	.write_iter	= pipe_write,
599a0ac14   Al Viro   pipe: fold file_o...
959
960
961
962
  	.poll		= pipe_poll,
  	.unlocked_ioctl	= pipe_ioctl,
  	.release	= pipe_release,
  	.fasync		= pipe_fasync,
f776c7388   Al Viro   fold fifo.c into ...
963
  };
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
964
  /*
f491bd711   Michael Kerrisk (man-pages)   pipe: relocate ro...
965
966
967
968
969
970
971
972
973
974
975
976
   * Currently we rely on the pipe array holding a power-of-2 number
   * of pages.
   */
  static inline unsigned int round_pipe_size(unsigned int size)
  {
  	unsigned long nr_pages;
  
  	nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  	return roundup_pow_of_two(nr_pages) << PAGE_SHIFT;
  }
  
  /*
35f3d14db   Jens Axboe   pipe: add support...
977
978
979
   * 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 ...
980
  static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
35f3d14db   Jens Axboe   pipe: add support...
981
982
  {
  	struct pipe_buffer *bufs;
d37d41666   Michael Kerrisk (man-pages)   pipe: move limit ...
983
  	unsigned int size, nr_pages;
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
984
  	unsigned long user_bufs;
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
985
  	long ret = 0;
d37d41666   Michael Kerrisk (man-pages)   pipe: move limit ...
986
987
988
989
990
991
  
  	size = round_pipe_size(arg);
  	nr_pages = size >> PAGE_SHIFT;
  
  	if (!nr_pages)
  		return -EINVAL;
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
992
993
994
995
996
997
998
999
1000
  	/*
  	 * 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 ...
1001
  		return -EPERM;
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
1002
  	user_bufs = account_pipe_buffers(pipe->user, pipe->buffers, nr_pages);
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1003
1004
  
  	if (nr_pages > pipe->buffers &&
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
1005
1006
  			(too_many_pipe_buffers_hard(user_bufs) ||
  			 too_many_pipe_buffers_soft(user_bufs)) &&
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1007
1008
1009
1010
  			!capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
  		ret = -EPERM;
  		goto out_revert_acct;
  	}
35f3d14db   Jens Axboe   pipe: add support...
1011
1012
  
  	/*
35f3d14db   Jens Axboe   pipe: add support...
1013
1014
1015
1016
1017
  	 * 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...
1018
1019
1020
1021
  	if (nr_pages < pipe->nrbufs) {
  		ret = -EBUSY;
  		goto out_revert_acct;
  	}
35f3d14db   Jens Axboe   pipe: add support...
1022

d86133bd3   Vladimir Davydov   pipe: account to ...
1023
1024
  	bufs = kcalloc(nr_pages, sizeof(*bufs),
  		       GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1025
1026
1027
1028
  	if (unlikely(!bufs)) {
  		ret = -ENOMEM;
  		goto out_revert_acct;
  	}
35f3d14db   Jens Axboe   pipe: add support...
1029
1030
1031
1032
1033
1034
  
  	/*
  	 * 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...
1035
1036
  		unsigned int tail;
  		unsigned int head;
35f3d14db   Jens Axboe   pipe: add support...
1037

1d862f412   Miklos Szeredi   pipe: fix pipe bu...
1038
1039
1040
1041
1042
1043
1044
  		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...
1045
1046
1047
  		if (head)
  			memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer));
  		if (tail)
1d862f412   Miklos Szeredi   pipe: fix pipe bu...
1048
  			memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer));
35f3d14db   Jens Axboe   pipe: add support...
1049
1050
1051
1052
1053
  	}
  
  	pipe->curbuf = 0;
  	kfree(pipe->bufs);
  	pipe->bufs = bufs;
b9598db34   Jens Axboe   pipe: make F_{GET...
1054
1055
  	pipe->buffers = nr_pages;
  	return nr_pages * PAGE_SIZE;
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1056
1057
  
  out_revert_acct:
9c87bcf0a   Michael Kerrisk (man-pages)   pipe: make accoun...
1058
  	(void) account_pipe_buffers(pipe->user, nr_pages, pipe->buffers);
b0b91d18e   Michael Kerrisk (man-pages)   pipe: fix limit c...
1059
  	return ret;
35f3d14db   Jens Axboe   pipe: add support...
1060
  }
ff9da691c   Jens Axboe   pipe: change /pro...
1061
  /*
ff9da691c   Jens Axboe   pipe: change /pro...
1062
1063
1064
1065
1066
1067
1068
1069
1070
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)
  {
  	int ret;
  
  	ret = proc_dointvec_minmax(table, write, buf, lenp, ppos);
  	if (ret < 0 || !write)
  		return ret;
  
  	pipe_max_size = round_pipe_size(pipe_max_size);
  	return ret;
  }
720836465   Linus Torvalds   Un-inline get_pip...
1077
1078
1079
1080
1081
1082
1083
  /*
   * 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...
1084
  	return file->f_op == &pipefifo_fops ? file->private_data : NULL;
720836465   Linus Torvalds   Un-inline get_pip...
1085
  }
35f3d14db   Jens Axboe   pipe: add support...
1086
1087
1088
1089
  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_...
1090
  	pipe = get_pipe_info(file);
35f3d14db   Jens Axboe   pipe: add support...
1091
1092
  	if (!pipe)
  		return -EBADF;
ebec73f47   Al Viro   introduce variant...
1093
  	__pipe_lock(pipe);
35f3d14db   Jens Axboe   pipe: add support...
1094
1095
  
  	switch (cmd) {
d37d41666   Michael Kerrisk (man-pages)   pipe: move limit ...
1096
1097
  	case F_SETPIPE_SZ:
  		ret = pipe_set_size(pipe, arg);
35f3d14db   Jens Axboe   pipe: add support...
1098
1099
  		break;
  	case F_GETPIPE_SZ:
b9598db34   Jens Axboe   pipe: make F_{GET...
1100
  		ret = pipe->buffers * PAGE_SIZE;
35f3d14db   Jens Axboe   pipe: add support...
1101
1102
1103
1104
1105
  		break;
  	default:
  		ret = -EINVAL;
  		break;
  	}
ebec73f47   Al Viro   introduce variant...
1106
  	__pipe_unlock(pipe);
35f3d14db   Jens Axboe   pipe: add support...
1107
1108
  	return ret;
  }
ff0c7d15f   Nick Piggin   fs: avoid inode R...
1109
1110
  static const struct super_operations pipefs_ops = {
  	.destroy_inode = free_inode_nonrcu,
d70ef97ba   Pavel Emelyanov   fs/pipe.c: add ->...
1111
  	.statfs = simple_statfs,
ff0c7d15f   Nick Piggin   fs: avoid inode R...
1112
  };
35f3d14db   Jens Axboe   pipe: add support...
1113
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1114
1115
1116
1117
1118
   * 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...
1119
1120
  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
1121
  {
c74a1cbb3   Al Viro   pass default dent...
1122
1123
  	return mount_pseudo(fs_type, "pipe:", &pipefs_ops,
  			&pipefs_dentry_operations, PIPEFS_MAGIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1124
1125
1126
1127
  }
  
  static struct file_system_type pipe_fs_type = {
  	.name		= "pipefs",
51139adac   Al Viro   convert get_sb_ps...
1128
  	.mount		= pipefs_mount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1129
1130
1131
1132
1133
1134
  	.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...
1135

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1136
1137
1138
1139
1140
1141
1142
1143
1144
  	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
1145
  fs_initcall(init_pipe_fs);