Blame view

fs/pipe.c 28.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
16
17
18
  #include <linux/mount.h>
  #include <linux/pipe_fs_i.h>
  #include <linux/uio.h>
  #include <linux/highmem.h>
5274f052e   Jens Axboe   [PATCH] Introduce...
19
  #include <linux/pagemap.h>
db3495099   Al Viro   [PATCH] AUDIT_FD_...
20
  #include <linux/audit.h>
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
21
  #include <linux/syscalls.h>
b492e95be   Jens Axboe   pipe: set lower a...
22
  #include <linux/fcntl.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
26
27
  
  #include <asm/uaccess.h>
  #include <asm/ioctls.h>
  
  /*
b492e95be   Jens Axboe   pipe: set lower a...
28
   * The max size that a non-root user is allowed to grow the pipe. Can
ff9da691c   Jens Axboe   pipe: change /pro...
29
   * be set by root in /proc/sys/fs/pipe-max-size
b492e95be   Jens Axboe   pipe: set lower a...
30
   */
ff9da691c   Jens Axboe   pipe: change /pro...
31
32
33
34
35
36
  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...
37
38
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
43
44
45
46
47
48
49
50
51
   * 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...
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  static void pipe_lock_nested(struct pipe_inode_info *pipe, int subclass)
  {
  	if (pipe->inode)
  		mutex_lock_nested(&pipe->inode->i_mutex, subclass);
  }
  
  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)
  {
  	if (pipe->inode)
  		mutex_unlock(&pipe->inode->i_mutex);
  }
  EXPORT_SYMBOL(pipe_unlock);
  
  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...
83
84
  		pipe_lock_nested(pipe2, I_MUTEX_PARENT);
  		pipe_lock_nested(pipe1, I_MUTEX_CHILD);
61e0d47c3   Miklos Szeredi   splice: add helpe...
85
86
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
  /* Drop the inode semaphore and wait for a pipe event, atomically */
3a326a2ce   Ingo Molnar   [PATCH] introduce...
88
  void pipe_wait(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
  {
  	DEFINE_WAIT(wait);
d79fc0fc6   Ingo Molnar   [PATCH] sched: TA...
91
92
93
94
  	/*
  	 * Pipes are system-local resources, so sleeping on them
  	 * is considered a noninteractive wait:
  	 */
af9272326   Mike Galbraith   sched: cleanup, r...
95
  	prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE);
61e0d47c3   Miklos Szeredi   splice: add helpe...
96
  	pipe_unlock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
  	schedule();
3a326a2ce   Ingo Molnar   [PATCH] introduce...
98
  	finish_wait(&pipe->wait, &wait);
61e0d47c3   Miklos Szeredi   splice: add helpe...
99
  	pipe_lock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
  }
858119e15   Arjan van de Ven   [PATCH] Unlinline...
101
  static int
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
102
103
  pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len,
  			int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
106
107
108
109
110
  {
  	unsigned long copy;
  
  	while (len > 0) {
  		while (!iov->iov_len)
  			iov++;
  		copy = min_t(unsigned long, len, iov->iov_len);
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
111
112
113
114
115
116
117
  		if (atomic) {
  			if (__copy_from_user_inatomic(to, iov->iov_base, copy))
  				return -EFAULT;
  		} else {
  			if (copy_from_user(to, iov->iov_base, copy))
  				return -EFAULT;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
120
121
122
123
124
  		to += copy;
  		len -= copy;
  		iov->iov_base += copy;
  		iov->iov_len -= copy;
  	}
  	return 0;
  }
858119e15   Arjan van de Ven   [PATCH] Unlinline...
125
  static int
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
126
127
  pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len,
  		      int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
131
132
133
134
  {
  	unsigned long copy;
  
  	while (len > 0) {
  		while (!iov->iov_len)
  			iov++;
  		copy = min_t(unsigned long, len, iov->iov_len);
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
135
136
137
138
139
140
141
  		if (atomic) {
  			if (__copy_to_user_inatomic(iov->iov_base, from, copy))
  				return -EFAULT;
  		} else {
  			if (copy_to_user(iov->iov_base, from, copy))
  				return -EFAULT;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
144
145
146
147
148
  		from += copy;
  		len -= copy;
  		iov->iov_base += copy;
  		iov->iov_len -= copy;
  	}
  	return 0;
  }
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  /*
   * Attempt to pre-fault in the user memory, so we can use atomic copies.
   * Returns the number of bytes not faulted in.
   */
  static int iov_fault_in_pages_write(struct iovec *iov, unsigned long len)
  {
  	while (!iov->iov_len)
  		iov++;
  
  	while (len > 0) {
  		unsigned long this_len;
  
  		this_len = min_t(unsigned long, len, iov->iov_len);
  		if (fault_in_pages_writeable(iov->iov_base, this_len))
  			break;
  
  		len -= this_len;
  		iov++;
  	}
  
  	return len;
  }
  
  /*
   * Pre-fault in the user memory, so we can use atomic copies.
   */
  static void iov_fault_in_pages_read(struct iovec *iov, unsigned long len)
  {
  	while (!iov->iov_len)
  		iov++;
  
  	while (len > 0) {
  		unsigned long this_len;
  
  		this_len = min_t(unsigned long, len, iov->iov_len);
  		fault_in_pages_readable(iov->iov_base, this_len);
  		len -= this_len;
  		iov++;
  	}
  }
341b446bc   Ingo Molnar   [PATCH] another r...
189
190
  static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
  				  struct pipe_buffer *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
  {
  	struct page *page = buf->page;
5274f052e   Jens Axboe   [PATCH] Introduce...
193
194
195
  	/*
  	 * 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...
196
  	 * allocation cache. (Otherwise just release our reference to it)
5274f052e   Jens Axboe   [PATCH] Introduce...
197
  	 */
341b446bc   Ingo Molnar   [PATCH] another r...
198
  	if (page_count(page) == 1 && !pipe->tmp_page)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
199
  		pipe->tmp_page = page;
341b446bc   Ingo Molnar   [PATCH] another r...
200
201
  	else
  		page_cache_release(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
  }
0845718da   Jens Axboe   pipe: add documen...
203
204
205
206
207
208
209
210
  /**
   * generic_pipe_buf_map - virtually map a pipe buffer
   * @pipe:	the pipe that the buffer belongs to
   * @buf:	the buffer that should be mapped
   * @atomic:	whether to use an atomic map
   *
   * Description:
   *	This function returns a kernel virtual address mapping for the
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
211
   *	pipe_buffer passed in @buf. If @atomic is set, an atomic map is provided
0845718da   Jens Axboe   pipe: add documen...
212
213
214
215
216
   *	and the caller has to be careful not to fault before calling
   *	the unmap function.
   *
   *	Note that this function occupies KM_USER0 if @atomic != 0.
   */
f84d75199   Jens Axboe   [PATCH] pipe: int...
217
  void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
218
  			   struct pipe_buffer *buf, int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219
  {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
220
221
222
223
  	if (atomic) {
  		buf->flags |= PIPE_BUF_FLAG_ATOMIC;
  		return kmap_atomic(buf->page, KM_USER0);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
225
  	return kmap(buf->page);
  }
51921cb74   Miklos Szeredi   mm: export generi...
226
  EXPORT_SYMBOL(generic_pipe_buf_map);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227

0845718da   Jens Axboe   pipe: add documen...
228
229
230
231
232
233
234
235
236
  /**
   * generic_pipe_buf_unmap - unmap a previously mapped pipe buffer
   * @pipe:	the pipe that the buffer belongs to
   * @buf:	the buffer that should be unmapped
   * @map_data:	the data that the mapping function returned
   *
   * Description:
   *	This function undoes the mapping that ->map() provided.
   */
f84d75199   Jens Axboe   [PATCH] pipe: int...
237
  void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
238
  			    struct pipe_buffer *buf, void *map_data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
  {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
240
241
242
243
244
  	if (buf->flags & PIPE_BUF_FLAG_ATOMIC) {
  		buf->flags &= ~PIPE_BUF_FLAG_ATOMIC;
  		kunmap_atomic(map_data, KM_USER0);
  	} else
  		kunmap(buf->page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
  }
51921cb74   Miklos Szeredi   mm: export generi...
246
  EXPORT_SYMBOL(generic_pipe_buf_unmap);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247

0845718da   Jens Axboe   pipe: add documen...
248
  /**
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
249
   * generic_pipe_buf_steal - attempt to take ownership of a &pipe_buffer
0845718da   Jens Axboe   pipe: add documen...
250
251
252
253
   * @pipe:	the pipe that the buffer belongs to
   * @buf:	the buffer to attempt to steal
   *
   * Description:
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
254
   *	This function attempts to steal the &struct page attached to
0845718da   Jens Axboe   pipe: add documen...
255
256
   *	@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...
257
   *	he wishes; the typical use is insertion into a different file
0845718da   Jens Axboe   pipe: add documen...
258
259
   *	page cache.
   */
330ab7161   Jens Axboe   [PATCH] vmsplice:...
260
261
  int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
  			   struct pipe_buffer *buf)
5abc97aa2   Jens Axboe   [PATCH] splice: a...
262
  {
46e678c96   Jens Axboe   [PATCH] splice: f...
263
  	struct page *page = buf->page;
0845718da   Jens Axboe   pipe: add documen...
264
265
266
267
268
  	/*
  	 * 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...
269
  	if (page_count(page) == 1) {
46e678c96   Jens Axboe   [PATCH] splice: f...
270
271
272
273
274
  		lock_page(page);
  		return 0;
  	}
  
  	return 1;
5abc97aa2   Jens Axboe   [PATCH] splice: a...
275
  }
51921cb74   Miklos Szeredi   mm: export generi...
276
  EXPORT_SYMBOL(generic_pipe_buf_steal);
5abc97aa2   Jens Axboe   [PATCH] splice: a...
277

0845718da   Jens Axboe   pipe: add documen...
278
  /**
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
279
   * generic_pipe_buf_get - get a reference to a &struct pipe_buffer
0845718da   Jens Axboe   pipe: add documen...
280
281
282
283
284
285
286
287
288
   * @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...
289
290
291
  {
  	page_cache_get(buf->page);
  }
51921cb74   Miklos Szeredi   mm: export generi...
292
  EXPORT_SYMBOL(generic_pipe_buf_get);
70524490e   Jens Axboe   [PATCH] splice: a...
293

0845718da   Jens Axboe   pipe: add documen...
294
295
  /**
   * generic_pipe_buf_confirm - verify contents of the pipe buffer
79685b8de   Randy Dunlap   docbook: add pipe...
296
   * @info:	the pipe that the buffer belongs to
0845718da   Jens Axboe   pipe: add documen...
297
298
299
300
301
302
   * @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 ...
303
304
  int generic_pipe_buf_confirm(struct pipe_inode_info *info,
  			     struct pipe_buffer *buf)
f84d75199   Jens Axboe   [PATCH] pipe: int...
305
306
307
  {
  	return 0;
  }
51921cb74   Miklos Szeredi   mm: export generi...
308
  EXPORT_SYMBOL(generic_pipe_buf_confirm);
f84d75199   Jens Axboe   [PATCH] pipe: int...
309

6818173bd   Miklos Szeredi   splice: implement...
310
311
312
313
314
315
316
317
318
319
320
321
322
  /**
   * 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)
  {
  	page_cache_release(buf->page);
  }
51921cb74   Miklos Szeredi   mm: export generi...
323
  EXPORT_SYMBOL(generic_pipe_buf_release);
6818173bd   Miklos Szeredi   splice: implement...
324

d4c3cca94   Eric Dumazet   [PATCH] constify ...
325
  static const struct pipe_buf_operations anon_pipe_buf_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
  	.can_merge = 1,
f84d75199   Jens Axboe   [PATCH] pipe: int...
327
328
  	.map = generic_pipe_buf_map,
  	.unmap = generic_pipe_buf_unmap,
cac36bb06   Jens Axboe   pipe: change the ...
329
  	.confirm = generic_pipe_buf_confirm,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
330
  	.release = anon_pipe_buf_release,
330ab7161   Jens Axboe   [PATCH] vmsplice:...
331
  	.steal = generic_pipe_buf_steal,
f84d75199   Jens Axboe   [PATCH] pipe: int...
332
  	.get = generic_pipe_buf_get,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
333
334
335
  };
  
  static ssize_t
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
336
337
  pipe_read(struct kiocb *iocb, const struct iovec *_iov,
  	   unsigned long nr_segs, loff_t pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
  {
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
339
  	struct file *filp = iocb->ki_filp;
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
340
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
341
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
343
344
345
346
347
348
349
350
351
352
353
  	int do_wakeup;
  	ssize_t ret;
  	struct iovec *iov = (struct iovec *)_iov;
  	size_t total_len;
  
  	total_len = iov_length(iov, nr_segs);
  	/* Null read succeeds. */
  	if (unlikely(total_len == 0))
  		return 0;
  
  	do_wakeup = 0;
  	ret = 0;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
354
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
355
  	pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
  	for (;;) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
357
  		int bufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
  		if (bufs) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
359
360
  			int curbuf = pipe->curbuf;
  			struct pipe_buffer *buf = pipe->bufs + curbuf;
d4c3cca94   Eric Dumazet   [PATCH] constify ...
361
  			const struct pipe_buf_operations *ops = buf->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
363
  			void *addr;
  			size_t chars = buf->len;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
364
  			int error, atomic;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365
366
367
  
  			if (chars > total_len)
  				chars = total_len;
cac36bb06   Jens Axboe   pipe: change the ...
368
  			error = ops->confirm(pipe, buf);
f84d75199   Jens Axboe   [PATCH] pipe: int...
369
  			if (error) {
5274f052e   Jens Axboe   [PATCH] Introduce...
370
  				if (!ret)
e5953cbdf   Nicolas Kaiser   pipe: fix failure...
371
  					ret = error;
5274f052e   Jens Axboe   [PATCH] Introduce...
372
373
  				break;
  			}
f84d75199   Jens Axboe   [PATCH] pipe: int...
374

f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
375
376
377
378
379
  			atomic = !iov_fault_in_pages_write(iov, chars);
  redo:
  			addr = ops->map(pipe, buf, atomic);
  			error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars, atomic);
  			ops->unmap(pipe, buf, addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
  			if (unlikely(error)) {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
381
382
383
384
385
386
387
  				/*
  				 * Just retry with the slow path if we failed.
  				 */
  				if (atomic) {
  					atomic = 0;
  					goto redo;
  				}
341b446bc   Ingo Molnar   [PATCH] another r...
388
  				if (!ret)
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
389
  					ret = error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
391
392
393
394
395
396
  				break;
  			}
  			ret += chars;
  			buf->offset += chars;
  			buf->len -= chars;
  			if (!buf->len) {
  				buf->ops = NULL;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
397
  				ops->release(pipe, buf);
35f3d14db   Jens Axboe   pipe: add support...
398
  				curbuf = (curbuf + 1) & (pipe->buffers - 1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
399
400
  				pipe->curbuf = curbuf;
  				pipe->nrbufs = --bufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
404
405
406
407
408
  				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...
409
  		if (!pipe->writers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
  			break;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
411
  		if (!pipe->waiting_writers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
413
414
415
416
417
418
419
420
421
422
423
424
  			/* 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...
425
426
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
428
429
  			break;
  		}
  		if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
430
  			wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
431
   			kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
432
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
433
  		pipe_wait(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
435
  	mutex_unlock(&inode->i_mutex);
341b446bc   Ingo Molnar   [PATCH] another r...
436
437
  
  	/* Signal writers asynchronously that there is more room. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
  	if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
439
  		wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
440
  		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
442
443
444
445
446
447
  	}
  	if (ret > 0)
  		file_accessed(filp);
  	return ret;
  }
  
  static ssize_t
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
448
449
  pipe_write(struct kiocb *iocb, const struct iovec *_iov,
  	    unsigned long nr_segs, loff_t ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
  {
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
451
  	struct file *filp = iocb->ki_filp;
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
452
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
453
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
455
456
457
458
459
460
461
462
463
464
465
466
  	ssize_t ret;
  	int do_wakeup;
  	struct iovec *iov = (struct iovec *)_iov;
  	size_t total_len;
  	ssize_t chars;
  
  	total_len = iov_length(iov, nr_segs);
  	/* Null write succeeds. */
  	if (unlikely(total_len == 0))
  		return 0;
  
  	do_wakeup = 0;
  	ret = 0;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
467
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
468
  	pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
470
  	if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471
472
473
474
475
476
477
  		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...
478
  	if (pipe->nrbufs && chars != 0) {
341b446bc   Ingo Molnar   [PATCH] another r...
479
  		int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
35f3d14db   Jens Axboe   pipe: add support...
480
  							(pipe->buffers - 1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
481
  		struct pipe_buffer *buf = pipe->bufs + lastbuf;
d4c3cca94   Eric Dumazet   [PATCH] constify ...
482
  		const struct pipe_buf_operations *ops = buf->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
  		int offset = buf->offset + buf->len;
341b446bc   Ingo Molnar   [PATCH] another r...
484

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
  		if (ops->can_merge && offset + chars <= PAGE_SIZE) {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
486
  			int error, atomic = 1;
5274f052e   Jens Axboe   [PATCH] Introduce...
487
  			void *addr;
5274f052e   Jens Axboe   [PATCH] Introduce...
488

cac36bb06   Jens Axboe   pipe: change the ...
489
  			error = ops->confirm(pipe, buf);
f84d75199   Jens Axboe   [PATCH] pipe: int...
490
  			if (error)
5274f052e   Jens Axboe   [PATCH] Introduce...
491
  				goto out;
f84d75199   Jens Axboe   [PATCH] pipe: int...
492

f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
493
494
495
  			iov_fault_in_pages_read(iov, chars);
  redo1:
  			addr = ops->map(pipe, buf, atomic);
5274f052e   Jens Axboe   [PATCH] Introduce...
496
  			error = pipe_iov_copy_from_user(offset + addr, iov,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
497
498
  							chars, atomic);
  			ops->unmap(pipe, buf, addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
499
500
  			ret = error;
  			do_wakeup = 1;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
501
502
503
504
505
  			if (error) {
  				if (atomic) {
  					atomic = 0;
  					goto redo1;
  				}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
  				goto out;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
507
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
508
509
510
511
512
513
514
515
516
517
  			buf->len += chars;
  			total_len -= chars;
  			ret = chars;
  			if (!total_len)
  				goto out;
  		}
  	}
  
  	for (;;) {
  		int bufs;
341b446bc   Ingo Molnar   [PATCH] another r...
518

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
519
  		if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
  			send_sig(SIGPIPE, current, 0);
341b446bc   Ingo Molnar   [PATCH] another r...
521
522
  			if (!ret)
  				ret = -EPIPE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
524
  			break;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
525
  		bufs = pipe->nrbufs;
35f3d14db   Jens Axboe   pipe: add support...
526
527
  		if (bufs < pipe->buffers) {
  			int newbuf = (pipe->curbuf + bufs) & (pipe->buffers-1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
528
529
  			struct pipe_buffer *buf = pipe->bufs + newbuf;
  			struct page *page = pipe->tmp_page;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
530
531
  			char *src;
  			int error, atomic = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
533
534
535
536
537
538
  
  			if (!page) {
  				page = alloc_page(GFP_HIGHUSER);
  				if (unlikely(!page)) {
  					ret = ret ? : -ENOMEM;
  					break;
  				}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
539
  				pipe->tmp_page = page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
540
  			}
341b446bc   Ingo Molnar   [PATCH] another r...
541
  			/* Always wake up, even if the copy fails. Otherwise
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
543
544
545
546
547
548
549
  			 * we lock up (O_NONBLOCK-)readers that sleep due to
  			 * syscall merging.
  			 * FIXME! Is this really true?
  			 */
  			do_wakeup = 1;
  			chars = PAGE_SIZE;
  			if (chars > total_len)
  				chars = total_len;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
550
551
552
553
554
555
556
557
558
559
560
561
562
  			iov_fault_in_pages_read(iov, chars);
  redo2:
  			if (atomic)
  				src = kmap_atomic(page, KM_USER0);
  			else
  				src = kmap(page);
  
  			error = pipe_iov_copy_from_user(src, iov, chars,
  							atomic);
  			if (atomic)
  				kunmap_atomic(src, KM_USER0);
  			else
  				kunmap(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
  			if (unlikely(error)) {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
564
565
566
567
  				if (atomic) {
  					atomic = 0;
  					goto redo2;
  				}
341b446bc   Ingo Molnar   [PATCH] another r...
568
  				if (!ret)
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
569
  					ret = error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570
571
572
573
574
575
576
577
578
  				break;
  			}
  			ret += chars;
  
  			/* Insert it into the buffer array */
  			buf->page = page;
  			buf->ops = &anon_pipe_buf_ops;
  			buf->offset = 0;
  			buf->len = chars;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
579
580
  			pipe->nrbufs = ++bufs;
  			pipe->tmp_page = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
582
583
584
585
  
  			total_len -= chars;
  			if (!total_len)
  				break;
  		}
35f3d14db   Jens Axboe   pipe: add support...
586
  		if (bufs < pipe->buffers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
588
  			continue;
  		if (filp->f_flags & O_NONBLOCK) {
341b446bc   Ingo Molnar   [PATCH] another r...
589
590
  			if (!ret)
  				ret = -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591
592
593
  			break;
  		}
  		if (signal_pending(current)) {
341b446bc   Ingo Molnar   [PATCH] another r...
594
595
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596
597
598
  			break;
  		}
  		if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
599
  			wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
600
  			kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
601
602
  			do_wakeup = 0;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
603
604
605
  		pipe->waiting_writers++;
  		pipe_wait(pipe);
  		pipe->waiting_writers--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606
607
  	}
  out:
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
608
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
  	if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
610
  		wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
611
  		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
612
613
  	}
  	if (ret > 0)
870f48179   Christoph Hellwig   [PATCH] replace i...
614
  		file_update_time(filp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
615
616
617
618
  	return ret;
  }
  
  static ssize_t
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619
620
621
622
623
624
  bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
  {
  	return -EBADF;
  }
  
  static ssize_t
341b446bc   Ingo Molnar   [PATCH] another r...
625
626
  bad_pipe_w(struct file *filp, const char __user *buf, size_t count,
  	   loff_t *ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
627
628
629
  {
  	return -EBADF;
  }
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
630
  static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
632
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
633
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
634
635
636
637
  	int count, buf, nrbufs;
  
  	switch (cmd) {
  		case FIONREAD:
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
638
  			mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
639
  			pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
640
  			count = 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
641
642
  			buf = pipe->curbuf;
  			nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643
  			while (--nrbufs >= 0) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
644
  				count += pipe->bufs[buf].len;
35f3d14db   Jens Axboe   pipe: add support...
645
  				buf = (buf+1) & (pipe->buffers - 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
  			}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
647
  			mutex_unlock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
648

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
649
650
651
652
653
654
655
656
657
658
659
  			return put_user(count, (int __user *)arg);
  		default:
  			return -EINVAL;
  	}
  }
  
  /* No kernel lock held - fine */
  static unsigned int
  pipe_poll(struct file *filp, poll_table *wait)
  {
  	unsigned int mask;
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
660
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
661
  	struct pipe_inode_info *pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
  	int nrbufs;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
663
  	poll_wait(filp, &pipe->wait, wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
664
665
  
  	/* Reading only -- no need for acquiring the semaphore.  */
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
666
  	nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
667
668
669
  	mask = 0;
  	if (filp->f_mode & FMODE_READ) {
  		mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
670
  		if (!pipe->writers && filp->f_version != pipe->w_counter)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
671
672
673
674
  			mask |= POLLHUP;
  	}
  
  	if (filp->f_mode & FMODE_WRITE) {
35f3d14db   Jens Axboe   pipe: add support...
675
  		mask |= (nrbufs < pipe->buffers) ? POLLOUT | POLLWRNORM : 0;
5e5d7a222   Pekka Enberg   [PATCH] pipe: rem...
676
677
678
679
  		/*
  		 * 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...
680
  		if (!pipe->readers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
682
683
684
685
  			mask |= POLLERR;
  	}
  
  	return mask;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
686
687
688
  static int
  pipe_release(struct inode *inode, int decr, int decw)
  {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
689
  	struct pipe_inode_info *pipe;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
690
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
691
692
693
  	pipe = inode->i_pipe;
  	pipe->readers -= decr;
  	pipe->writers -= decw;
341b446bc   Ingo Molnar   [PATCH] another r...
694

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
695
  	if (!pipe->readers && !pipe->writers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
696
697
  		free_pipe_info(inode);
  	} else {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
698
  		wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM | POLLERR | POLLHUP);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
699
700
  		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
  		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
701
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
702
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703
704
705
706
707
708
709
  
  	return 0;
  }
  
  static int
  pipe_read_fasync(int fd, struct file *filp, int on)
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
710
  	struct inode *inode = filp->f_path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
711
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
712
713
714
  	mutex_lock(&inode->i_mutex);
  	retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers);
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
715

60aa49243   Jonathan Corbet   Rationalize fasyn...
716
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
717
718
719
720
721
722
  }
  
  
  static int
  pipe_write_fasync(int fd, struct file *filp, int on)
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
723
  	struct inode *inode = filp->f_path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
724
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
725
726
727
  	mutex_lock(&inode->i_mutex);
  	retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers);
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
728

60aa49243   Jonathan Corbet   Rationalize fasyn...
729
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
730
731
732
733
734
735
  }
  
  
  static int
  pipe_rdwr_fasync(int fd, struct file *filp, int on)
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
736
  	struct inode *inode = filp->f_path.dentry->d_inode;
341b446bc   Ingo Molnar   [PATCH] another r...
737
  	struct pipe_inode_info *pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
738
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
739
  	mutex_lock(&inode->i_mutex);
341b446bc   Ingo Molnar   [PATCH] another r...
740
  	retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
e5bc49ba7   Oleg Nesterov   pipe_rdwr_fasync:...
741
  	if (retval >= 0) {
341b446bc   Ingo Molnar   [PATCH] another r...
742
  		retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
e5bc49ba7   Oleg Nesterov   pipe_rdwr_fasync:...
743
744
745
  		if (retval < 0) /* this can happen only if on == T */
  			fasync_helper(-1, filp, 0, &pipe->fasync_readers);
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
746
  	mutex_unlock(&inode->i_mutex);
60aa49243   Jonathan Corbet   Rationalize fasyn...
747
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
748
749
750
751
752
753
  }
  
  
  static int
  pipe_read_release(struct inode *inode, struct file *filp)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
755
756
757
758
759
  	return pipe_release(inode, 1, 0);
  }
  
  static int
  pipe_write_release(struct inode *inode, struct file *filp)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
760
761
762
763
764
765
766
  	return pipe_release(inode, 0, 1);
  }
  
  static int
  pipe_rdwr_release(struct inode *inode, struct file *filp)
  {
  	int decr, decw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
768
769
770
771
772
773
774
  	decr = (filp->f_mode & FMODE_READ) != 0;
  	decw = (filp->f_mode & FMODE_WRITE) != 0;
  	return pipe_release(inode, decr, decw);
  }
  
  static int
  pipe_read_open(struct inode *inode, struct file *filp)
  {
ad3960243   Earl Chew   fs: pipe.c null p...
775
  	int ret = -ENOENT;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
776
  	mutex_lock(&inode->i_mutex);
ad3960243   Earl Chew   fs: pipe.c null p...
777
778
779
780
781
  
  	if (inode->i_pipe) {
  		ret = 0;
  		inode->i_pipe->readers++;
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
782
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
783

ad3960243   Earl Chew   fs: pipe.c null p...
784
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
785
786
787
788
789
  }
  
  static int
  pipe_write_open(struct inode *inode, struct file *filp)
  {
ad3960243   Earl Chew   fs: pipe.c null p...
790
  	int ret = -ENOENT;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
791
  	mutex_lock(&inode->i_mutex);
ad3960243   Earl Chew   fs: pipe.c null p...
792
793
794
795
796
  
  	if (inode->i_pipe) {
  		ret = 0;
  		inode->i_pipe->writers++;
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
797
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798

ad3960243   Earl Chew   fs: pipe.c null p...
799
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800
801
802
803
804
  }
  
  static int
  pipe_rdwr_open(struct inode *inode, struct file *filp)
  {
ad3960243   Earl Chew   fs: pipe.c null p...
805
  	int ret = -ENOENT;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
806
  	mutex_lock(&inode->i_mutex);
ad3960243   Earl Chew   fs: pipe.c null p...
807
808
809
810
811
812
813
814
  
  	if (inode->i_pipe) {
  		ret = 0;
  		if (filp->f_mode & FMODE_READ)
  			inode->i_pipe->readers++;
  		if (filp->f_mode & FMODE_WRITE)
  			inode->i_pipe->writers++;
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
815
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
816

ad3960243   Earl Chew   fs: pipe.c null p...
817
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
818
819
820
821
822
  }
  
  /*
   * The file_operations structs are not static because they
   * are also used in linux/fs/fifo.c to do operations on FIFOs.
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
823
824
   *
   * Pipes reuse fifos' file_operations structs.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
825
   */
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
826
  const struct file_operations read_pipefifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
827
  	.llseek		= no_llseek,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
828
829
  	.read		= do_sync_read,
  	.aio_read	= pipe_read,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
830
831
  	.write		= bad_pipe_w,
  	.poll		= pipe_poll,
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
832
  	.unlocked_ioctl	= pipe_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833
834
835
836
  	.open		= pipe_read_open,
  	.release	= pipe_read_release,
  	.fasync		= pipe_read_fasync,
  };
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
837
  const struct file_operations write_pipefifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
838
839
  	.llseek		= no_llseek,
  	.read		= bad_pipe_r,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
840
841
  	.write		= do_sync_write,
  	.aio_write	= pipe_write,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
842
  	.poll		= pipe_poll,
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
843
  	.unlocked_ioctl	= pipe_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844
845
846
847
  	.open		= pipe_write_open,
  	.release	= pipe_write_release,
  	.fasync		= pipe_write_fasync,
  };
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
848
  const struct file_operations rdwr_pipefifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
849
  	.llseek		= no_llseek,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
850
851
852
853
  	.read		= do_sync_read,
  	.aio_read	= pipe_read,
  	.write		= do_sync_write,
  	.aio_write	= pipe_write,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
854
  	.poll		= pipe_poll,
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
855
  	.unlocked_ioctl	= pipe_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
857
858
859
  	.open		= pipe_rdwr_open,
  	.release	= pipe_rdwr_release,
  	.fasync		= pipe_rdwr_fasync,
  };
3a326a2ce   Ingo Molnar   [PATCH] introduce...
860
861
  struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
  {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
862
  	struct pipe_inode_info *pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
863

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
864
865
  	pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
  	if (pipe) {
35f3d14db   Jens Axboe   pipe: add support...
866
867
868
869
870
871
872
873
874
  		pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * PIPE_DEF_BUFFERS, GFP_KERNEL);
  		if (pipe->bufs) {
  			init_waitqueue_head(&pipe->wait);
  			pipe->r_counter = pipe->w_counter = 1;
  			pipe->inode = inode;
  			pipe->buffers = PIPE_DEF_BUFFERS;
  			return pipe;
  		}
  		kfree(pipe);
3a326a2ce   Ingo Molnar   [PATCH] introduce...
875
  	}
35f3d14db   Jens Axboe   pipe: add support...
876
  	return NULL;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
877
  }
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
878
  void __free_pipe_info(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879
880
  {
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
881

35f3d14db   Jens Axboe   pipe: add support...
882
  	for (i = 0; i < pipe->buffers; i++) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
883
  		struct pipe_buffer *buf = pipe->bufs + i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
884
  		if (buf->ops)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
885
  			buf->ops->release(pipe, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
886
  	}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
887
888
  	if (pipe->tmp_page)
  		__free_page(pipe->tmp_page);
35f3d14db   Jens Axboe   pipe: add support...
889
  	kfree(pipe->bufs);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
890
  	kfree(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
891
  }
b92ce5589   Jens Axboe   [PATCH] splice: a...
892
893
894
895
896
  void free_pipe_info(struct inode *inode)
  {
  	__free_pipe_info(inode->i_pipe);
  	inode->i_pipe = NULL;
  }
fa3536cc1   Eric Dumazet   [PATCH] Use __rea...
897
  static struct vfsmount *pipe_mnt __read_mostly;
341b446bc   Ingo Molnar   [PATCH] another r...
898

c23fbb6bc   Eric Dumazet   VFS: delay the de...
899
900
901
902
903
904
905
906
  /*
   * 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]",
  				dentry->d_inode->i_ino);
  }
3ba13d179   Al Viro   constify dentry_o...
907
  static const struct dentry_operations pipefs_dentry_operations = {
c23fbb6bc   Eric Dumazet   VFS: delay the de...
908
  	.d_dname	= pipefs_dname,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
909
910
911
912
  };
  
  static struct inode * get_pipe_inode(void)
  {
a209dfc7b   Eric Dumazet   vfs: dont chain p...
913
  	struct inode *inode = new_inode_pseudo(pipe_mnt->mnt_sb);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
914
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
915
916
917
  
  	if (!inode)
  		goto fail_inode;
85fe4025c   Christoph Hellwig   fs: do not assign...
918
  	inode->i_ino = get_next_ino();
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
919
920
  	pipe = alloc_pipe_info(inode);
  	if (!pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
921
  		goto fail_iput;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
922
  	inode->i_pipe = pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
923

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
924
  	pipe->readers = pipe->writers = 1;
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
925
  	inode->i_fop = &rdwr_pipefifo_fops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
926
927
928
929
930
931
932
933
934
  
  	/*
  	 * 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...
935
936
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937
  	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
938

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
939
940
941
942
  	return inode;
  
  fail_iput:
  	iput(inode);
341b446bc   Ingo Molnar   [PATCH] another r...
943

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
944
945
946
  fail_inode:
  	return NULL;
  }
be61a86d7   Ulrich Drepper   flag parameters: ...
947
  struct file *create_write_pipe(int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
948
  {
d6cbd281d   Andi Kleen   [PATCH] Some clea...
949
950
951
  	int err;
  	struct inode *inode;
  	struct file *f;
2c48b9c45   Al Viro   switch alloc_file...
952
  	struct path path;
c23fbb6bc   Eric Dumazet   VFS: delay the de...
953
  	struct qstr name = { .name = "" };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
954

d6cbd281d   Andi Kleen   [PATCH] Some clea...
955
  	err = -ENFILE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
956
957
  	inode = get_pipe_inode();
  	if (!inode)
430e285e0   Dave Hansen   [PATCH] fix up ne...
958
  		goto err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
959

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

2c48b9c45   Al Viro   switch alloc_file...
966
  	d_instantiate(path.dentry, inode);
430e285e0   Dave Hansen   [PATCH] fix up ne...
967
968
  
  	err = -ENFILE;
2c48b9c45   Al Viro   switch alloc_file...
969
  	f = alloc_file(&path, FMODE_WRITE, &write_pipefifo_fops);
430e285e0   Dave Hansen   [PATCH] fix up ne...
970
971
  	if (!f)
  		goto err_dentry;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
972
  	f->f_mapping = inode->i_mapping;
341b446bc   Ingo Molnar   [PATCH] another r...
973

be61a86d7   Ulrich Drepper   flag parameters: ...
974
  	f->f_flags = O_WRONLY | (flags & O_NONBLOCK);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
975
976
977
  	f->f_version = 0;
  
  	return f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
978

430e285e0   Dave Hansen   [PATCH] fix up ne...
979
   err_dentry:
ed1524371   Al Viro   [PATCH] double-fr...
980
  	free_pipe_info(inode);
2c48b9c45   Al Viro   switch alloc_file...
981
  	path_put(&path);
ed1524371   Al Viro   [PATCH] double-fr...
982
  	return ERR_PTR(err);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
983
   err_inode:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
984
985
  	free_pipe_info(inode);
  	iput(inode);
430e285e0   Dave Hansen   [PATCH] fix up ne...
986
   err:
d6cbd281d   Andi Kleen   [PATCH] Some clea...
987
988
989
990
991
  	return ERR_PTR(err);
  }
  
  void free_write_pipe(struct file *f)
  {
5ccac88ee   Al Viro   [PATCH] fix leaks...
992
  	free_pipe_info(f->f_dentry->d_inode);
c8e7f449b   Jan Blunck   [patch 1/4] vfs: ...
993
  	path_put(&f->f_path);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
994
995
  	put_filp(f);
  }
be61a86d7   Ulrich Drepper   flag parameters: ...
996
  struct file *create_read_pipe(struct file *wrf, int flags)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
997
  {
d231412db   Al Viro   switch create_rea...
998
999
1000
  	/* Grab pipe from the writer */
  	struct file *f = alloc_file(&wrf->f_path, FMODE_READ,
  				    &read_pipefifo_fops);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
1001
1002
  	if (!f)
  		return ERR_PTR(-ENFILE);
c8e7f449b   Jan Blunck   [patch 1/4] vfs: ...
1003
  	path_get(&wrf->f_path);
be61a86d7   Ulrich Drepper   flag parameters: ...
1004
  	f->f_flags = O_RDONLY | (flags & O_NONBLOCK);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
1005
1006
1007
  
  	return f;
  }
ed8cae8ba   Ulrich Drepper   flag parameters: ...
1008
  int do_pipe_flags(int *fd, int flags)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
1009
1010
1011
1012
  {
  	struct file *fw, *fr;
  	int error;
  	int fdw, fdr;
be61a86d7   Ulrich Drepper   flag parameters: ...
1013
  	if (flags & ~(O_CLOEXEC | O_NONBLOCK))
ed8cae8ba   Ulrich Drepper   flag parameters: ...
1014
  		return -EINVAL;
be61a86d7   Ulrich Drepper   flag parameters: ...
1015
  	fw = create_write_pipe(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
1016
1017
  	if (IS_ERR(fw))
  		return PTR_ERR(fw);
be61a86d7   Ulrich Drepper   flag parameters: ...
1018
  	fr = create_read_pipe(fw, flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
1019
1020
1021
  	error = PTR_ERR(fr);
  	if (IS_ERR(fr))
  		goto err_write_pipe;
ed8cae8ba   Ulrich Drepper   flag parameters: ...
1022
  	error = get_unused_fd_flags(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
1023
1024
1025
  	if (error < 0)
  		goto err_read_pipe;
  	fdr = error;
ed8cae8ba   Ulrich Drepper   flag parameters: ...
1026
  	error = get_unused_fd_flags(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
1027
1028
1029
  	if (error < 0)
  		goto err_fdr;
  	fdw = error;
157cf649a   Al Viro   sanitize audit_fd...
1030
  	audit_fd_pair(fdr, fdw);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
  	fd_install(fdr, fr);
  	fd_install(fdw, fw);
  	fd[0] = fdr;
  	fd[1] = fdw;
  
  	return 0;
  
   err_fdr:
  	put_unused_fd(fdr);
   err_read_pipe:
c8e7f449b   Jan Blunck   [patch 1/4] vfs: ...
1041
  	path_put(&fr->f_path);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
1042
1043
1044
1045
  	put_filp(fr);
   err_write_pipe:
  	free_write_pipe(fw);
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1046
1047
1048
  }
  
  /*
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1049
1050
1051
   * 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...
1052
  SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1053
1054
1055
  {
  	int fd[2];
  	int error;
ed8cae8ba   Ulrich Drepper   flag parameters: ...
1056
  	error = do_pipe_flags(fd, flags);
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1057
  	if (!error) {
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
1058
1059
1060
  		if (copy_to_user(fildes, fd, sizeof(fd))) {
  			sys_close(fd[0]);
  			sys_close(fd[1]);
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1061
  			error = -EFAULT;
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
1062
  		}
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1063
1064
1065
  	}
  	return error;
  }
2b6642199   Heiko Carstens   [CVE-2009-0029] S...
1066
  SYSCALL_DEFINE1(pipe, int __user *, fildes)
ed8cae8ba   Ulrich Drepper   flag parameters: ...
1067
1068
1069
  {
  	return sys_pipe2(fildes, 0);
  }
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1070
  /*
35f3d14db   Jens Axboe   pipe: add support...
1071
1072
1073
   * Allocate a new array of pipe buffers and copy the info over. Returns the
   * pipe size if successful, or return -ERROR on error.
   */
b9598db34   Jens Axboe   pipe: make F_{GET...
1074
  static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages)
35f3d14db   Jens Axboe   pipe: add support...
1075
1076
1077
1078
  {
  	struct pipe_buffer *bufs;
  
  	/*
35f3d14db   Jens Axboe   pipe: add support...
1079
1080
1081
1082
1083
  	 * 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.
  	 */
b9598db34   Jens Axboe   pipe: make F_{GET...
1084
  	if (nr_pages < pipe->nrbufs)
35f3d14db   Jens Axboe   pipe: add support...
1085
  		return -EBUSY;
2ccd4f4d4   Sasha Levin   pipe: fail cleanl...
1086
  	bufs = kcalloc(nr_pages, sizeof(*bufs), GFP_KERNEL | __GFP_NOWARN);
35f3d14db   Jens Axboe   pipe: add support...
1087
1088
1089
1090
1091
1092
1093
1094
  	if (unlikely(!bufs))
  		return -ENOMEM;
  
  	/*
  	 * 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...
1095
1096
  		unsigned int tail;
  		unsigned int head;
35f3d14db   Jens Axboe   pipe: add support...
1097

1d862f412   Miklos Szeredi   pipe: fix pipe bu...
1098
1099
1100
1101
1102
1103
1104
  		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...
1105
1106
1107
  		if (head)
  			memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer));
  		if (tail)
1d862f412   Miklos Szeredi   pipe: fix pipe bu...
1108
  			memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer));
35f3d14db   Jens Axboe   pipe: add support...
1109
1110
1111
1112
1113
  	}
  
  	pipe->curbuf = 0;
  	kfree(pipe->bufs);
  	pipe->bufs = bufs;
b9598db34   Jens Axboe   pipe: make F_{GET...
1114
1115
  	pipe->buffers = nr_pages;
  	return nr_pages * PAGE_SIZE;
35f3d14db   Jens Axboe   pipe: add support...
1116
  }
ff9da691c   Jens Axboe   pipe: change /pro...
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
  /*
   * 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;
  }
  
  /*
   * 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...
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
  /*
   * 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)
  {
  	struct inode *i = file->f_path.dentry->d_inode;
  
  	return S_ISFIFO(i->i_mode) ? i->i_pipe : NULL;
  }
35f3d14db   Jens Axboe   pipe: add support...
1156
1157
1158
1159
  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_...
1160
  	pipe = get_pipe_info(file);
35f3d14db   Jens Axboe   pipe: add support...
1161
1162
1163
1164
1165
1166
  	if (!pipe)
  		return -EBADF;
  
  	mutex_lock(&pipe->inode->i_mutex);
  
  	switch (cmd) {
b9598db34   Jens Axboe   pipe: make F_{GET...
1167
  	case F_SETPIPE_SZ: {
ff9da691c   Jens Axboe   pipe: change /pro...
1168
  		unsigned int size, nr_pages;
b9598db34   Jens Axboe   pipe: make F_{GET...
1169

ff9da691c   Jens Axboe   pipe: change /pro...
1170
1171
  		size = round_pipe_size(arg);
  		nr_pages = size >> PAGE_SHIFT;
b9598db34   Jens Axboe   pipe: make F_{GET...
1172

6db40cf04   Miklos Szeredi   pipe: fix check i...
1173
1174
1175
  		ret = -EINVAL;
  		if (!nr_pages)
  			goto out;
ff9da691c   Jens Axboe   pipe: change /pro...
1176
  		if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) {
b4ca76157   Jens Axboe   Merge branch 'mas...
1177
  			ret = -EPERM;
cc967be54   Julia Lawall   fs: Add missing m...
1178
  			goto out;
cc967be54   Julia Lawall   fs: Add missing m...
1179
  		}
ff9da691c   Jens Axboe   pipe: change /pro...
1180
  		ret = pipe_set_size(pipe, nr_pages);
35f3d14db   Jens Axboe   pipe: add support...
1181
  		break;
b9598db34   Jens Axboe   pipe: make F_{GET...
1182
  		}
35f3d14db   Jens Axboe   pipe: add support...
1183
  	case F_GETPIPE_SZ:
b9598db34   Jens Axboe   pipe: make F_{GET...
1184
  		ret = pipe->buffers * PAGE_SIZE;
35f3d14db   Jens Axboe   pipe: add support...
1185
1186
1187
1188
1189
  		break;
  	default:
  		ret = -EINVAL;
  		break;
  	}
cc967be54   Julia Lawall   fs: Add missing m...
1190
  out:
35f3d14db   Jens Axboe   pipe: add support...
1191
1192
1193
  	mutex_unlock(&pipe->inode->i_mutex);
  	return ret;
  }
ff0c7d15f   Nick Piggin   fs: avoid inode R...
1194
1195
  static const struct super_operations pipefs_ops = {
  	.destroy_inode = free_inode_nonrcu,
d70ef97ba   Pavel Emelyanov   fs/pipe.c: add ->...
1196
  	.statfs = simple_statfs,
ff0c7d15f   Nick Piggin   fs: avoid inode R...
1197
  };
35f3d14db   Jens Axboe   pipe: add support...
1198
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1199
1200
1201
1202
1203
   * 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...
1204
1205
  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
1206
  {
c74a1cbb3   Al Viro   pass default dent...
1207
1208
  	return mount_pseudo(fs_type, "pipe:", &pipefs_ops,
  			&pipefs_dentry_operations, PIPEFS_MAGIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1209
1210
1211
1212
  }
  
  static struct file_system_type pipe_fs_type = {
  	.name		= "pipefs",
51139adac   Al Viro   convert get_sb_ps...
1213
  	.mount		= pipefs_mount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1214
1215
1216
1217
1218
1219
  	.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...
1220

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1221
1222
1223
1224
1225
1226
1227
1228
1229
  	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
1230
  fs_initcall(init_pipe_fs);