Blame view

fs/pipe.c 24.8 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   *  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>
  #include <linux/mount.h>
  #include <linux/pipe_fs_i.h>
  #include <linux/uio.h>
  #include <linux/highmem.h>
5274f052e   Jens Axboe   [PATCH] Introduce...
18
  #include <linux/pagemap.h>
db3495099   Al Viro   [PATCH] AUDIT_FD_...
19
  #include <linux/audit.h>
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
20
  #include <linux/syscalls.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  
  #include <asm/uaccess.h>
  #include <asm/ioctls.h>
  
  /*
   * 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...
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  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 {
  		pipe_lock_nested(pipe2, I_MUTEX_CHILD);
  		pipe_lock_nested(pipe1, I_MUTEX_PARENT);
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
  /* Drop the inode semaphore and wait for a pipe event, atomically */
3a326a2ce   Ingo Molnar   [PATCH] introduce...
75
  void pipe_wait(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
  {
  	DEFINE_WAIT(wait);
d79fc0fc6   Ingo Molnar   [PATCH] sched: TA...
78
79
80
81
  	/*
  	 * Pipes are system-local resources, so sleeping on them
  	 * is considered a noninteractive wait:
  	 */
af9272326   Mike Galbraith   sched: cleanup, r...
82
  	prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE);
61e0d47c3   Miklos Szeredi   splice: add helpe...
83
  	pipe_unlock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
  	schedule();
3a326a2ce   Ingo Molnar   [PATCH] introduce...
85
  	finish_wait(&pipe->wait, &wait);
61e0d47c3   Miklos Szeredi   splice: add helpe...
86
  	pipe_lock(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
  }
858119e15   Arjan van de Ven   [PATCH] Unlinline...
88
  static int
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
89
90
  pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len,
  			int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
93
94
95
96
97
  {
  	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...
98
99
100
101
102
103
104
  		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
105
106
107
108
109
110
111
  		to += copy;
  		len -= copy;
  		iov->iov_base += copy;
  		iov->iov_len -= copy;
  	}
  	return 0;
  }
858119e15   Arjan van de Ven   [PATCH] Unlinline...
112
  static int
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
113
114
  pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len,
  		      int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115
116
117
118
119
120
121
  {
  	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...
122
123
124
125
126
127
128
  		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
129
130
131
132
133
134
135
  		from += copy;
  		len -= copy;
  		iov->iov_base += copy;
  		iov->iov_len -= copy;
  	}
  	return 0;
  }
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
136
137
138
139
140
141
142
143
144
145
146
147
148
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
  /*
   * 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...
176
177
  static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
  				  struct pipe_buffer *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
  {
  	struct page *page = buf->page;
5274f052e   Jens Axboe   [PATCH] Introduce...
180
181
182
  	/*
  	 * 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...
183
  	 * allocation cache. (Otherwise just release our reference to it)
5274f052e   Jens Axboe   [PATCH] Introduce...
184
  	 */
341b446bc   Ingo Molnar   [PATCH] another r...
185
  	if (page_count(page) == 1 && !pipe->tmp_page)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
186
  		pipe->tmp_page = page;
341b446bc   Ingo Molnar   [PATCH] another r...
187
188
  	else
  		page_cache_release(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
  }
0845718da   Jens Axboe   pipe: add documen...
190
191
192
193
194
195
196
197
  /**
   * 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...
198
   *	pipe_buffer passed in @buf. If @atomic is set, an atomic map is provided
0845718da   Jens Axboe   pipe: add documen...
199
200
201
202
203
   *	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...
204
  void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
205
  			   struct pipe_buffer *buf, int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
  {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
207
208
209
210
  	if (atomic) {
  		buf->flags |= PIPE_BUF_FLAG_ATOMIC;
  		return kmap_atomic(buf->page, KM_USER0);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
212
  	return kmap(buf->page);
  }
0845718da   Jens Axboe   pipe: add documen...
213
214
215
216
217
218
219
220
221
  /**
   * 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...
222
  void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
223
  			    struct pipe_buffer *buf, void *map_data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
  {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
225
226
227
228
229
  	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
230
  }
0845718da   Jens Axboe   pipe: add documen...
231
  /**
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
232
   * generic_pipe_buf_steal - attempt to take ownership of a &pipe_buffer
0845718da   Jens Axboe   pipe: add documen...
233
234
235
236
   * @pipe:	the pipe that the buffer belongs to
   * @buf:	the buffer to attempt to steal
   *
   * Description:
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
237
   *	This function attempts to steal the &struct page attached to
0845718da   Jens Axboe   pipe: add documen...
238
239
   *	@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...
240
   *	he wishes; the typical use is insertion into a different file
0845718da   Jens Axboe   pipe: add documen...
241
242
   *	page cache.
   */
330ab7161   Jens Axboe   [PATCH] vmsplice:...
243
244
  int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
  			   struct pipe_buffer *buf)
5abc97aa2   Jens Axboe   [PATCH] splice: a...
245
  {
46e678c96   Jens Axboe   [PATCH] splice: f...
246
  	struct page *page = buf->page;
0845718da   Jens Axboe   pipe: add documen...
247
248
249
250
251
  	/*
  	 * 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...
252
  	if (page_count(page) == 1) {
46e678c96   Jens Axboe   [PATCH] splice: f...
253
254
255
256
257
  		lock_page(page);
  		return 0;
  	}
  
  	return 1;
5abc97aa2   Jens Axboe   [PATCH] splice: a...
258
  }
0845718da   Jens Axboe   pipe: add documen...
259
  /**
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
260
   * generic_pipe_buf_get - get a reference to a &struct pipe_buffer
0845718da   Jens Axboe   pipe: add documen...
261
262
263
264
265
266
267
268
269
   * @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...
270
271
272
  {
  	page_cache_get(buf->page);
  }
0845718da   Jens Axboe   pipe: add documen...
273
274
  /**
   * generic_pipe_buf_confirm - verify contents of the pipe buffer
79685b8de   Randy Dunlap   docbook: add pipe...
275
   * @info:	the pipe that the buffer belongs to
0845718da   Jens Axboe   pipe: add documen...
276
277
278
279
280
281
   * @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 ...
282
283
  int generic_pipe_buf_confirm(struct pipe_inode_info *info,
  			     struct pipe_buffer *buf)
f84d75199   Jens Axboe   [PATCH] pipe: int...
284
285
286
  {
  	return 0;
  }
d4c3cca94   Eric Dumazet   [PATCH] constify ...
287
  static const struct pipe_buf_operations anon_pipe_buf_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
  	.can_merge = 1,
f84d75199   Jens Axboe   [PATCH] pipe: int...
289
290
  	.map = generic_pipe_buf_map,
  	.unmap = generic_pipe_buf_unmap,
cac36bb06   Jens Axboe   pipe: change the ...
291
  	.confirm = generic_pipe_buf_confirm,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
  	.release = anon_pipe_buf_release,
330ab7161   Jens Axboe   [PATCH] vmsplice:...
293
  	.steal = generic_pipe_buf_steal,
f84d75199   Jens Axboe   [PATCH] pipe: int...
294
  	.get = generic_pipe_buf_get,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
296
297
  };
  
  static ssize_t
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
298
299
  pipe_read(struct kiocb *iocb, const struct iovec *_iov,
  	   unsigned long nr_segs, loff_t pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
  {
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
301
  	struct file *filp = iocb->ki_filp;
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
302
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
303
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
306
307
308
309
310
311
312
313
314
315
  	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...
316
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
317
  	pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
  	for (;;) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
319
  		int bufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  		if (bufs) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
321
322
  			int curbuf = pipe->curbuf;
  			struct pipe_buffer *buf = pipe->bufs + curbuf;
d4c3cca94   Eric Dumazet   [PATCH] constify ...
323
  			const struct pipe_buf_operations *ops = buf->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
325
  			void *addr;
  			size_t chars = buf->len;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
326
  			int error, atomic;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
328
329
  
  			if (chars > total_len)
  				chars = total_len;
cac36bb06   Jens Axboe   pipe: change the ...
330
  			error = ops->confirm(pipe, buf);
f84d75199   Jens Axboe   [PATCH] pipe: int...
331
  			if (error) {
5274f052e   Jens Axboe   [PATCH] Introduce...
332
  				if (!ret)
f84d75199   Jens Axboe   [PATCH] pipe: int...
333
  					error = ret;
5274f052e   Jens Axboe   [PATCH] Introduce...
334
335
  				break;
  			}
f84d75199   Jens Axboe   [PATCH] pipe: int...
336

f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
337
338
339
340
341
  			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
342
  			if (unlikely(error)) {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
343
344
345
346
347
348
349
  				/*
  				 * Just retry with the slow path if we failed.
  				 */
  				if (atomic) {
  					atomic = 0;
  					goto redo;
  				}
341b446bc   Ingo Molnar   [PATCH] another r...
350
  				if (!ret)
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
351
  					ret = error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
354
355
356
357
358
  				break;
  			}
  			ret += chars;
  			buf->offset += chars;
  			buf->len -= chars;
  			if (!buf->len) {
  				buf->ops = NULL;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
359
  				ops->release(pipe, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
  				curbuf = (curbuf + 1) & (PIPE_BUFFERS-1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
361
362
  				pipe->curbuf = curbuf;
  				pipe->nrbufs = --bufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
363
364
365
366
367
368
369
370
  				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...
371
  		if (!pipe->writers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
  			break;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
373
  		if (!pipe->waiting_writers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
375
376
377
378
379
380
381
382
383
384
385
386
  			/* 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...
387
388
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
390
391
  			break;
  		}
  		if (do_wakeup) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
392
393
  			wake_up_interruptible_sync(&pipe->wait);
   			kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
394
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
395
  		pipe_wait(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
397
  	mutex_unlock(&inode->i_mutex);
341b446bc   Ingo Molnar   [PATCH] another r...
398
399
  
  	/* Signal writers asynchronously that there is more room. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
  	if (do_wakeup) {
71e20f187   Ingo Molnar   sched: affine syn...
401
  		wake_up_interruptible_sync(&pipe->wait);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
402
  		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403
404
405
406
407
408
409
  	}
  	if (ret > 0)
  		file_accessed(filp);
  	return ret;
  }
  
  static ssize_t
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
410
411
  pipe_write(struct kiocb *iocb, const struct iovec *_iov,
  	    unsigned long nr_segs, loff_t ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
  {
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
413
  	struct file *filp = iocb->ki_filp;
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
414
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
415
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
418
419
420
421
422
423
424
425
426
427
428
  	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...
429
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
430
  	pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
432
  	if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433
434
435
436
437
438
439
  		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...
440
  	if (pipe->nrbufs && chars != 0) {
341b446bc   Ingo Molnar   [PATCH] another r...
441
442
  		int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
  							(PIPE_BUFFERS-1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
443
  		struct pipe_buffer *buf = pipe->bufs + lastbuf;
d4c3cca94   Eric Dumazet   [PATCH] constify ...
444
  		const struct pipe_buf_operations *ops = buf->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
  		int offset = buf->offset + buf->len;
341b446bc   Ingo Molnar   [PATCH] another r...
446

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

cac36bb06   Jens Axboe   pipe: change the ...
451
  			error = ops->confirm(pipe, buf);
f84d75199   Jens Axboe   [PATCH] pipe: int...
452
  			if (error)
5274f052e   Jens Axboe   [PATCH] Introduce...
453
  				goto out;
f84d75199   Jens Axboe   [PATCH] pipe: int...
454

f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
455
456
457
  			iov_fault_in_pages_read(iov, chars);
  redo1:
  			addr = ops->map(pipe, buf, atomic);
5274f052e   Jens Axboe   [PATCH] Introduce...
458
  			error = pipe_iov_copy_from_user(offset + addr, iov,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
459
460
  							chars, atomic);
  			ops->unmap(pipe, buf, addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
461
462
  			ret = error;
  			do_wakeup = 1;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
463
464
465
466
467
  			if (error) {
  				if (atomic) {
  					atomic = 0;
  					goto redo1;
  				}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
468
  				goto out;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
469
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
470
471
472
473
474
475
476
477
478
479
  			buf->len += chars;
  			total_len -= chars;
  			ret = chars;
  			if (!total_len)
  				goto out;
  		}
  	}
  
  	for (;;) {
  		int bufs;
341b446bc   Ingo Molnar   [PATCH] another r...
480

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
481
  		if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
482
  			send_sig(SIGPIPE, current, 0);
341b446bc   Ingo Molnar   [PATCH] another r...
483
484
  			if (!ret)
  				ret = -EPIPE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
486
  			break;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
487
  		bufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
488
  		if (bufs < PIPE_BUFFERS) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
489
490
491
  			int newbuf = (pipe->curbuf + bufs) & (PIPE_BUFFERS-1);
  			struct pipe_buffer *buf = pipe->bufs + newbuf;
  			struct page *page = pipe->tmp_page;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
492
493
  			char *src;
  			int error, atomic = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
495
496
497
498
499
500
  
  			if (!page) {
  				page = alloc_page(GFP_HIGHUSER);
  				if (unlikely(!page)) {
  					ret = ret ? : -ENOMEM;
  					break;
  				}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
501
  				pipe->tmp_page = page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
  			}
341b446bc   Ingo Molnar   [PATCH] another r...
503
  			/* Always wake up, even if the copy fails. Otherwise
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
505
506
507
508
509
510
511
  			 * 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...
512
513
514
515
516
517
518
519
520
521
522
523
524
  			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
525
  			if (unlikely(error)) {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
526
527
528
529
  				if (atomic) {
  					atomic = 0;
  					goto redo2;
  				}
341b446bc   Ingo Molnar   [PATCH] another r...
530
  				if (!ret)
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
531
  					ret = error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
533
534
535
536
537
538
539
540
  				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...
541
542
  			pipe->nrbufs = ++bufs;
  			pipe->tmp_page = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543
544
545
546
547
548
549
550
  
  			total_len -= chars;
  			if (!total_len)
  				break;
  		}
  		if (bufs < PIPE_BUFFERS)
  			continue;
  		if (filp->f_flags & O_NONBLOCK) {
341b446bc   Ingo Molnar   [PATCH] another r...
551
552
  			if (!ret)
  				ret = -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
553
554
555
  			break;
  		}
  		if (signal_pending(current)) {
341b446bc   Ingo Molnar   [PATCH] another r...
556
557
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
559
560
  			break;
  		}
  		if (do_wakeup) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
561
562
  			wake_up_interruptible_sync(&pipe->wait);
  			kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
564
  			do_wakeup = 0;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
565
566
567
  		pipe->waiting_writers++;
  		pipe_wait(pipe);
  		pipe->waiting_writers--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
569
  	}
  out:
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
570
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
571
  	if (do_wakeup) {
71e20f187   Ingo Molnar   sched: affine syn...
572
  		wake_up_interruptible_sync(&pipe->wait);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
573
  		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
574
575
  	}
  	if (ret > 0)
870f48179   Christoph Hellwig   [PATCH] replace i...
576
  		file_update_time(filp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
578
579
580
  	return ret;
  }
  
  static ssize_t
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
582
583
584
585
586
  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...
587
588
  bad_pipe_w(struct file *filp, const char __user *buf, size_t count,
  	   loff_t *ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589
590
591
  {
  	return -EBADF;
  }
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
592
  static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
594
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
595
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596
597
598
599
  	int count, buf, nrbufs;
  
  	switch (cmd) {
  		case FIONREAD:
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
600
  			mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
601
  			pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
602
  			count = 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
603
604
  			buf = pipe->curbuf;
  			nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
605
  			while (--nrbufs >= 0) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
606
  				count += pipe->bufs[buf].len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
608
  				buf = (buf+1) & (PIPE_BUFFERS-1);
  			}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
609
  			mutex_unlock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
610

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
612
613
614
615
616
617
618
619
620
621
  			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...
622
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
623
  	struct pipe_inode_info *pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624
  	int nrbufs;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
625
  	poll_wait(filp, &pipe->wait, wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
627
  
  	/* Reading only -- no need for acquiring the semaphore.  */
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
628
  	nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
629
630
631
  	mask = 0;
  	if (filp->f_mode & FMODE_READ) {
  		mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
632
  		if (!pipe->writers && filp->f_version != pipe->w_counter)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
634
635
636
637
  			mask |= POLLHUP;
  	}
  
  	if (filp->f_mode & FMODE_WRITE) {
  		mask |= (nrbufs < PIPE_BUFFERS) ? POLLOUT | POLLWRNORM : 0;
5e5d7a222   Pekka Enberg   [PATCH] pipe: rem...
638
639
640
641
  		/*
  		 * 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...
642
  		if (!pipe->readers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643
644
645
646
647
  			mask |= POLLERR;
  	}
  
  	return mask;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
648
649
650
  static int
  pipe_release(struct inode *inode, int decr, int decw)
  {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
651
  	struct pipe_inode_info *pipe;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
652
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
653
654
655
  	pipe = inode->i_pipe;
  	pipe->readers -= decr;
  	pipe->writers -= decw;
341b446bc   Ingo Molnar   [PATCH] another r...
656

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
657
  	if (!pipe->readers && !pipe->writers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
659
  		free_pipe_info(inode);
  	} else {
71e20f187   Ingo Molnar   sched: affine syn...
660
  		wake_up_interruptible_sync(&pipe->wait);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
661
662
  		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
  		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
663
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
664
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
665
666
667
668
669
670
671
  
  	return 0;
  }
  
  static int
  pipe_read_fasync(int fd, struct file *filp, int on)
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
672
  	struct inode *inode = filp->f_path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
673
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
674
675
676
  	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
677

60aa49243   Jonathan Corbet   Rationalize fasyn...
678
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
679
680
681
682
683
684
  }
  
  
  static int
  pipe_write_fasync(int fd, struct file *filp, int on)
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
685
  	struct inode *inode = filp->f_path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
686
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
687
688
689
  	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
690

60aa49243   Jonathan Corbet   Rationalize fasyn...
691
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
692
693
694
695
696
697
  }
  
  
  static int
  pipe_rdwr_fasync(int fd, struct file *filp, int on)
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
698
  	struct inode *inode = filp->f_path.dentry->d_inode;
341b446bc   Ingo Molnar   [PATCH] another r...
699
  	struct pipe_inode_info *pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
700
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
701
  	mutex_lock(&inode->i_mutex);
341b446bc   Ingo Molnar   [PATCH] another r...
702
  	retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
e5bc49ba7   Oleg Nesterov   pipe_rdwr_fasync:...
703
  	if (retval >= 0) {
341b446bc   Ingo Molnar   [PATCH] another r...
704
  		retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
e5bc49ba7   Oleg Nesterov   pipe_rdwr_fasync:...
705
706
707
  		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...
708
  	mutex_unlock(&inode->i_mutex);
60aa49243   Jonathan Corbet   Rationalize fasyn...
709
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710
711
712
713
714
715
  }
  
  
  static int
  pipe_read_release(struct inode *inode, struct file *filp)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716
717
718
719
720
721
  	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
722
723
724
725
726
727
728
  	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
729
730
731
732
733
734
735
736
737
738
  	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)
  {
  	/* We could have perhaps used atomic_t, but this and friends
  	   below are the only places.  So it doesn't seem worthwhile.  */
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
739
740
741
  	mutex_lock(&inode->i_mutex);
  	inode->i_pipe->readers++;
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
742
743
744
745
746
747
748
  
  	return 0;
  }
  
  static int
  pipe_write_open(struct inode *inode, struct file *filp)
  {
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
749
750
751
  	mutex_lock(&inode->i_mutex);
  	inode->i_pipe->writers++;
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
753
754
755
756
757
758
  
  	return 0;
  }
  
  static int
  pipe_rdwr_open(struct inode *inode, struct file *filp)
  {
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
759
  	mutex_lock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
760
  	if (filp->f_mode & FMODE_READ)
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
761
  		inode->i_pipe->readers++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
762
  	if (filp->f_mode & FMODE_WRITE)
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
763
764
  		inode->i_pipe->writers++;
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
765
766
767
768
769
770
771
  
  	return 0;
  }
  
  /*
   * 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...
772
773
   *
   * Pipes reuse fifos' file_operations structs.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
774
   */
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
775
  const struct file_operations read_pipefifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
776
  	.llseek		= no_llseek,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
777
778
  	.read		= do_sync_read,
  	.aio_read	= pipe_read,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779
780
  	.write		= bad_pipe_w,
  	.poll		= pipe_poll,
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
781
  	.unlocked_ioctl	= pipe_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
782
783
784
785
  	.open		= pipe_read_open,
  	.release	= pipe_read_release,
  	.fasync		= pipe_read_fasync,
  };
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
786
  const struct file_operations write_pipefifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
787
788
  	.llseek		= no_llseek,
  	.read		= bad_pipe_r,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
789
790
  	.write		= do_sync_write,
  	.aio_write	= pipe_write,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
791
  	.poll		= pipe_poll,
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
792
  	.unlocked_ioctl	= pipe_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
793
794
795
796
  	.open		= pipe_write_open,
  	.release	= pipe_write_release,
  	.fasync		= pipe_write_fasync,
  };
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
797
  const struct file_operations rdwr_pipefifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798
  	.llseek		= no_llseek,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
799
800
801
802
  	.read		= do_sync_read,
  	.aio_read	= pipe_read,
  	.write		= do_sync_write,
  	.aio_write	= pipe_write,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
803
  	.poll		= pipe_poll,
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
804
  	.unlocked_ioctl	= pipe_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
806
807
808
  	.open		= pipe_rdwr_open,
  	.release	= pipe_rdwr_release,
  	.fasync		= pipe_rdwr_fasync,
  };
3a326a2ce   Ingo Molnar   [PATCH] introduce...
809
810
  struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
  {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
811
  	struct pipe_inode_info *pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
812

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
813
814
815
816
817
  	pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
  	if (pipe) {
  		init_waitqueue_head(&pipe->wait);
  		pipe->r_counter = pipe->w_counter = 1;
  		pipe->inode = inode;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
818
  	}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
819
  	return pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
820
  }
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
821
  void __free_pipe_info(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822
823
  {
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
824

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
825
  	for (i = 0; i < PIPE_BUFFERS; i++) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
826
  		struct pipe_buffer *buf = pipe->bufs + i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
827
  		if (buf->ops)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
828
  			buf->ops->release(pipe, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
  	}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
830
831
832
  	if (pipe->tmp_page)
  		__free_page(pipe->tmp_page);
  	kfree(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833
  }
b92ce5589   Jens Axboe   [PATCH] splice: a...
834
835
836
837
838
  void free_pipe_info(struct inode *inode)
  {
  	__free_pipe_info(inode->i_pipe);
  	inode->i_pipe = NULL;
  }
fa3536cc1   Eric Dumazet   [PATCH] Use __rea...
839
  static struct vfsmount *pipe_mnt __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
840
841
  static int pipefs_delete_dentry(struct dentry *dentry)
  {
d18de5a27   Eric Dumazet   [PATCH] don't ins...
842
843
844
845
846
847
848
849
  	/*
  	 * At creation time, we pretended this dentry was hashed
  	 * (by clearing DCACHE_UNHASHED bit in d_flags)
  	 * At delete time, we restore the truth : not hashed.
  	 * (so that dput() can proceed correctly)
  	 */
  	dentry->d_flags |= DCACHE_UNHASHED;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
850
  }
341b446bc   Ingo Molnar   [PATCH] another r...
851

c23fbb6bc   Eric Dumazet   VFS: delay the de...
852
853
854
855
856
857
858
859
  /*
   * 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...
860
  static const struct dentry_operations pipefs_dentry_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861
  	.d_delete	= pipefs_delete_dentry,
c23fbb6bc   Eric Dumazet   VFS: delay the de...
862
  	.d_dname	= pipefs_dname,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
864
865
866
867
  };
  
  static struct inode * get_pipe_inode(void)
  {
  	struct inode *inode = new_inode(pipe_mnt->mnt_sb);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
868
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
869
870
871
  
  	if (!inode)
  		goto fail_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
872
873
  	pipe = alloc_pipe_info(inode);
  	if (!pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874
  		goto fail_iput;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
875
  	inode->i_pipe = pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
876

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
877
  	pipe->readers = pipe->writers = 1;
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
878
  	inode->i_fop = &rdwr_pipefifo_fops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879
880
881
882
883
884
885
886
887
  
  	/*
  	 * 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...
888
889
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
890
  	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
891

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
892
893
894
895
  	return inode;
  
  fail_iput:
  	iput(inode);
341b446bc   Ingo Molnar   [PATCH] another r...
896

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
897
898
899
  fail_inode:
  	return NULL;
  }
be61a86d7   Ulrich Drepper   flag parameters: ...
900
  struct file *create_write_pipe(int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
901
  {
d6cbd281d   Andi Kleen   [PATCH] Some clea...
902
903
904
  	int err;
  	struct inode *inode;
  	struct file *f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
905
  	struct dentry *dentry;
c23fbb6bc   Eric Dumazet   VFS: delay the de...
906
  	struct qstr name = { .name = "" };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
907

d6cbd281d   Andi Kleen   [PATCH] Some clea...
908
  	err = -ENFILE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
909
910
  	inode = get_pipe_inode();
  	if (!inode)
430e285e0   Dave Hansen   [PATCH] fix up ne...
911
  		goto err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
912

d6cbd281d   Andi Kleen   [PATCH] Some clea...
913
  	err = -ENOMEM;
c23fbb6bc   Eric Dumazet   VFS: delay the de...
914
  	dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
915
  	if (!dentry)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
916
  		goto err_inode;
341b446bc   Ingo Molnar   [PATCH] another r...
917

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
918
  	dentry->d_op = &pipefs_dentry_operations;
d18de5a27   Eric Dumazet   [PATCH] don't ins...
919
920
921
922
923
924
925
  	/*
  	 * We dont want to publish this dentry into global dentry hash table.
  	 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
  	 * This permits a working /proc/$pid/fd/XXX on pipes
  	 */
  	dentry->d_flags &= ~DCACHE_UNHASHED;
  	d_instantiate(dentry, inode);
430e285e0   Dave Hansen   [PATCH] fix up ne...
926
927
  
  	err = -ENFILE;
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
928
  	f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipefifo_fops);
430e285e0   Dave Hansen   [PATCH] fix up ne...
929
930
  	if (!f)
  		goto err_dentry;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
931
  	f->f_mapping = inode->i_mapping;
341b446bc   Ingo Molnar   [PATCH] another r...
932

be61a86d7   Ulrich Drepper   flag parameters: ...
933
  	f->f_flags = O_WRONLY | (flags & O_NONBLOCK);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
934
935
936
  	f->f_version = 0;
  
  	return f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937

430e285e0   Dave Hansen   [PATCH] fix up ne...
938
   err_dentry:
ed1524371   Al Viro   [PATCH] double-fr...
939
  	free_pipe_info(inode);
430e285e0   Dave Hansen   [PATCH] fix up ne...
940
  	dput(dentry);
ed1524371   Al Viro   [PATCH] double-fr...
941
  	return ERR_PTR(err);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
942
   err_inode:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
943
944
  	free_pipe_info(inode);
  	iput(inode);
430e285e0   Dave Hansen   [PATCH] fix up ne...
945
   err:
d6cbd281d   Andi Kleen   [PATCH] Some clea...
946
947
948
949
950
  	return ERR_PTR(err);
  }
  
  void free_write_pipe(struct file *f)
  {
5ccac88ee   Al Viro   [PATCH] fix leaks...
951
  	free_pipe_info(f->f_dentry->d_inode);
c8e7f449b   Jan Blunck   [patch 1/4] vfs: ...
952
  	path_put(&f->f_path);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
953
954
  	put_filp(f);
  }
be61a86d7   Ulrich Drepper   flag parameters: ...
955
  struct file *create_read_pipe(struct file *wrf, int flags)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
956
957
958
959
960
961
  {
  	struct file *f = get_empty_filp();
  	if (!f)
  		return ERR_PTR(-ENFILE);
  
  	/* Grab pipe from the writer */
c8e7f449b   Jan Blunck   [patch 1/4] vfs: ...
962
963
  	f->f_path = wrf->f_path;
  	path_get(&wrf->f_path);
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
964
  	f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
965
966
  
  	f->f_pos = 0;
be61a86d7   Ulrich Drepper   flag parameters: ...
967
  	f->f_flags = O_RDONLY | (flags & O_NONBLOCK);
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
968
  	f->f_op = &read_pipefifo_fops;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
969
970
971
972
973
  	f->f_mode = FMODE_READ;
  	f->f_version = 0;
  
  	return f;
  }
ed8cae8ba   Ulrich Drepper   flag parameters: ...
974
  int do_pipe_flags(int *fd, int flags)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
975
976
977
978
  {
  	struct file *fw, *fr;
  	int error;
  	int fdw, fdr;
be61a86d7   Ulrich Drepper   flag parameters: ...
979
  	if (flags & ~(O_CLOEXEC | O_NONBLOCK))
ed8cae8ba   Ulrich Drepper   flag parameters: ...
980
  		return -EINVAL;
be61a86d7   Ulrich Drepper   flag parameters: ...
981
  	fw = create_write_pipe(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
982
983
  	if (IS_ERR(fw))
  		return PTR_ERR(fw);
be61a86d7   Ulrich Drepper   flag parameters: ...
984
  	fr = create_read_pipe(fw, flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
985
986
987
  	error = PTR_ERR(fr);
  	if (IS_ERR(fr))
  		goto err_write_pipe;
ed8cae8ba   Ulrich Drepper   flag parameters: ...
988
  	error = get_unused_fd_flags(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
989
990
991
  	if (error < 0)
  		goto err_read_pipe;
  	fdr = error;
ed8cae8ba   Ulrich Drepper   flag parameters: ...
992
  	error = get_unused_fd_flags(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
993
994
995
  	if (error < 0)
  		goto err_fdr;
  	fdw = error;
157cf649a   Al Viro   sanitize audit_fd...
996
  	audit_fd_pair(fdr, fdw);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
997
998
999
1000
1001
1002
1003
1004
1005
1006
  	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: ...
1007
  	path_put(&fr->f_path);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
1008
1009
1010
1011
  	put_filp(fr);
   err_write_pipe:
  	free_write_pipe(fw);
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1012
1013
1014
  }
  
  /*
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1015
1016
1017
   * 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...
1018
  SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1019
1020
1021
  {
  	int fd[2];
  	int error;
ed8cae8ba   Ulrich Drepper   flag parameters: ...
1022
  	error = do_pipe_flags(fd, flags);
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1023
  	if (!error) {
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
1024
1025
1026
  		if (copy_to_user(fildes, fd, sizeof(fd))) {
  			sys_close(fd[0]);
  			sys_close(fd[1]);
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1027
  			error = -EFAULT;
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
1028
  		}
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1029
1030
1031
  	}
  	return error;
  }
2b6642199   Heiko Carstens   [CVE-2009-0029] S...
1032
  SYSCALL_DEFINE1(pipe, int __user *, fildes)
ed8cae8ba   Ulrich Drepper   flag parameters: ...
1033
1034
1035
  {
  	return sys_pipe2(fildes, 0);
  }
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1036
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1037
1038
1039
1040
1041
   * 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.
   */
454e2398b   David Howells   [PATCH] VFS: Perm...
1042
1043
1044
  static int pipefs_get_sb(struct file_system_type *fs_type,
  			 int flags, const char *dev_name, void *data,
  			 struct vfsmount *mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1045
  {
454e2398b   David Howells   [PATCH] VFS: Perm...
1046
  	return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC, mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
  }
  
  static struct file_system_type pipe_fs_type = {
  	.name		= "pipefs",
  	.get_sb		= pipefs_get_sb,
  	.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...
1058

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
  	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;
  }
  
  static void __exit exit_pipe_fs(void)
  {
  	unregister_filesystem(&pipe_fs_type);
  	mntput(pipe_mnt);
  }
  
  fs_initcall(init_pipe_fs);
  module_exit(exit_pipe_fs);