Blame view

fs/pipe.c 24 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
39
40
  
  #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
   */
  
  /* Drop the inode semaphore and wait for a pipe event, atomically */
3a326a2ce   Ingo Molnar   [PATCH] introduce...
41
  void pipe_wait(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
43
  {
  	DEFINE_WAIT(wait);
d79fc0fc6   Ingo Molnar   [PATCH] sched: TA...
44
45
46
47
  	/*
  	 * Pipes are system-local resources, so sleeping on them
  	 * is considered a noninteractive wait:
  	 */
af9272326   Mike Galbraith   sched: cleanup, r...
48
  	prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE);
3a326a2ce   Ingo Molnar   [PATCH] introduce...
49
50
  	if (pipe->inode)
  		mutex_unlock(&pipe->inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
  	schedule();
3a326a2ce   Ingo Molnar   [PATCH] introduce...
52
53
54
  	finish_wait(&pipe->wait, &wait);
  	if (pipe->inode)
  		mutex_lock(&pipe->inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
  }
858119e15   Arjan van de Ven   [PATCH] Unlinline...
56
  static int
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
57
58
  pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len,
  			int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
63
64
65
  {
  	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...
66
67
68
69
70
71
72
  		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
73
74
75
76
77
78
79
  		to += copy;
  		len -= copy;
  		iov->iov_base += copy;
  		iov->iov_len -= copy;
  	}
  	return 0;
  }
858119e15   Arjan van de Ven   [PATCH] Unlinline...
80
  static int
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
81
82
  pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len,
  		      int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
85
86
87
88
89
  {
  	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...
90
91
92
93
94
95
96
  		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
97
98
99
100
101
102
103
  		from += copy;
  		len -= copy;
  		iov->iov_base += copy;
  		iov->iov_len -= copy;
  	}
  	return 0;
  }
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
  /*
   * 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...
144
145
  static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
  				  struct pipe_buffer *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
147
  {
  	struct page *page = buf->page;
5274f052e   Jens Axboe   [PATCH] Introduce...
148
149
150
  	/*
  	 * 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...
151
  	 * allocation cache. (Otherwise just release our reference to it)
5274f052e   Jens Axboe   [PATCH] Introduce...
152
  	 */
341b446bc   Ingo Molnar   [PATCH] another r...
153
  	if (page_count(page) == 1 && !pipe->tmp_page)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
154
  		pipe->tmp_page = page;
341b446bc   Ingo Molnar   [PATCH] another r...
155
156
  	else
  		page_cache_release(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  }
0845718da   Jens Axboe   pipe: add documen...
158
159
160
161
162
163
164
165
  /**
   * 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...
166
   *	pipe_buffer passed in @buf. If @atomic is set, an atomic map is provided
0845718da   Jens Axboe   pipe: add documen...
167
168
169
170
171
   *	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...
172
  void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
173
  			   struct pipe_buffer *buf, int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
  {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
175
176
177
178
  	if (atomic) {
  		buf->flags |= PIPE_BUF_FLAG_ATOMIC;
  		return kmap_atomic(buf->page, KM_USER0);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
180
  	return kmap(buf->page);
  }
0845718da   Jens Axboe   pipe: add documen...
181
182
183
184
185
186
187
188
189
  /**
   * 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...
190
  void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
191
  			    struct pipe_buffer *buf, void *map_data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
  {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
193
194
195
196
197
  	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
198
  }
0845718da   Jens Axboe   pipe: add documen...
199
  /**
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
200
   * generic_pipe_buf_steal - attempt to take ownership of a &pipe_buffer
0845718da   Jens Axboe   pipe: add documen...
201
202
203
204
   * @pipe:	the pipe that the buffer belongs to
   * @buf:	the buffer to attempt to steal
   *
   * Description:
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
205
   *	This function attempts to steal the &struct page attached to
0845718da   Jens Axboe   pipe: add documen...
206
207
   *	@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...
208
   *	he wishes; the typical use is insertion into a different file
0845718da   Jens Axboe   pipe: add documen...
209
210
   *	page cache.
   */
330ab7161   Jens Axboe   [PATCH] vmsplice:...
211
212
  int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
  			   struct pipe_buffer *buf)
5abc97aa2   Jens Axboe   [PATCH] splice: a...
213
  {
46e678c96   Jens Axboe   [PATCH] splice: f...
214
  	struct page *page = buf->page;
0845718da   Jens Axboe   pipe: add documen...
215
216
217
218
219
  	/*
  	 * 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...
220
  	if (page_count(page) == 1) {
46e678c96   Jens Axboe   [PATCH] splice: f...
221
222
223
224
225
  		lock_page(page);
  		return 0;
  	}
  
  	return 1;
5abc97aa2   Jens Axboe   [PATCH] splice: a...
226
  }
0845718da   Jens Axboe   pipe: add documen...
227
  /**
b51d63c6d   Randy Dunlap   kernel-doc: fix f...
228
   * generic_pipe_buf_get - get a reference to a &struct pipe_buffer
0845718da   Jens Axboe   pipe: add documen...
229
230
231
232
233
234
235
236
237
   * @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...
238
239
240
  {
  	page_cache_get(buf->page);
  }
0845718da   Jens Axboe   pipe: add documen...
241
242
  /**
   * generic_pipe_buf_confirm - verify contents of the pipe buffer
79685b8de   Randy Dunlap   docbook: add pipe...
243
   * @info:	the pipe that the buffer belongs to
0845718da   Jens Axboe   pipe: add documen...
244
245
246
247
248
249
   * @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 ...
250
251
  int generic_pipe_buf_confirm(struct pipe_inode_info *info,
  			     struct pipe_buffer *buf)
f84d75199   Jens Axboe   [PATCH] pipe: int...
252
253
254
  {
  	return 0;
  }
d4c3cca94   Eric Dumazet   [PATCH] constify ...
255
  static const struct pipe_buf_operations anon_pipe_buf_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
  	.can_merge = 1,
f84d75199   Jens Axboe   [PATCH] pipe: int...
257
258
  	.map = generic_pipe_buf_map,
  	.unmap = generic_pipe_buf_unmap,
cac36bb06   Jens Axboe   pipe: change the ...
259
  	.confirm = generic_pipe_buf_confirm,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
  	.release = anon_pipe_buf_release,
330ab7161   Jens Axboe   [PATCH] vmsplice:...
261
  	.steal = generic_pipe_buf_steal,
f84d75199   Jens Axboe   [PATCH] pipe: int...
262
  	.get = generic_pipe_buf_get,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
264
265
  };
  
  static ssize_t
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
266
267
  pipe_read(struct kiocb *iocb, const struct iovec *_iov,
  	   unsigned long nr_segs, loff_t pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
  {
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
269
  	struct file *filp = iocb->ki_filp;
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
270
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
271
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
273
274
275
276
277
278
279
280
281
282
283
  	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...
284
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
285
  	pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
  	for (;;) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
287
  		int bufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
  		if (bufs) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
289
290
  			int curbuf = pipe->curbuf;
  			struct pipe_buffer *buf = pipe->bufs + curbuf;
d4c3cca94   Eric Dumazet   [PATCH] constify ...
291
  			const struct pipe_buf_operations *ops = buf->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
293
  			void *addr;
  			size_t chars = buf->len;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
294
  			int error, atomic;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
296
297
  
  			if (chars > total_len)
  				chars = total_len;
cac36bb06   Jens Axboe   pipe: change the ...
298
  			error = ops->confirm(pipe, buf);
f84d75199   Jens Axboe   [PATCH] pipe: int...
299
  			if (error) {
5274f052e   Jens Axboe   [PATCH] Introduce...
300
  				if (!ret)
f84d75199   Jens Axboe   [PATCH] pipe: int...
301
  					error = ret;
5274f052e   Jens Axboe   [PATCH] Introduce...
302
303
  				break;
  			}
f84d75199   Jens Axboe   [PATCH] pipe: int...
304

f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
305
306
307
308
309
  			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
310
  			if (unlikely(error)) {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
311
312
313
314
315
316
317
  				/*
  				 * Just retry with the slow path if we failed.
  				 */
  				if (atomic) {
  					atomic = 0;
  					goto redo;
  				}
341b446bc   Ingo Molnar   [PATCH] another r...
318
  				if (!ret)
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
319
  					ret = error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
321
322
323
324
325
326
  				break;
  			}
  			ret += chars;
  			buf->offset += chars;
  			buf->len -= chars;
  			if (!buf->len) {
  				buf->ops = NULL;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
327
  				ops->release(pipe, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
  				curbuf = (curbuf + 1) & (PIPE_BUFFERS-1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
329
330
  				pipe->curbuf = curbuf;
  				pipe->nrbufs = --bufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
333
334
335
336
337
338
  				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...
339
  		if (!pipe->writers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
  			break;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
341
  		if (!pipe->waiting_writers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
343
344
345
346
347
348
349
350
351
352
353
354
  			/* 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...
355
356
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357
358
359
  			break;
  		}
  		if (do_wakeup) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
360
361
  			wake_up_interruptible_sync(&pipe->wait);
   			kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
363
  		pipe_wait(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
365
  	mutex_unlock(&inode->i_mutex);
341b446bc   Ingo Molnar   [PATCH] another r...
366
367
  
  	/* Signal writers asynchronously that there is more room. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
  	if (do_wakeup) {
71e20f187   Ingo Molnar   sched: affine syn...
369
  		wake_up_interruptible_sync(&pipe->wait);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
370
  		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
371
372
373
374
375
376
377
  	}
  	if (ret > 0)
  		file_accessed(filp);
  	return ret;
  }
  
  static ssize_t
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
378
379
  pipe_write(struct kiocb *iocb, const struct iovec *_iov,
  	    unsigned long nr_segs, loff_t ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
  {
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
381
  	struct file *filp = iocb->ki_filp;
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
382
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
383
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
385
386
387
388
389
390
391
392
393
394
395
396
  	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...
397
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
398
  	pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
400
  	if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
404
405
406
407
  		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...
408
  	if (pipe->nrbufs && chars != 0) {
341b446bc   Ingo Molnar   [PATCH] another r...
409
410
  		int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
  							(PIPE_BUFFERS-1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
411
  		struct pipe_buffer *buf = pipe->bufs + lastbuf;
d4c3cca94   Eric Dumazet   [PATCH] constify ...
412
  		const struct pipe_buf_operations *ops = buf->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
413
  		int offset = buf->offset + buf->len;
341b446bc   Ingo Molnar   [PATCH] another r...
414

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

cac36bb06   Jens Axboe   pipe: change the ...
419
  			error = ops->confirm(pipe, buf);
f84d75199   Jens Axboe   [PATCH] pipe: int...
420
  			if (error)
5274f052e   Jens Axboe   [PATCH] Introduce...
421
  				goto out;
f84d75199   Jens Axboe   [PATCH] pipe: int...
422

f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
423
424
425
  			iov_fault_in_pages_read(iov, chars);
  redo1:
  			addr = ops->map(pipe, buf, atomic);
5274f052e   Jens Axboe   [PATCH] Introduce...
426
  			error = pipe_iov_copy_from_user(offset + addr, iov,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
427
428
  							chars, atomic);
  			ops->unmap(pipe, buf, addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
429
430
  			ret = error;
  			do_wakeup = 1;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
431
432
433
434
435
  			if (error) {
  				if (atomic) {
  					atomic = 0;
  					goto redo1;
  				}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
  				goto out;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
437
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
439
440
441
442
443
444
445
446
447
  			buf->len += chars;
  			total_len -= chars;
  			ret = chars;
  			if (!total_len)
  				goto out;
  		}
  	}
  
  	for (;;) {
  		int bufs;
341b446bc   Ingo Molnar   [PATCH] another r...
448

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
449
  		if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
  			send_sig(SIGPIPE, current, 0);
341b446bc   Ingo Molnar   [PATCH] another r...
451
452
  			if (!ret)
  				ret = -EPIPE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
453
454
  			break;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
455
  		bufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
  		if (bufs < PIPE_BUFFERS) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
457
458
459
  			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...
460
461
  			char *src;
  			int error, atomic = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
463
464
465
466
467
468
  
  			if (!page) {
  				page = alloc_page(GFP_HIGHUSER);
  				if (unlikely(!page)) {
  					ret = ret ? : -ENOMEM;
  					break;
  				}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
469
  				pipe->tmp_page = page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
470
  			}
341b446bc   Ingo Molnar   [PATCH] another r...
471
  			/* Always wake up, even if the copy fails. Otherwise
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
473
474
475
476
477
478
479
  			 * 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...
480
481
482
483
484
485
486
487
488
489
490
491
492
  			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
493
  			if (unlikely(error)) {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
494
495
496
497
  				if (atomic) {
  					atomic = 0;
  					goto redo2;
  				}
341b446bc   Ingo Molnar   [PATCH] another r...
498
  				if (!ret)
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
499
  					ret = error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
500
501
502
503
504
505
506
507
508
  				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...
509
510
  			pipe->nrbufs = ++bufs;
  			pipe->tmp_page = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511
512
513
514
515
516
517
518
  
  			total_len -= chars;
  			if (!total_len)
  				break;
  		}
  		if (bufs < PIPE_BUFFERS)
  			continue;
  		if (filp->f_flags & O_NONBLOCK) {
341b446bc   Ingo Molnar   [PATCH] another r...
519
520
  			if (!ret)
  				ret = -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
521
522
523
  			break;
  		}
  		if (signal_pending(current)) {
341b446bc   Ingo Molnar   [PATCH] another r...
524
525
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
528
  			break;
  		}
  		if (do_wakeup) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
529
530
  			wake_up_interruptible_sync(&pipe->wait);
  			kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
532
  			do_wakeup = 0;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
533
534
535
  		pipe->waiting_writers++;
  		pipe_wait(pipe);
  		pipe->waiting_writers--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
537
  	}
  out:
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
538
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
  	if (do_wakeup) {
71e20f187   Ingo Molnar   sched: affine syn...
540
  		wake_up_interruptible_sync(&pipe->wait);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
541
  		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
543
  	}
  	if (ret > 0)
870f48179   Christoph Hellwig   [PATCH] replace i...
544
  		file_update_time(filp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545
546
547
548
  	return ret;
  }
  
  static ssize_t
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
549
550
551
552
553
554
  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...
555
556
  bad_pipe_w(struct file *filp, const char __user *buf, size_t count,
  	   loff_t *ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
557
558
559
  {
  	return -EBADF;
  }
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
560
  static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
561
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
562
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
563
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
564
565
566
567
  	int count, buf, nrbufs;
  
  	switch (cmd) {
  		case FIONREAD:
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
568
  			mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
569
  			pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570
  			count = 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
571
572
  			buf = pipe->curbuf;
  			nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573
  			while (--nrbufs >= 0) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
574
  				count += pipe->bufs[buf].len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
576
  				buf = (buf+1) & (PIPE_BUFFERS-1);
  			}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
577
  			mutex_unlock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
578

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
579
580
581
582
583
584
585
586
587
588
589
  			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...
590
  	struct inode *inode = filp->f_path.dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
591
  	struct pipe_inode_info *pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
592
  	int nrbufs;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
593
  	poll_wait(filp, &pipe->wait, wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594
595
  
  	/* Reading only -- no need for acquiring the semaphore.  */
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
596
  	nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
597
598
599
  	mask = 0;
  	if (filp->f_mode & FMODE_READ) {
  		mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
600
  		if (!pipe->writers && filp->f_version != pipe->w_counter)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
601
602
603
604
605
  			mask |= POLLHUP;
  	}
  
  	if (filp->f_mode & FMODE_WRITE) {
  		mask |= (nrbufs < PIPE_BUFFERS) ? POLLOUT | POLLWRNORM : 0;
5e5d7a222   Pekka Enberg   [PATCH] pipe: rem...
606
607
608
609
  		/*
  		 * 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...
610
  		if (!pipe->readers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
612
613
614
615
  			mask |= POLLERR;
  	}
  
  	return mask;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
616
617
618
  static int
  pipe_release(struct inode *inode, int decr, int decw)
  {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
619
  	struct pipe_inode_info *pipe;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
620
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
621
622
623
  	pipe = inode->i_pipe;
  	pipe->readers -= decr;
  	pipe->writers -= decw;
341b446bc   Ingo Molnar   [PATCH] another r...
624

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
625
  	if (!pipe->readers && !pipe->writers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
627
  		free_pipe_info(inode);
  	} else {
71e20f187   Ingo Molnar   sched: affine syn...
628
  		wake_up_interruptible_sync(&pipe->wait);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
629
630
  		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
  		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
632
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
634
635
636
637
638
639
  
  	return 0;
  }
  
  static int
  pipe_read_fasync(int fd, struct file *filp, int on)
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
640
  	struct inode *inode = filp->f_path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
642
643
644
  	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
645

60aa49243   Jonathan Corbet   Rationalize fasyn...
646
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
647
648
649
650
651
652
  }
  
  
  static int
  pipe_write_fasync(int fd, struct file *filp, int on)
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
653
  	struct inode *inode = filp->f_path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
655
656
657
  	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
658

60aa49243   Jonathan Corbet   Rationalize fasyn...
659
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
660
661
662
663
664
665
  }
  
  
  static int
  pipe_rdwr_fasync(int fd, struct file *filp, int on)
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
666
  	struct inode *inode = filp->f_path.dentry->d_inode;
341b446bc   Ingo Molnar   [PATCH] another r...
667
  	struct pipe_inode_info *pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
669
  	mutex_lock(&inode->i_mutex);
341b446bc   Ingo Molnar   [PATCH] another r...
670
  	retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
e5bc49ba7   Oleg Nesterov   pipe_rdwr_fasync:...
671
  	if (retval >= 0) {
341b446bc   Ingo Molnar   [PATCH] another r...
672
  		retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
e5bc49ba7   Oleg Nesterov   pipe_rdwr_fasync:...
673
674
675
  		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...
676
  	mutex_unlock(&inode->i_mutex);
60aa49243   Jonathan Corbet   Rationalize fasyn...
677
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
678
679
680
681
682
683
  }
  
  
  static int
  pipe_read_release(struct inode *inode, struct file *filp)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
684
685
686
687
688
689
  	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
690
691
692
693
694
695
696
  	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
697
698
699
700
701
702
703
704
705
706
  	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...
707
708
709
  	mutex_lock(&inode->i_mutex);
  	inode->i_pipe->readers++;
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710
711
712
713
714
715
716
  
  	return 0;
  }
  
  static int
  pipe_write_open(struct inode *inode, struct file *filp)
  {
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
717
718
719
  	mutex_lock(&inode->i_mutex);
  	inode->i_pipe->writers++;
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720
721
722
723
724
725
726
  
  	return 0;
  }
  
  static int
  pipe_rdwr_open(struct inode *inode, struct file *filp)
  {
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
727
  	mutex_lock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
728
  	if (filp->f_mode & FMODE_READ)
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
729
  		inode->i_pipe->readers++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
730
  	if (filp->f_mode & FMODE_WRITE)
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
731
732
  		inode->i_pipe->writers++;
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
733
734
735
736
737
738
739
  
  	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...
740
741
   *
   * Pipes reuse fifos' file_operations structs.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
742
   */
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
743
  const struct file_operations read_pipefifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
744
  	.llseek		= no_llseek,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
745
746
  	.read		= do_sync_read,
  	.aio_read	= pipe_read,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
747
748
  	.write		= bad_pipe_w,
  	.poll		= pipe_poll,
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
749
  	.unlocked_ioctl	= pipe_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750
751
752
753
  	.open		= pipe_read_open,
  	.release	= pipe_read_release,
  	.fasync		= pipe_read_fasync,
  };
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
754
  const struct file_operations write_pipefifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
755
756
  	.llseek		= no_llseek,
  	.read		= bad_pipe_r,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
757
758
  	.write		= do_sync_write,
  	.aio_write	= pipe_write,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
759
  	.poll		= pipe_poll,
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
760
  	.unlocked_ioctl	= pipe_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
761
762
763
764
  	.open		= pipe_write_open,
  	.release	= pipe_write_release,
  	.fasync		= pipe_write_fasync,
  };
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
765
  const struct file_operations rdwr_pipefifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
766
  	.llseek		= no_llseek,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
767
768
769
770
  	.read		= do_sync_read,
  	.aio_read	= pipe_read,
  	.write		= do_sync_write,
  	.aio_write	= pipe_write,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
771
  	.poll		= pipe_poll,
d59d0b1b8   Andi Kleen   BKL-Removal: conv...
772
  	.unlocked_ioctl	= pipe_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
773
774
775
776
  	.open		= pipe_rdwr_open,
  	.release	= pipe_rdwr_release,
  	.fasync		= pipe_rdwr_fasync,
  };
3a326a2ce   Ingo Molnar   [PATCH] introduce...
777
778
  struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
  {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
779
  	struct pipe_inode_info *pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
780

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
781
782
783
784
785
  	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...
786
  	}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
787
  	return pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
788
  }
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
789
  void __free_pipe_info(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
790
791
  {
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
792

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
793
  	for (i = 0; i < PIPE_BUFFERS; i++) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
794
  		struct pipe_buffer *buf = pipe->bufs + i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
795
  		if (buf->ops)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
796
  			buf->ops->release(pipe, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
797
  	}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
798
799
800
  	if (pipe->tmp_page)
  		__free_page(pipe->tmp_page);
  	kfree(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
801
  }
b92ce5589   Jens Axboe   [PATCH] splice: a...
802
803
804
805
806
  void free_pipe_info(struct inode *inode)
  {
  	__free_pipe_info(inode->i_pipe);
  	inode->i_pipe = NULL;
  }
fa3536cc1   Eric Dumazet   [PATCH] Use __rea...
807
  static struct vfsmount *pipe_mnt __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
808
809
  static int pipefs_delete_dentry(struct dentry *dentry)
  {
d18de5a27   Eric Dumazet   [PATCH] don't ins...
810
811
812
813
814
815
816
817
  	/*
  	 * 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
818
  }
341b446bc   Ingo Molnar   [PATCH] another r...
819

c23fbb6bc   Eric Dumazet   VFS: delay the de...
820
821
822
823
824
825
826
827
  /*
   * 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...
828
  static const struct dentry_operations pipefs_dentry_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
  	.d_delete	= pipefs_delete_dentry,
c23fbb6bc   Eric Dumazet   VFS: delay the de...
830
  	.d_dname	= pipefs_dname,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
831
832
833
834
835
  };
  
  static struct inode * get_pipe_inode(void)
  {
  	struct inode *inode = new_inode(pipe_mnt->mnt_sb);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
836
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
837
838
839
  
  	if (!inode)
  		goto fail_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
840
841
  	pipe = alloc_pipe_info(inode);
  	if (!pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
842
  		goto fail_iput;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
843
  	inode->i_pipe = pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
844

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
845
  	pipe->readers = pipe->writers = 1;
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
846
  	inode->i_fop = &rdwr_pipefifo_fops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
847
848
849
850
851
852
853
854
855
  
  	/*
  	 * 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...
856
857
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858
  	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
859

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
860
861
862
863
  	return inode;
  
  fail_iput:
  	iput(inode);
341b446bc   Ingo Molnar   [PATCH] another r...
864

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
865
866
867
  fail_inode:
  	return NULL;
  }
be61a86d7   Ulrich Drepper   flag parameters: ...
868
  struct file *create_write_pipe(int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
869
  {
d6cbd281d   Andi Kleen   [PATCH] Some clea...
870
871
872
  	int err;
  	struct inode *inode;
  	struct file *f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
873
  	struct dentry *dentry;
c23fbb6bc   Eric Dumazet   VFS: delay the de...
874
  	struct qstr name = { .name = "" };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
875

d6cbd281d   Andi Kleen   [PATCH] Some clea...
876
  	err = -ENFILE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
877
878
  	inode = get_pipe_inode();
  	if (!inode)
430e285e0   Dave Hansen   [PATCH] fix up ne...
879
  		goto err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
880

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
886
  	dentry->d_op = &pipefs_dentry_operations;
d18de5a27   Eric Dumazet   [PATCH] don't ins...
887
888
889
890
891
892
893
  	/*
  	 * 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...
894
895
  
  	err = -ENFILE;
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
896
  	f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipefifo_fops);
430e285e0   Dave Hansen   [PATCH] fix up ne...
897
898
  	if (!f)
  		goto err_dentry;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
899
  	f->f_mapping = inode->i_mapping;
341b446bc   Ingo Molnar   [PATCH] another r...
900

be61a86d7   Ulrich Drepper   flag parameters: ...
901
  	f->f_flags = O_WRONLY | (flags & O_NONBLOCK);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
902
903
904
  	f->f_version = 0;
  
  	return f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
905

430e285e0   Dave Hansen   [PATCH] fix up ne...
906
   err_dentry:
ed1524371   Al Viro   [PATCH] double-fr...
907
  	free_pipe_info(inode);
430e285e0   Dave Hansen   [PATCH] fix up ne...
908
  	dput(dentry);
ed1524371   Al Viro   [PATCH] double-fr...
909
  	return ERR_PTR(err);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
910
   err_inode:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
911
912
  	free_pipe_info(inode);
  	iput(inode);
430e285e0   Dave Hansen   [PATCH] fix up ne...
913
   err:
d6cbd281d   Andi Kleen   [PATCH] Some clea...
914
915
916
917
918
  	return ERR_PTR(err);
  }
  
  void free_write_pipe(struct file *f)
  {
5ccac88ee   Al Viro   [PATCH] fix leaks...
919
  	free_pipe_info(f->f_dentry->d_inode);
c8e7f449b   Jan Blunck   [patch 1/4] vfs: ...
920
  	path_put(&f->f_path);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
921
922
  	put_filp(f);
  }
be61a86d7   Ulrich Drepper   flag parameters: ...
923
  struct file *create_read_pipe(struct file *wrf, int flags)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
924
925
926
927
928
929
  {
  	struct file *f = get_empty_filp();
  	if (!f)
  		return ERR_PTR(-ENFILE);
  
  	/* Grab pipe from the writer */
c8e7f449b   Jan Blunck   [patch 1/4] vfs: ...
930
931
  	f->f_path = wrf->f_path;
  	path_get(&wrf->f_path);
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
932
  	f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
933
934
  
  	f->f_pos = 0;
be61a86d7   Ulrich Drepper   flag parameters: ...
935
  	f->f_flags = O_RDONLY | (flags & O_NONBLOCK);
d2d9648ec   Denys Vlasenko   [PATCH] reuse xxx...
936
  	f->f_op = &read_pipefifo_fops;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
937
938
939
940
941
  	f->f_mode = FMODE_READ;
  	f->f_version = 0;
  
  	return f;
  }
ed8cae8ba   Ulrich Drepper   flag parameters: ...
942
  int do_pipe_flags(int *fd, int flags)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
943
944
945
946
  {
  	struct file *fw, *fr;
  	int error;
  	int fdw, fdr;
be61a86d7   Ulrich Drepper   flag parameters: ...
947
  	if (flags & ~(O_CLOEXEC | O_NONBLOCK))
ed8cae8ba   Ulrich Drepper   flag parameters: ...
948
  		return -EINVAL;
be61a86d7   Ulrich Drepper   flag parameters: ...
949
  	fw = create_write_pipe(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
950
951
  	if (IS_ERR(fw))
  		return PTR_ERR(fw);
be61a86d7   Ulrich Drepper   flag parameters: ...
952
  	fr = create_read_pipe(fw, flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
953
954
955
  	error = PTR_ERR(fr);
  	if (IS_ERR(fr))
  		goto err_write_pipe;
ed8cae8ba   Ulrich Drepper   flag parameters: ...
956
  	error = get_unused_fd_flags(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
957
958
959
  	if (error < 0)
  		goto err_read_pipe;
  	fdr = error;
ed8cae8ba   Ulrich Drepper   flag parameters: ...
960
  	error = get_unused_fd_flags(flags);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
961
962
963
  	if (error < 0)
  		goto err_fdr;
  	fdw = error;
157cf649a   Al Viro   sanitize audit_fd...
964
  	audit_fd_pair(fdr, fdw);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
965
966
967
968
969
970
971
972
973
974
  	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: ...
975
  	path_put(&fr->f_path);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
976
977
978
979
  	put_filp(fr);
   err_write_pipe:
  	free_write_pipe(fw);
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
980
981
982
  }
  
  /*
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
983
984
985
   * 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...
986
  SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
987
988
989
  {
  	int fd[2];
  	int error;
ed8cae8ba   Ulrich Drepper   flag parameters: ...
990
  	error = do_pipe_flags(fd, flags);
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
991
  	if (!error) {
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
992
993
994
  		if (copy_to_user(fildes, fd, sizeof(fd))) {
  			sys_close(fd[0]);
  			sys_close(fd[1]);
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
995
  			error = -EFAULT;
ba719baea   Ulrich Drepper   sys_pipe(): fix f...
996
  		}
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
997
998
999
  	}
  	return error;
  }
2b6642199   Heiko Carstens   [CVE-2009-0029] S...
1000
  SYSCALL_DEFINE1(pipe, int __user *, fildes)
ed8cae8ba   Ulrich Drepper   flag parameters: ...
1001
1002
1003
  {
  	return sys_pipe2(fildes, 0);
  }
d35c7b0e5   Ulrich Drepper   unified (weak) sy...
1004
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1005
1006
1007
1008
1009
   * 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...
1010
1011
1012
  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
1013
  {
454e2398b   David Howells   [PATCH] VFS: Perm...
1014
  	return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC, mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
  }
  
  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...
1026

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
  	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);