Blame view

fs/pipe.c 29.2 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>
a27bb332c   Kent Overstreet   aio: don't includ...
24
  #include <linux/aio.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
40
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
42
43
44
45
46
47
48
49
50
51
52
53
   * 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...
54
55
  static void pipe_lock_nested(struct pipe_inode_info *pipe, int subclass)
  {
6447a3cf1   Al Viro   get rid of pipe->...
56
  	if (pipe->files)
72b0d9aac   Al Viro   pipe: don't use -...
57
  		mutex_lock_nested(&pipe->mutex, subclass);
61e0d47c3   Miklos Szeredi   splice: add helpe...
58
59
60
61
62
63
64
65
66
67
68
69
70
  }
  
  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->...
71
  	if (pipe->files)
72b0d9aac   Al Viro   pipe: don't use -...
72
  		mutex_unlock(&pipe->mutex);
61e0d47c3   Miklos Szeredi   splice: add helpe...
73
74
  }
  EXPORT_SYMBOL(pipe_unlock);
ebec73f47   Al Viro   introduce variant...
75
76
77
78
79
80
81
82
83
  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...
84
85
86
87
88
89
90
91
92
  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...
93
94
  		pipe_lock_nested(pipe2, I_MUTEX_PARENT);
  		pipe_lock_nested(pipe1, I_MUTEX_CHILD);
61e0d47c3   Miklos Szeredi   splice: add helpe...
95
96
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
  /* Drop the inode semaphore and wait for a pipe event, atomically */
3a326a2ce   Ingo Molnar   [PATCH] introduce...
98
  void pipe_wait(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
100
  {
  	DEFINE_WAIT(wait);
d79fc0fc6   Ingo Molnar   [PATCH] sched: TA...
101
102
103
104
  	/*
  	 * Pipes are system-local resources, so sleeping on them
  	 * is considered a noninteractive wait:
  	 */
af9272326   Mike Galbraith   sched: cleanup, r...
105
  	prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE);
61e0d47c3   Miklos Szeredi   splice: add helpe...
106
  	pipe_unlock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
  	schedule();
3a326a2ce   Ingo Molnar   [PATCH] introduce...
108
  	finish_wait(&pipe->wait, &wait);
61e0d47c3   Miklos Szeredi   splice: add helpe...
109
  	pipe_lock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
  }
858119e15   Arjan van de Ven   [PATCH] Unlinline...
111
  static int
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
112
113
  pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len,
  			int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
115
116
117
118
119
120
  {
  	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...
121
122
123
124
125
126
127
  		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
128
129
130
131
132
133
134
  		to += copy;
  		len -= copy;
  		iov->iov_base += copy;
  		iov->iov_len -= copy;
  	}
  	return 0;
  }
858119e15   Arjan van de Ven   [PATCH] Unlinline...
135
  static int
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
136
137
  pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len,
  		      int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
140
141
142
143
144
  {
  	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...
145
146
147
148
149
150
151
  		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
152
153
154
155
156
157
158
  		from += copy;
  		len -= copy;
  		iov->iov_base += copy;
  		iov->iov_len -= copy;
  	}
  	return 0;
  }
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
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
189
190
191
192
193
194
195
196
197
198
  /*
   * 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...
199
200
  static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
  				  struct pipe_buffer *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
  {
  	struct page *page = buf->page;
5274f052e   Jens Axboe   [PATCH] Introduce...
203
204
205
  	/*
  	 * 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...
206
  	 * allocation cache. (Otherwise just release our reference to it)
5274f052e   Jens Axboe   [PATCH] Introduce...
207
  	 */
341b446bc   Ingo Molnar   [PATCH] another r...
208
  	if (page_count(page) == 1 && !pipe->tmp_page)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
209
  		pipe->tmp_page = page;
341b446bc   Ingo Molnar   [PATCH] another r...
210
211
  	else
  		page_cache_release(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
  }
0845718da   Jens Axboe   pipe: add documen...
213
214
215
216
217
218
219
220
  /**
   * 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...
221
   *	pipe_buffer passed in @buf. If @atomic is set, an atomic map is provided
0845718da   Jens Axboe   pipe: add documen...
222
223
224
   *	and the caller has to be careful not to fault before calling
   *	the unmap function.
   *
2164d3344   Cong Wang   pipe: remove KM_U...
225
   *	Note that this function calls kmap_atomic() if @atomic != 0.
0845718da   Jens Axboe   pipe: add documen...
226
   */
f84d75199   Jens Axboe   [PATCH] pipe: int...
227
  void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
228
  			   struct pipe_buffer *buf, int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
  {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
230
231
  	if (atomic) {
  		buf->flags |= PIPE_BUF_FLAG_ATOMIC;
e8e3c3d66   Cong Wang   fs: remove the se...
232
  		return kmap_atomic(buf->page);
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
233
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
  	return kmap(buf->page);
  }
51921cb74   Miklos Szeredi   mm: export generi...
236
  EXPORT_SYMBOL(generic_pipe_buf_map);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237

0845718da   Jens Axboe   pipe: add documen...
238
239
240
241
242
243
244
245
246
  /**
   * 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...
247
  void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
248
  			    struct pipe_buffer *buf, void *map_data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
  {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
250
251
  	if (buf->flags & PIPE_BUF_FLAG_ATOMIC) {
  		buf->flags &= ~PIPE_BUF_FLAG_ATOMIC;
e8e3c3d66   Cong Wang   fs: remove the se...
252
  		kunmap_atomic(map_data);
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
253
254
  	} else
  		kunmap(buf->page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
  }
51921cb74   Miklos Szeredi   mm: export generi...
256
  EXPORT_SYMBOL(generic_pipe_buf_unmap);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257

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

0845718da   Jens Axboe   pipe: add documen...
288
  /**
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
289
   * generic_pipe_buf_get - get a reference to a &struct pipe_buffer
0845718da   Jens Axboe   pipe: add documen...
290
291
292
293
294
295
296
297
298
   * @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...
299
300
301
  {
  	page_cache_get(buf->page);
  }
51921cb74   Miklos Szeredi   mm: export generi...
302
  EXPORT_SYMBOL(generic_pipe_buf_get);
70524490e   Jens Axboe   [PATCH] splice: a...
303

0845718da   Jens Axboe   pipe: add documen...
304
305
  /**
   * generic_pipe_buf_confirm - verify contents of the pipe buffer
79685b8de   Randy Dunlap   docbook: add pipe...
306
   * @info:	the pipe that the buffer belongs to
0845718da   Jens Axboe   pipe: add documen...
307
308
309
310
311
312
   * @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 ...
313
314
  int generic_pipe_buf_confirm(struct pipe_inode_info *info,
  			     struct pipe_buffer *buf)
f84d75199   Jens Axboe   [PATCH] pipe: int...
315
316
317
  {
  	return 0;
  }
51921cb74   Miklos Szeredi   mm: export generi...
318
  EXPORT_SYMBOL(generic_pipe_buf_confirm);
f84d75199   Jens Axboe   [PATCH] pipe: int...
319

6818173bd   Miklos Szeredi   splice: implement...
320
321
322
323
324
325
326
327
328
329
330
331
332
  /**
   * 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...
333
  EXPORT_SYMBOL(generic_pipe_buf_release);
6818173bd   Miklos Szeredi   splice: implement...
334

d4c3cca94   Eric Dumazet   [PATCH] constify ...
335
  static const struct pipe_buf_operations anon_pipe_buf_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
  	.can_merge = 1,
f84d75199   Jens Axboe   [PATCH] pipe: int...
337
338
  	.map = generic_pipe_buf_map,
  	.unmap = generic_pipe_buf_unmap,
cac36bb06   Jens Axboe   pipe: change the ...
339
  	.confirm = generic_pipe_buf_confirm,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
  	.release = anon_pipe_buf_release,
330ab7161   Jens Axboe   [PATCH] vmsplice:...
341
  	.steal = generic_pipe_buf_steal,
f84d75199   Jens Axboe   [PATCH] pipe: int...
342
  	.get = generic_pipe_buf_get,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
343
  };
9883035ae   Linus Torvalds   pipes: add a "pac...
344
345
346
347
348
349
350
351
352
  static const struct pipe_buf_operations packet_pipe_buf_ops = {
  	.can_merge = 0,
  	.map = generic_pipe_buf_map,
  	.unmap = generic_pipe_buf_unmap,
  	.confirm = generic_pipe_buf_confirm,
  	.release = anon_pipe_buf_release,
  	.steal = generic_pipe_buf_steal,
  	.get = generic_pipe_buf_get,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
  static ssize_t
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
354
355
  pipe_read(struct kiocb *iocb, const struct iovec *_iov,
  	   unsigned long nr_segs, loff_t pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
  {
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
357
  	struct file *filp = iocb->ki_filp;
de32ec4cf   Al Viro   pipe: set file->p...
358
  	struct pipe_inode_info *pipe = filp->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359
360
361
362
363
364
365
366
367
368
369
370
  	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;
ebec73f47   Al Viro   introduce variant...
371
  	__pipe_lock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
  	for (;;) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
373
  		int bufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
  		if (bufs) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
375
376
  			int curbuf = pipe->curbuf;
  			struct pipe_buffer *buf = pipe->bufs + curbuf;
d4c3cca94   Eric Dumazet   [PATCH] constify ...
377
  			const struct pipe_buf_operations *ops = buf->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
379
  			void *addr;
  			size_t chars = buf->len;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
380
  			int error, atomic;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
381
382
383
  
  			if (chars > total_len)
  				chars = total_len;
cac36bb06   Jens Axboe   pipe: change the ...
384
  			error = ops->confirm(pipe, buf);
f84d75199   Jens Axboe   [PATCH] pipe: int...
385
  			if (error) {
5274f052e   Jens Axboe   [PATCH] Introduce...
386
  				if (!ret)
e5953cbdf   Nicolas Kaiser   pipe: fix failure...
387
  					ret = error;
5274f052e   Jens Axboe   [PATCH] Introduce...
388
389
  				break;
  			}
f84d75199   Jens Axboe   [PATCH] pipe: int...
390

f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
391
392
393
394
395
  			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
396
  			if (unlikely(error)) {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
397
398
399
400
401
402
403
  				/*
  				 * Just retry with the slow path if we failed.
  				 */
  				if (atomic) {
  					atomic = 0;
  					goto redo;
  				}
341b446bc   Ingo Molnar   [PATCH] another r...
404
  				if (!ret)
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
405
  					ret = error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
407
408
409
410
  				break;
  			}
  			ret += chars;
  			buf->offset += chars;
  			buf->len -= chars;
9883035ae   Linus Torvalds   pipes: add a "pac...
411
412
413
414
415
416
  
  			/* 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
417
418
  			if (!buf->len) {
  				buf->ops = NULL;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
419
  				ops->release(pipe, buf);
35f3d14db   Jens Axboe   pipe: add support...
420
  				curbuf = (curbuf + 1) & (pipe->buffers - 1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
421
422
  				pipe->curbuf = curbuf;
  				pipe->nrbufs = --bufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
424
425
426
427
428
429
430
  				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...
431
  		if (!pipe->writers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
432
  			break;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
433
  		if (!pipe->waiting_writers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
435
436
437
438
439
440
441
442
443
444
445
446
  			/* 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...
447
448
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
450
451
  			break;
  		}
  		if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
452
  			wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
453
   			kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
455
  		pipe_wait(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
  	}
ebec73f47   Al Viro   introduce variant...
457
  	__pipe_unlock(pipe);
341b446bc   Ingo Molnar   [PATCH] another r...
458
459
  
  	/* Signal writers asynchronously that there is more room. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
  	if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
461
  		wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
462
  		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
464
465
466
467
  	}
  	if (ret > 0)
  		file_accessed(filp);
  	return ret;
  }
9883035ae   Linus Torvalds   pipes: add a "pac...
468
469
470
471
  static inline int is_packetized(struct file *file)
  {
  	return (file->f_flags & O_DIRECT) != 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
  static ssize_t
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
473
474
  pipe_write(struct kiocb *iocb, const struct iovec *_iov,
  	    unsigned long nr_segs, loff_t ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
  {
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
476
  	struct file *filp = iocb->ki_filp;
de32ec4cf   Al Viro   pipe: set file->p...
477
  	struct pipe_inode_info *pipe = filp->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
478
479
480
481
482
483
484
485
486
487
488
489
490
  	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;
ebec73f47   Al Viro   introduce variant...
491
  	__pipe_lock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
493
  	if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
495
496
497
498
499
500
  		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...
501
  	if (pipe->nrbufs && chars != 0) {
341b446bc   Ingo Molnar   [PATCH] another r...
502
  		int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
35f3d14db   Jens Axboe   pipe: add support...
503
  							(pipe->buffers - 1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
504
  		struct pipe_buffer *buf = pipe->bufs + lastbuf;
d4c3cca94   Eric Dumazet   [PATCH] constify ...
505
  		const struct pipe_buf_operations *ops = buf->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
  		int offset = buf->offset + buf->len;
341b446bc   Ingo Molnar   [PATCH] another r...
507

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

cac36bb06   Jens Axboe   pipe: change the ...
512
  			error = ops->confirm(pipe, buf);
f84d75199   Jens Axboe   [PATCH] pipe: int...
513
  			if (error)
5274f052e   Jens Axboe   [PATCH] Introduce...
514
  				goto out;
f84d75199   Jens Axboe   [PATCH] pipe: int...
515

f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
516
517
518
  			iov_fault_in_pages_read(iov, chars);
  redo1:
  			addr = ops->map(pipe, buf, atomic);
5274f052e   Jens Axboe   [PATCH] Introduce...
519
  			error = pipe_iov_copy_from_user(offset + addr, iov,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
520
521
  							chars, atomic);
  			ops->unmap(pipe, buf, addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
523
  			ret = error;
  			do_wakeup = 1;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
524
525
526
527
528
  			if (error) {
  				if (atomic) {
  					atomic = 0;
  					goto redo1;
  				}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
529
  				goto out;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
530
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
532
533
534
535
536
537
538
539
540
  			buf->len += chars;
  			total_len -= chars;
  			ret = chars;
  			if (!total_len)
  				goto out;
  		}
  	}
  
  	for (;;) {
  		int bufs;
341b446bc   Ingo Molnar   [PATCH] another r...
541

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
542
  		if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543
  			send_sig(SIGPIPE, current, 0);
341b446bc   Ingo Molnar   [PATCH] another r...
544
545
  			if (!ret)
  				ret = -EPIPE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
546
547
  			break;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
548
  		bufs = pipe->nrbufs;
35f3d14db   Jens Axboe   pipe: add support...
549
550
  		if (bufs < pipe->buffers) {
  			int newbuf = (pipe->curbuf + bufs) & (pipe->buffers-1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
551
552
  			struct pipe_buffer *buf = pipe->bufs + newbuf;
  			struct page *page = pipe->tmp_page;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
553
554
  			char *src;
  			int error, atomic = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555
556
557
558
559
560
561
  
  			if (!page) {
  				page = alloc_page(GFP_HIGHUSER);
  				if (unlikely(!page)) {
  					ret = ret ? : -ENOMEM;
  					break;
  				}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
562
  				pipe->tmp_page = page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
  			}
341b446bc   Ingo Molnar   [PATCH] another r...
564
  			/* Always wake up, even if the copy fails. Otherwise
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
565
566
567
568
569
570
571
572
  			 * 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...
573
574
575
  			iov_fault_in_pages_read(iov, chars);
  redo2:
  			if (atomic)
e8e3c3d66   Cong Wang   fs: remove the se...
576
  				src = kmap_atomic(page);
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
577
578
579
580
581
582
  			else
  				src = kmap(page);
  
  			error = pipe_iov_copy_from_user(src, iov, chars,
  							atomic);
  			if (atomic)
e8e3c3d66   Cong Wang   fs: remove the se...
583
  				kunmap_atomic(src);
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
584
585
  			else
  				kunmap(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
586
  			if (unlikely(error)) {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
587
588
589
590
  				if (atomic) {
  					atomic = 0;
  					goto redo2;
  				}
341b446bc   Ingo Molnar   [PATCH] another r...
591
  				if (!ret)
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
592
  					ret = error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
594
595
596
597
598
599
600
601
  				break;
  			}
  			ret += chars;
  
  			/* Insert it into the buffer array */
  			buf->page = page;
  			buf->ops = &anon_pipe_buf_ops;
  			buf->offset = 0;
  			buf->len = chars;
9883035ae   Linus Torvalds   pipes: add a "pac...
602
603
604
605
606
  			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...
607
608
  			pipe->nrbufs = ++bufs;
  			pipe->tmp_page = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
610
611
612
613
  
  			total_len -= chars;
  			if (!total_len)
  				break;
  		}
35f3d14db   Jens Axboe   pipe: add support...
614
  		if (bufs < pipe->buffers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
615
616
  			continue;
  		if (filp->f_flags & O_NONBLOCK) {
341b446bc   Ingo Molnar   [PATCH] another r...
617
618
  			if (!ret)
  				ret = -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619
620
621
  			break;
  		}
  		if (signal_pending(current)) {
341b446bc   Ingo Molnar   [PATCH] another r...
622
623
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624
625
626
  			break;
  		}
  		if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
627
  			wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
628
  			kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
629
630
  			do_wakeup = 0;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
631
632
633
  		pipe->waiting_writers++;
  		pipe_wait(pipe);
  		pipe->waiting_writers--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
634
635
  	}
  out:
ebec73f47   Al Viro   introduce variant...
636
  	__pipe_unlock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
637
  	if (do_wakeup) {
28e58ee8c   Linus Torvalds   Fix broken "pipe:...
638
  		wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
639
  		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
640
  	}
c3b2da314   Josef Bacik   fs: introduce ino...
641
642
643
644
645
  	if (ret > 0) {
  		int err = file_update_time(filp);
  		if (err)
  			ret = err;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
647
  	return ret;
  }
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
648
  static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
649
  {
de32ec4cf   Al Viro   pipe: set file->p...
650
  	struct pipe_inode_info *pipe = filp->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
652
653
654
  	int count, buf, nrbufs;
  
  	switch (cmd) {
  		case FIONREAD:
ebec73f47   Al Viro   introduce variant...
655
  			__pipe_lock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
  			count = 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
657
658
  			buf = pipe->curbuf;
  			nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
659
  			while (--nrbufs >= 0) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
660
  				count += pipe->bufs[buf].len;
35f3d14db   Jens Axboe   pipe: add support...
661
  				buf = (buf+1) & (pipe->buffers - 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
  			}
ebec73f47   Al Viro   introduce variant...
663
  			__pipe_unlock(pipe);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
664

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
665
666
  			return put_user(count, (int __user *)arg);
  		default:
46ce341b2   Will Deacon   pipe: return -ENO...
667
  			return -ENOIOCTLCMD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
669
670
671
672
673
674
675
  	}
  }
  
  /* 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...
676
  	struct pipe_inode_info *pipe = filp->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
677
  	int nrbufs;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
678
  	poll_wait(filp, &pipe->wait, wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
679
680
  
  	/* Reading only -- no need for acquiring the semaphore.  */
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
681
  	nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
682
683
684
  	mask = 0;
  	if (filp->f_mode & FMODE_READ) {
  		mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
685
  		if (!pipe->writers && filp->f_version != pipe->w_counter)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
686
687
688
689
  			mask |= POLLHUP;
  	}
  
  	if (filp->f_mode & FMODE_WRITE) {
35f3d14db   Jens Axboe   pipe: add support...
690
  		mask |= (nrbufs < pipe->buffers) ? POLLOUT | POLLWRNORM : 0;
5e5d7a222   Pekka Enberg   [PATCH] pipe: rem...
691
692
693
694
  		/*
  		 * 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...
695
  		if (!pipe->readers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
696
697
698
699
700
  			mask |= POLLERR;
  	}
  
  	return mask;
  }
b0d8d2292   Linus Torvalds   vfs: fix subtle u...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
  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
715
  static int
599a0ac14   Al Viro   pipe: fold file_o...
716
  pipe_release(struct inode *inode, struct file *file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
717
  {
b0d8d2292   Linus Torvalds   vfs: fix subtle u...
718
  	struct pipe_inode_info *pipe = file->private_data;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
719

ebec73f47   Al Viro   introduce variant...
720
  	__pipe_lock(pipe);
599a0ac14   Al Viro   pipe: fold file_o...
721
722
723
724
  	if (file->f_mode & FMODE_READ)
  		pipe->readers--;
  	if (file->f_mode & FMODE_WRITE)
  		pipe->writers--;
341b446bc   Ingo Molnar   [PATCH] another r...
725

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

b0d8d2292   Linus Torvalds   vfs: fix subtle u...
733
  	put_pipe_info(inode, pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
734
735
736
737
  	return 0;
  }
  
  static int
599a0ac14   Al Viro   pipe: fold file_o...
738
  pipe_fasync(int fd, struct file *filp, int on)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739
  {
de32ec4cf   Al Viro   pipe: set file->p...
740
  	struct pipe_inode_info *pipe = filp->private_data;
599a0ac14   Al Viro   pipe: fold file_o...
741
  	int retval = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
742

ebec73f47   Al Viro   introduce variant...
743
  	__pipe_lock(pipe);
599a0ac14   Al Viro   pipe: fold file_o...
744
745
746
  	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...
747
  		retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
599a0ac14   Al Viro   pipe: fold file_o...
748
749
  		if (retval < 0 && (filp->f_mode & FMODE_READ))
  			/* this can happen only if on == T */
e5bc49ba7   Oleg Nesterov   pipe_rdwr_fasync:...
750
751
  			fasync_helper(-1, filp, 0, &pipe->fasync_readers);
  	}
ebec73f47   Al Viro   introduce variant...
752
  	__pipe_unlock(pipe);
60aa49243   Jonathan Corbet   Rationalize fasyn...
753
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
  }
7bee130e2   Al Viro   get rid of alloc_...
755
  struct pipe_inode_info *alloc_pipe_info(void)
3a326a2ce   Ingo Molnar   [PATCH] introduce...
756
  {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
757
  	struct pipe_inode_info *pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
758

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
759
760
  	pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
  	if (pipe) {
35f3d14db   Jens Axboe   pipe: add support...
761
762
763
764
  		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;
35f3d14db   Jens Axboe   pipe: add support...
765
  			pipe->buffers = PIPE_DEF_BUFFERS;
72b0d9aac   Al Viro   pipe: don't use -...
766
  			mutex_init(&pipe->mutex);
35f3d14db   Jens Axboe   pipe: add support...
767
768
769
  			return pipe;
  		}
  		kfree(pipe);
3a326a2ce   Ingo Molnar   [PATCH] introduce...
770
  	}
35f3d14db   Jens Axboe   pipe: add support...
771
  	return NULL;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
772
  }
4b8a8f1e4   Al Viro   get rid of the la...
773
  void free_pipe_info(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
774
775
  {
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
776

35f3d14db   Jens Axboe   pipe: add support...
777
  	for (i = 0; i < pipe->buffers; i++) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
778
  		struct pipe_buffer *buf = pipe->bufs + i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779
  		if (buf->ops)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
780
  			buf->ops->release(pipe, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
781
  	}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
782
783
  	if (pipe->tmp_page)
  		__free_page(pipe->tmp_page);
35f3d14db   Jens Axboe   pipe: add support...
784
  	kfree(pipe->bufs);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
785
  	kfree(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
786
  }
fa3536cc1   Eric Dumazet   [PATCH] Use __rea...
787
  static struct vfsmount *pipe_mnt __read_mostly;
341b446bc   Ingo Molnar   [PATCH] another r...
788

c23fbb6bc   Eric Dumazet   VFS: delay the de...
789
790
791
792
793
794
795
796
  /*
   * 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...
797
  static const struct dentry_operations pipefs_dentry_operations = {
c23fbb6bc   Eric Dumazet   VFS: delay the de...
798
  	.d_dname	= pipefs_dname,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
799
800
801
802
  };
  
  static struct inode * get_pipe_inode(void)
  {
a209dfc7b   Eric Dumazet   vfs: dont chain p...
803
  	struct inode *inode = new_inode_pseudo(pipe_mnt->mnt_sb);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
804
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
806
807
  
  	if (!inode)
  		goto fail_inode;
85fe4025c   Christoph Hellwig   fs: do not assign...
808
  	inode->i_ino = get_next_ino();
7bee130e2   Al Viro   get rid of alloc_...
809
  	pipe = alloc_pipe_info();
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
810
  	if (!pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
811
  		goto fail_iput;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
812

ba5bb1473   Al Viro   pipe: take alloca...
813
814
  	inode->i_pipe = pipe;
  	pipe->files = 2;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
815
  	pipe->readers = pipe->writers = 1;
599a0ac14   Al Viro   pipe: fold file_o...
816
  	inode->i_fop = &pipefifo_fops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
817
818
819
820
821
822
823
824
825
  
  	/*
  	 * 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...
826
827
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
  	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
829

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
830
831
832
833
  	return inode;
  
  fail_iput:
  	iput(inode);
341b446bc   Ingo Molnar   [PATCH] another r...
834

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
835
836
837
  fail_inode:
  	return NULL;
  }
e4fad8e5d   Al Viro   consolidate pipe ...
838
  int create_pipe_files(struct file **res, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
839
  {
d6cbd281d   Andi Kleen   [PATCH] Some clea...
840
  	int err;
e4fad8e5d   Al Viro   consolidate pipe ...
841
  	struct inode *inode = get_pipe_inode();
d6cbd281d   Andi Kleen   [PATCH] Some clea...
842
  	struct file *f;
2c48b9c45   Al Viro   switch alloc_file...
843
  	struct path path;
e4fad8e5d   Al Viro   consolidate pipe ...
844
  	static struct qstr name = { .name = "" };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
846
  	if (!inode)
e4fad8e5d   Al Viro   consolidate pipe ...
847
  		return -ENFILE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
848

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

2c48b9c45   Al Viro   switch alloc_file...
855
  	d_instantiate(path.dentry, inode);
430e285e0   Dave Hansen   [PATCH] fix up ne...
856
857
  
  	err = -ENFILE;
599a0ac14   Al Viro   pipe: fold file_o...
858
  	f = alloc_file(&path, FMODE_WRITE, &pipefifo_fops);
39b652527   Anatol Pomozov   fs: Preserve erro...
859
  	if (IS_ERR(f))
430e285e0   Dave Hansen   [PATCH] fix up ne...
860
  		goto err_dentry;
341b446bc   Ingo Molnar   [PATCH] another r...
861

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

599a0ac14   Al Viro   pipe: fold file_o...
865
  	res[0] = alloc_file(&path, FMODE_READ, &pipefifo_fops);
39b652527   Anatol Pomozov   fs: Preserve erro...
866
  	if (IS_ERR(res[0]))
e4fad8e5d   Al Viro   consolidate pipe ...
867
868
869
  		goto err_file;
  
  	path_get(&path);
de32ec4cf   Al Viro   pipe: set file->p...
870
  	res[0]->private_data = inode->i_pipe;
e4fad8e5d   Al Viro   consolidate pipe ...
871
872
873
  	res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK);
  	res[1] = f;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874

e4fad8e5d   Al Viro   consolidate pipe ...
875
876
877
  err_file:
  	put_filp(f);
  err_dentry:
4b8a8f1e4   Al Viro   get rid of the la...
878
  	free_pipe_info(inode->i_pipe);
2c48b9c45   Al Viro   switch alloc_file...
879
  	path_put(&path);
e4fad8e5d   Al Viro   consolidate pipe ...
880
  	return err;
ed1524371   Al Viro   [PATCH] double-fr...
881

e4fad8e5d   Al Viro   consolidate pipe ...
882
  err_inode:
4b8a8f1e4   Al Viro   get rid of the la...
883
  	free_pipe_info(inode->i_pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
884
  	iput(inode);
e4fad8e5d   Al Viro   consolidate pipe ...
885
  	return err;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
886
  }
5b249b1b0   Al Viro   pipe(2) - race-fr...
887
  static int __do_pipe_flags(int *fd, struct file **files, int flags)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
888
  {
d6cbd281d   Andi Kleen   [PATCH] Some clea...
889
890
  	int error;
  	int fdw, fdr;
9883035ae   Linus Torvalds   pipes: add a "pac...
891
  	if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
ed8cae8ba   Ulrich Drepper   flag parameters: ...
892
  		return -EINVAL;
e4fad8e5d   Al Viro   consolidate pipe ...
893
894
895
  	error = create_pipe_files(files, flags);
  	if (error)
  		return error;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
896

ed8cae8ba   Ulrich Drepper   flag parameters: ...
897
  	error = get_unused_fd_flags(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
898
899
900
  	if (error < 0)
  		goto err_read_pipe;
  	fdr = error;
ed8cae8ba   Ulrich Drepper   flag parameters: ...
901
  	error = get_unused_fd_flags(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
902
903
904
  	if (error < 0)
  		goto err_fdr;
  	fdw = error;
157cf649a   Al Viro   sanitize audit_fd...
905
  	audit_fd_pair(fdr, fdw);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
906
907
  	fd[0] = fdr;
  	fd[1] = fdw;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
908
909
910
911
912
  	return 0;
  
   err_fdr:
  	put_unused_fd(fdr);
   err_read_pipe:
e4fad8e5d   Al Viro   consolidate pipe ...
913
914
  	fput(files[0]);
  	fput(files[1]);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
915
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
916
  }
5b249b1b0   Al Viro   pipe(2) - race-fr...
917
918
919
920
921
922
923
924
925
926
  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
927
  /*
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
928
929
930
   * 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...
931
  SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
932
  {
5b249b1b0   Al Viro   pipe(2) - race-fr...
933
  	struct file *files[2];
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
934
935
  	int fd[2];
  	int error;
5b249b1b0   Al Viro   pipe(2) - race-fr...
936
  	error = __do_pipe_flags(fd, files, flags);
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
937
  	if (!error) {
5b249b1b0   Al Viro   pipe(2) - race-fr...
938
939
940
941
942
  		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...
943
  			error = -EFAULT;
5b249b1b0   Al Viro   pipe(2) - race-fr...
944
945
946
  		} else {
  			fd_install(fd[0], files[0]);
  			fd_install(fd[1], files[1]);
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
947
  		}
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
948
949
950
  	}
  	return error;
  }
2b6642199   Heiko Carstens   [CVE-2009-0029] S...
951
  SYSCALL_DEFINE1(pipe, int __user *, fildes)
ed8cae8ba   Ulrich Drepper   flag parameters: ...
952
953
954
  {
  	return sys_pipe2(fildes, 0);
  }
fc7478a2b   Al Viro   pipe: switch wait...
955
  static int wait_for_partner(struct pipe_inode_info *pipe, unsigned int *cnt)
f776c7388   Al Viro   fold fifo.c into ...
956
957
958
959
  {
  	int cur = *cnt;	
  
  	while (cur == *cnt) {
fc7478a2b   Al Viro   pipe: switch wait...
960
  		pipe_wait(pipe);
f776c7388   Al Viro   fold fifo.c into ...
961
962
963
964
965
  		if (signal_pending(current))
  			break;
  	}
  	return cur == *cnt ? -ERESTARTSYS : 0;
  }
fc7478a2b   Al Viro   pipe: switch wait...
966
  static void wake_up_partner(struct pipe_inode_info *pipe)
f776c7388   Al Viro   fold fifo.c into ...
967
  {
fc7478a2b   Al Viro   pipe: switch wait...
968
  	wake_up_interruptible(&pipe->wait);
f776c7388   Al Viro   fold fifo.c into ...
969
970
971
972
973
  }
  
  static int fifo_open(struct inode *inode, struct file *filp)
  {
  	struct pipe_inode_info *pipe;
599a0ac14   Al Viro   pipe: fold file_o...
974
  	bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC;
f776c7388   Al Viro   fold fifo.c into ...
975
  	int ret;
ba5bb1473   Al Viro   pipe: take alloca...
976
977
978
979
980
981
982
983
984
  	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_...
985
  		pipe = alloc_pipe_info();
f776c7388   Al Viro   fold fifo.c into ...
986
  		if (!pipe)
ba5bb1473   Al Viro   pipe: take alloca...
987
988
989
990
991
992
  			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...
993
  			free_pipe_info(pipe);
ba5bb1473   Al Viro   pipe: take alloca...
994
995
996
997
998
  			pipe = inode->i_pipe;
  		} else {
  			inode->i_pipe = pipe;
  			spin_unlock(&inode->i_lock);
  		}
f776c7388   Al Viro   fold fifo.c into ...
999
  	}
de32ec4cf   Al Viro   pipe: set file->p...
1000
  	filp->private_data = pipe;
ba5bb1473   Al Viro   pipe: take alloca...
1001
  	/* OK, we have a pipe and it's pinned down */
ebec73f47   Al Viro   introduce variant...
1002
  	__pipe_lock(pipe);
f776c7388   Al Viro   fold fifo.c into ...
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
  
  	/* 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 ...
1014
1015
  		pipe->r_counter++;
  		if (pipe->readers++ == 0)
fc7478a2b   Al Viro   pipe: switch wait...
1016
  			wake_up_partner(pipe);
f776c7388   Al Viro   fold fifo.c into ...
1017

599a0ac14   Al Viro   pipe: fold file_o...
1018
  		if (!is_pipe && !pipe->writers) {
f776c7388   Al Viro   fold fifo.c into ...
1019
1020
1021
1022
1023
  			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...
1024
  				if (wait_for_partner(pipe, &pipe->w_counter))
f776c7388   Al Viro   fold fifo.c into ...
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
  					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...
1037
  		if (!is_pipe && (filp->f_flags & O_NONBLOCK) && !pipe->readers)
f776c7388   Al Viro   fold fifo.c into ...
1038
  			goto err;
f776c7388   Al Viro   fold fifo.c into ...
1039
1040
  		pipe->w_counter++;
  		if (!pipe->writers++)
fc7478a2b   Al Viro   pipe: switch wait...
1041
  			wake_up_partner(pipe);
f776c7388   Al Viro   fold fifo.c into ...
1042

599a0ac14   Al Viro   pipe: fold file_o...
1043
  		if (!is_pipe && !pipe->readers) {
fc7478a2b   Al Viro   pipe: switch wait...
1044
  			if (wait_for_partner(pipe, &pipe->r_counter))
f776c7388   Al Viro   fold fifo.c into ...
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
  				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 ...
1056
1057
1058
1059
1060
1061
  
  		pipe->readers++;
  		pipe->writers++;
  		pipe->r_counter++;
  		pipe->w_counter++;
  		if (pipe->readers == 1 || pipe->writers == 1)
fc7478a2b   Al Viro   pipe: switch wait...
1062
  			wake_up_partner(pipe);
f776c7388   Al Viro   fold fifo.c into ...
1063
1064
1065
1066
1067
1068
1069
1070
  		break;
  
  	default:
  		ret = -EINVAL;
  		goto err;
  	}
  
  	/* Ok! */
ebec73f47   Al Viro   introduce variant...
1071
  	__pipe_unlock(pipe);
f776c7388   Al Viro   fold fifo.c into ...
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
  	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...
1087
  	__pipe_unlock(pipe);
b0d8d2292   Linus Torvalds   vfs: fix subtle u...
1088
1089
  
  	put_pipe_info(inode, pipe);
f776c7388   Al Viro   fold fifo.c into ...
1090
1091
  	return ret;
  }
599a0ac14   Al Viro   pipe: fold file_o...
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
  const struct file_operations pipefifo_fops = {
  	.open		= fifo_open,
  	.llseek		= no_llseek,
  	.read		= do_sync_read,
  	.aio_read	= pipe_read,
  	.write		= do_sync_write,
  	.aio_write	= pipe_write,
  	.poll		= pipe_poll,
  	.unlocked_ioctl	= pipe_ioctl,
  	.release	= pipe_release,
  	.fasync		= pipe_fasync,
f776c7388   Al Viro   fold fifo.c into ...
1103
  };
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1104
  /*
35f3d14db   Jens Axboe   pipe: add support...
1105
1106
1107
   * 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...
1108
  static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages)
35f3d14db   Jens Axboe   pipe: add support...
1109
1110
1111
1112
  {
  	struct pipe_buffer *bufs;
  
  	/*
35f3d14db   Jens Axboe   pipe: add support...
1113
1114
1115
1116
1117
  	 * 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...
1118
  	if (nr_pages < pipe->nrbufs)
35f3d14db   Jens Axboe   pipe: add support...
1119
  		return -EBUSY;
2ccd4f4d4   Sasha Levin   pipe: fail cleanl...
1120
  	bufs = kcalloc(nr_pages, sizeof(*bufs), GFP_KERNEL | __GFP_NOWARN);
35f3d14db   Jens Axboe   pipe: add support...
1121
1122
1123
1124
1125
1126
1127
1128
  	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...
1129
1130
  		unsigned int tail;
  		unsigned int head;
35f3d14db   Jens Axboe   pipe: add support...
1131

1d862f412   Miklos Szeredi   pipe: fix pipe bu...
1132
1133
1134
1135
1136
1137
1138
  		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...
1139
1140
1141
  		if (head)
  			memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer));
  		if (tail)
1d862f412   Miklos Szeredi   pipe: fix pipe bu...
1142
  			memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer));
35f3d14db   Jens Axboe   pipe: add support...
1143
1144
1145
1146
1147
  	}
  
  	pipe->curbuf = 0;
  	kfree(pipe->bufs);
  	pipe->bufs = bufs;
b9598db34   Jens Axboe   pipe: make F_{GET...
1148
1149
  	pipe->buffers = nr_pages;
  	return nr_pages * PAGE_SIZE;
35f3d14db   Jens Axboe   pipe: add support...
1150
  }
ff9da691c   Jens Axboe   pipe: change /pro...
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
  /*
   * 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...
1179
1180
1181
1182
1183
1184
1185
  /*
   * 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...
1186
  	return file->f_op == &pipefifo_fops ? file->private_data : NULL;
720836465   Linus Torvalds   Un-inline get_pip...
1187
  }
35f3d14db   Jens Axboe   pipe: add support...
1188
1189
1190
1191
  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_...
1192
  	pipe = get_pipe_info(file);
35f3d14db   Jens Axboe   pipe: add support...
1193
1194
  	if (!pipe)
  		return -EBADF;
ebec73f47   Al Viro   introduce variant...
1195
  	__pipe_lock(pipe);
35f3d14db   Jens Axboe   pipe: add support...
1196
1197
  
  	switch (cmd) {
b9598db34   Jens Axboe   pipe: make F_{GET...
1198
  	case F_SETPIPE_SZ: {
ff9da691c   Jens Axboe   pipe: change /pro...
1199
  		unsigned int size, nr_pages;
b9598db34   Jens Axboe   pipe: make F_{GET...
1200

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

6db40cf04   Miklos Szeredi   pipe: fix check i...
1204
1205
1206
  		ret = -EINVAL;
  		if (!nr_pages)
  			goto out;
ff9da691c   Jens Axboe   pipe: change /pro...
1207
  		if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) {
b4ca76157   Jens Axboe   Merge branch 'mas...
1208
  			ret = -EPERM;
cc967be54   Julia Lawall   fs: Add missing m...
1209
  			goto out;
cc967be54   Julia Lawall   fs: Add missing m...
1210
  		}
ff9da691c   Jens Axboe   pipe: change /pro...
1211
  		ret = pipe_set_size(pipe, nr_pages);
35f3d14db   Jens Axboe   pipe: add support...
1212
  		break;
b9598db34   Jens Axboe   pipe: make F_{GET...
1213
  		}
35f3d14db   Jens Axboe   pipe: add support...
1214
  	case F_GETPIPE_SZ:
b9598db34   Jens Axboe   pipe: make F_{GET...
1215
  		ret = pipe->buffers * PAGE_SIZE;
35f3d14db   Jens Axboe   pipe: add support...
1216
1217
1218
1219
1220
  		break;
  	default:
  		ret = -EINVAL;
  		break;
  	}
cc967be54   Julia Lawall   fs: Add missing m...
1221
  out:
ebec73f47   Al Viro   introduce variant...
1222
  	__pipe_unlock(pipe);
35f3d14db   Jens Axboe   pipe: add support...
1223
1224
  	return ret;
  }
ff0c7d15f   Nick Piggin   fs: avoid inode R...
1225
1226
  static const struct super_operations pipefs_ops = {
  	.destroy_inode = free_inode_nonrcu,
d70ef97ba   Pavel Emelyanov   fs/pipe.c: add ->...
1227
  	.statfs = simple_statfs,
ff0c7d15f   Nick Piggin   fs: avoid inode R...
1228
  };
35f3d14db   Jens Axboe   pipe: add support...
1229
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1230
1231
1232
1233
1234
   * 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...
1235
1236
  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
1237
  {
c74a1cbb3   Al Viro   pass default dent...
1238
1239
  	return mount_pseudo(fs_type, "pipe:", &pipefs_ops,
  			&pipefs_dentry_operations, PIPEFS_MAGIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1240
1241
1242
1243
  }
  
  static struct file_system_type pipe_fs_type = {
  	.name		= "pipefs",
51139adac   Al Viro   convert get_sb_ps...
1244
  	.mount		= pipefs_mount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1245
1246
1247
1248
1249
1250
  	.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...
1251

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1252
1253
1254
1255
1256
1257
1258
1259
1260
  	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
1261
  fs_initcall(init_pipe_fs);