Blame view

fs/pipe.c 21.5 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>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
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
   */
  
  /* Drop the inode semaphore and wait for a pipe event, atomically */
3a326a2ce   Ingo Molnar   [PATCH] introduce...
39
  void pipe_wait(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
  {
  	DEFINE_WAIT(wait);
d79fc0fc6   Ingo Molnar   [PATCH] sched: TA...
42
43
44
45
  	/*
  	 * Pipes are system-local resources, so sleeping on them
  	 * is considered a noninteractive wait:
  	 */
341b446bc   Ingo Molnar   [PATCH] another r...
46
47
  	prepare_to_wait(&pipe->wait, &wait,
  			TASK_INTERRUPTIBLE | TASK_NONINTERACTIVE);
3a326a2ce   Ingo Molnar   [PATCH] introduce...
48
49
  	if (pipe->inode)
  		mutex_unlock(&pipe->inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
  	schedule();
3a326a2ce   Ingo Molnar   [PATCH] introduce...
51
52
53
  	finish_wait(&pipe->wait, &wait);
  	if (pipe->inode)
  		mutex_lock(&pipe->inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  }
858119e15   Arjan van de Ven   [PATCH] Unlinline...
55
  static int
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
56
57
  pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len,
  			int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
60
61
62
63
64
  {
  	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...
65
66
67
68
69
70
71
  		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
72
73
74
75
76
77
78
  		to += copy;
  		len -= copy;
  		iov->iov_base += copy;
  		iov->iov_len -= copy;
  	}
  	return 0;
  }
858119e15   Arjan van de Ven   [PATCH] Unlinline...
79
  static int
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
80
81
  pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len,
  		      int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
83
84
85
86
87
88
  {
  	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...
89
90
91
92
93
94
95
  		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
96
97
98
99
100
101
102
  		from += copy;
  		len -= copy;
  		iov->iov_base += copy;
  		iov->iov_len -= copy;
  	}
  	return 0;
  }
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
103
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
  /*
   * 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...
143
144
  static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
  				  struct pipe_buffer *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
  {
  	struct page *page = buf->page;
5274f052e   Jens Axboe   [PATCH] Introduce...
147
148
149
  	/*
  	 * 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...
150
  	 * allocation cache. (Otherwise just release our reference to it)
5274f052e   Jens Axboe   [PATCH] Introduce...
151
  	 */
341b446bc   Ingo Molnar   [PATCH] another r...
152
  	if (page_count(page) == 1 && !pipe->tmp_page)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
153
  		pipe->tmp_page = page;
341b446bc   Ingo Molnar   [PATCH] another r...
154
155
  	else
  		page_cache_release(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
  }
f84d75199   Jens Axboe   [PATCH] pipe: int...
157
  void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
158
  			   struct pipe_buffer *buf, int atomic)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
  {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
160
161
162
163
  	if (atomic) {
  		buf->flags |= PIPE_BUF_FLAG_ATOMIC;
  		return kmap_atomic(buf->page, KM_USER0);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
  	return kmap(buf->page);
  }
f84d75199   Jens Axboe   [PATCH] pipe: int...
166
  void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
167
  			    struct pipe_buffer *buf, void *map_data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
  {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
169
170
171
172
173
  	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
174
  }
330ab7161   Jens Axboe   [PATCH] vmsplice:...
175
176
  int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
  			   struct pipe_buffer *buf)
5abc97aa2   Jens Axboe   [PATCH] splice: a...
177
  {
46e678c96   Jens Axboe   [PATCH] splice: f...
178
179
180
  	struct page *page = buf->page;
  
  	if (page_count(page) == 1) {
46e678c96   Jens Axboe   [PATCH] splice: f...
181
182
183
184
185
  		lock_page(page);
  		return 0;
  	}
  
  	return 1;
5abc97aa2   Jens Axboe   [PATCH] splice: a...
186
  }
f84d75199   Jens Axboe   [PATCH] pipe: int...
187
  void generic_pipe_buf_get(struct pipe_inode_info *info, struct pipe_buffer *buf)
70524490e   Jens Axboe   [PATCH] splice: a...
188
189
190
  {
  	page_cache_get(buf->page);
  }
f84d75199   Jens Axboe   [PATCH] pipe: int...
191
192
193
194
  int generic_pipe_buf_pin(struct pipe_inode_info *info, struct pipe_buffer *buf)
  {
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
196
  static struct pipe_buf_operations anon_pipe_buf_ops = {
  	.can_merge = 1,
f84d75199   Jens Axboe   [PATCH] pipe: int...
197
198
199
  	.map = generic_pipe_buf_map,
  	.unmap = generic_pipe_buf_unmap,
  	.pin = generic_pipe_buf_pin,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
  	.release = anon_pipe_buf_release,
330ab7161   Jens Axboe   [PATCH] vmsplice:...
201
  	.steal = generic_pipe_buf_steal,
f84d75199   Jens Axboe   [PATCH] pipe: int...
202
  	.get = generic_pipe_buf_get,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
205
  };
  
  static ssize_t
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
206
207
  pipe_read(struct kiocb *iocb, const struct iovec *_iov,
  	   unsigned long nr_segs, loff_t pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
  {
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
209
  	struct file *filp = iocb->ki_filp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
  	struct inode *inode = filp->f_dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
211
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
213
214
215
216
217
218
219
220
221
222
223
  	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...
224
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
225
  	pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
  	for (;;) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
227
  		int bufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
  		if (bufs) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
229
230
  			int curbuf = pipe->curbuf;
  			struct pipe_buffer *buf = pipe->bufs + curbuf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
232
233
  			struct pipe_buf_operations *ops = buf->ops;
  			void *addr;
  			size_t chars = buf->len;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
234
  			int error, atomic;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
236
237
  
  			if (chars > total_len)
  				chars = total_len;
f84d75199   Jens Axboe   [PATCH] pipe: int...
238
239
  			error = ops->pin(pipe, buf);
  			if (error) {
5274f052e   Jens Axboe   [PATCH] Introduce...
240
  				if (!ret)
f84d75199   Jens Axboe   [PATCH] pipe: int...
241
  					error = ret;
5274f052e   Jens Axboe   [PATCH] Introduce...
242
243
  				break;
  			}
f84d75199   Jens Axboe   [PATCH] pipe: int...
244

f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
245
246
247
248
249
  			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
250
  			if (unlikely(error)) {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
251
252
253
254
255
256
257
  				/*
  				 * Just retry with the slow path if we failed.
  				 */
  				if (atomic) {
  					atomic = 0;
  					goto redo;
  				}
341b446bc   Ingo Molnar   [PATCH] another r...
258
  				if (!ret)
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
259
  					ret = error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
261
262
263
264
265
266
  				break;
  			}
  			ret += chars;
  			buf->offset += chars;
  			buf->len -= chars;
  			if (!buf->len) {
  				buf->ops = NULL;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
267
  				ops->release(pipe, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
  				curbuf = (curbuf + 1) & (PIPE_BUFFERS-1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
269
270
  				pipe->curbuf = curbuf;
  				pipe->nrbufs = --bufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
272
273
274
275
276
277
278
  				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...
279
  		if (!pipe->writers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
  			break;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
281
  		if (!pipe->waiting_writers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
284
285
286
287
288
289
290
291
292
293
294
  			/* 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...
295
296
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
298
299
  			break;
  		}
  		if (do_wakeup) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
300
301
  			wake_up_interruptible_sync(&pipe->wait);
   			kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
303
  		pipe_wait(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
305
  	mutex_unlock(&inode->i_mutex);
341b446bc   Ingo Molnar   [PATCH] another r...
306
307
  
  	/* Signal writers asynchronously that there is more room. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
  	if (do_wakeup) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
309
310
  		wake_up_interruptible(&pipe->wait);
  		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311
312
313
314
315
316
317
  	}
  	if (ret > 0)
  		file_accessed(filp);
  	return ret;
  }
  
  static ssize_t
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
318
319
  pipe_write(struct kiocb *iocb, const struct iovec *_iov,
  	    unsigned long nr_segs, loff_t ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  {
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
321
  	struct file *filp = iocb->ki_filp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
  	struct inode *inode = filp->f_dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
323
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
325
326
327
328
329
330
331
332
333
334
335
336
  	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...
337
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
338
  	pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
340
  	if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
342
343
344
345
346
347
  		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...
348
  	if (pipe->nrbufs && chars != 0) {
341b446bc   Ingo Molnar   [PATCH] another r...
349
350
  		int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
  							(PIPE_BUFFERS-1);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
351
  		struct pipe_buffer *buf = pipe->bufs + lastbuf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
  		struct pipe_buf_operations *ops = buf->ops;
  		int offset = buf->offset + buf->len;
341b446bc   Ingo Molnar   [PATCH] another r...
354

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

f84d75199   Jens Axboe   [PATCH] pipe: int...
359
360
  			error = ops->pin(pipe, buf);
  			if (error)
5274f052e   Jens Axboe   [PATCH] Introduce...
361
  				goto out;
f84d75199   Jens Axboe   [PATCH] pipe: int...
362

f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
363
364
365
  			iov_fault_in_pages_read(iov, chars);
  redo1:
  			addr = ops->map(pipe, buf, atomic);
5274f052e   Jens Axboe   [PATCH] Introduce...
366
  			error = pipe_iov_copy_from_user(offset + addr, iov,
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
367
368
  							chars, atomic);
  			ops->unmap(pipe, buf, addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
370
  			ret = error;
  			do_wakeup = 1;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
371
372
373
374
375
  			if (error) {
  				if (atomic) {
  					atomic = 0;
  					goto redo1;
  				}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
  				goto out;
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
377
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
379
380
381
382
383
384
385
386
387
  			buf->len += chars;
  			total_len -= chars;
  			ret = chars;
  			if (!total_len)
  				goto out;
  		}
  	}
  
  	for (;;) {
  		int bufs;
341b446bc   Ingo Molnar   [PATCH] another r...
388

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
389
  		if (!pipe->readers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
  			send_sig(SIGPIPE, current, 0);
341b446bc   Ingo Molnar   [PATCH] another r...
391
392
  			if (!ret)
  				ret = -EPIPE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
394
  			break;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
395
  		bufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
  		if (bufs < PIPE_BUFFERS) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
397
398
399
  			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...
400
401
  			char *src;
  			int error, atomic = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
403
404
405
406
407
408
  
  			if (!page) {
  				page = alloc_page(GFP_HIGHUSER);
  				if (unlikely(!page)) {
  					ret = ret ? : -ENOMEM;
  					break;
  				}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
409
  				pipe->tmp_page = page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
  			}
341b446bc   Ingo Molnar   [PATCH] another r...
411
  			/* Always wake up, even if the copy fails. Otherwise
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
413
414
415
416
417
418
419
  			 * 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...
420
421
422
423
424
425
426
427
428
429
430
431
432
  			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
433
  			if (unlikely(error)) {
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
434
435
436
437
  				if (atomic) {
  					atomic = 0;
  					goto redo2;
  				}
341b446bc   Ingo Molnar   [PATCH] another r...
438
  				if (!ret)
f6762b7ad   Jens Axboe   [PATCH] pipe: ena...
439
  					ret = error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
441
442
443
444
445
446
447
448
  				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...
449
450
  			pipe->nrbufs = ++bufs;
  			pipe->tmp_page = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
452
453
454
455
456
457
458
  
  			total_len -= chars;
  			if (!total_len)
  				break;
  		}
  		if (bufs < PIPE_BUFFERS)
  			continue;
  		if (filp->f_flags & O_NONBLOCK) {
341b446bc   Ingo Molnar   [PATCH] another r...
459
460
  			if (!ret)
  				ret = -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
461
462
463
  			break;
  		}
  		if (signal_pending(current)) {
341b446bc   Ingo Molnar   [PATCH] another r...
464
465
  			if (!ret)
  				ret = -ERESTARTSYS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
466
467
468
  			break;
  		}
  		if (do_wakeup) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
469
470
  			wake_up_interruptible_sync(&pipe->wait);
  			kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471
472
  			do_wakeup = 0;
  		}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
473
474
475
  		pipe->waiting_writers++;
  		pipe_wait(pipe);
  		pipe->waiting_writers--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
476
477
  	}
  out:
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
478
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
479
  	if (do_wakeup) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
480
481
  		wake_up_interruptible(&pipe->wait);
  		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
482
483
  	}
  	if (ret > 0)
870f48179   Christoph Hellwig   [PATCH] replace i...
484
  		file_update_time(filp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
486
487
488
  	return ret;
  }
  
  static ssize_t
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
490
491
492
493
494
  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...
495
496
  bad_pipe_w(struct file *filp, const char __user *buf, size_t count,
  	   loff_t *ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497
498
499
500
501
502
503
504
505
  {
  	return -EBADF;
  }
  
  static int
  pipe_ioctl(struct inode *pino, struct file *filp,
  	   unsigned int cmd, unsigned long arg)
  {
  	struct inode *inode = filp->f_dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
506
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
508
509
510
  	int count, buf, nrbufs;
  
  	switch (cmd) {
  		case FIONREAD:
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
511
  			mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
512
  			pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513
  			count = 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
514
515
  			buf = pipe->curbuf;
  			nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
  			while (--nrbufs >= 0) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
517
  				count += pipe->bufs[buf].len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
518
519
  				buf = (buf+1) & (PIPE_BUFFERS-1);
  			}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
520
  			mutex_unlock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
521

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
523
524
525
526
527
528
529
530
531
532
533
  			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;
  	struct inode *inode = filp->f_dentry->d_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
534
  	struct pipe_inode_info *pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535
  	int nrbufs;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
536
  	poll_wait(filp, &pipe->wait, wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537
538
  
  	/* Reading only -- no need for acquiring the semaphore.  */
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
539
  	nrbufs = pipe->nrbufs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
540
541
542
  	mask = 0;
  	if (filp->f_mode & FMODE_READ) {
  		mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
543
  		if (!pipe->writers && filp->f_version != pipe->w_counter)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
544
545
546
547
548
  			mask |= POLLHUP;
  	}
  
  	if (filp->f_mode & FMODE_WRITE) {
  		mask |= (nrbufs < PIPE_BUFFERS) ? POLLOUT | POLLWRNORM : 0;
5e5d7a222   Pekka Enberg   [PATCH] pipe: rem...
549
550
551
552
  		/*
  		 * 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...
553
  		if (!pipe->readers)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
554
555
556
557
558
  			mask |= POLLERR;
  	}
  
  	return mask;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
560
561
  static int
  pipe_release(struct inode *inode, int decr, int decw)
  {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
562
  	struct pipe_inode_info *pipe;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
563
  	mutex_lock(&inode->i_mutex);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
564
565
566
  	pipe = inode->i_pipe;
  	pipe->readers -= decr;
  	pipe->writers -= decw;
341b446bc   Ingo Molnar   [PATCH] another r...
567

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
568
  	if (!pipe->readers && !pipe->writers) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
569
570
  		free_pipe_info(inode);
  	} else {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
571
572
573
  		wake_up_interruptible(&pipe->wait);
  		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
  		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
574
  	}
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
575
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
576
577
578
579
580
581
582
583
584
  
  	return 0;
  }
  
  static int
  pipe_read_fasync(int fd, struct file *filp, int on)
  {
  	struct inode *inode = filp->f_dentry->d_inode;
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
585
586
587
  	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
588
589
590
591
592
593
594
595
596
597
598
599
600
  
  	if (retval < 0)
  		return retval;
  
  	return 0;
  }
  
  
  static int
  pipe_write_fasync(int fd, struct file *filp, int on)
  {
  	struct inode *inode = filp->f_dentry->d_inode;
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
601
602
603
  	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
604
605
606
607
608
609
610
611
612
613
614
615
  
  	if (retval < 0)
  		return retval;
  
  	return 0;
  }
  
  
  static int
  pipe_rdwr_fasync(int fd, struct file *filp, int on)
  {
  	struct inode *inode = filp->f_dentry->d_inode;
341b446bc   Ingo Molnar   [PATCH] another r...
616
  	struct pipe_inode_info *pipe = inode->i_pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
617
  	int retval;
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
618
  	mutex_lock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619

341b446bc   Ingo Molnar   [PATCH] another r...
620
  	retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
621
622
  
  	if (retval >= 0)
341b446bc   Ingo Molnar   [PATCH] another r...
623
  		retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624

9aeedfc47   Ingo Molnar   [PATCH] get rid o...
625
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
  
  	if (retval < 0)
  		return retval;
  
  	return 0;
  }
  
  
  static int
  pipe_read_release(struct inode *inode, struct file *filp)
  {
  	pipe_read_fasync(-1, filp, 0);
  	return pipe_release(inode, 1, 0);
  }
  
  static int
  pipe_write_release(struct inode *inode, struct file *filp)
  {
  	pipe_write_fasync(-1, filp, 0);
  	return pipe_release(inode, 0, 1);
  }
  
  static int
  pipe_rdwr_release(struct inode *inode, struct file *filp)
  {
  	int decr, decw;
  
  	pipe_rdwr_fasync(-1, filp, 0);
  	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...
664
665
666
  	mutex_lock(&inode->i_mutex);
  	inode->i_pipe->readers++;
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
667
668
669
670
671
672
673
  
  	return 0;
  }
  
  static int
  pipe_write_open(struct inode *inode, struct file *filp)
  {
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
674
675
676
  	mutex_lock(&inode->i_mutex);
  	inode->i_pipe->writers++;
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
677
678
679
680
681
682
683
  
  	return 0;
  }
  
  static int
  pipe_rdwr_open(struct inode *inode, struct file *filp)
  {
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
684
  	mutex_lock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
685
  	if (filp->f_mode & FMODE_READ)
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
686
  		inode->i_pipe->readers++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
687
  	if (filp->f_mode & FMODE_WRITE)
9aeedfc47   Ingo Molnar   [PATCH] get rid o...
688
689
  		inode->i_pipe->writers++;
  	mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
690
691
692
693
694
695
696
697
  
  	return 0;
  }
  
  /*
   * The file_operations structs are not static because they
   * are also used in linux/fs/fifo.c to do operations on FIFOs.
   */
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
698
  const struct file_operations read_fifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
699
  	.llseek		= no_llseek,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
700
701
  	.read		= do_sync_read,
  	.aio_read	= pipe_read,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
702
  	.write		= bad_pipe_w,
5e5d7a222   Pekka Enberg   [PATCH] pipe: rem...
703
  	.poll		= pipe_poll,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
704
705
706
707
708
  	.ioctl		= pipe_ioctl,
  	.open		= pipe_read_open,
  	.release	= pipe_read_release,
  	.fasync		= pipe_read_fasync,
  };
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
709
  const struct file_operations write_fifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710
711
  	.llseek		= no_llseek,
  	.read		= bad_pipe_r,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
712
713
  	.write		= do_sync_write,
  	.aio_write	= pipe_write,
5e5d7a222   Pekka Enberg   [PATCH] pipe: rem...
714
  	.poll		= pipe_poll,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
715
716
717
718
719
  	.ioctl		= pipe_ioctl,
  	.open		= pipe_write_open,
  	.release	= pipe_write_release,
  	.fasync		= pipe_write_fasync,
  };
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
720
  const struct file_operations rdwr_fifo_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
721
  	.llseek		= no_llseek,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
722
723
724
725
  	.read		= do_sync_read,
  	.aio_read	= pipe_read,
  	.write		= do_sync_write,
  	.aio_write	= pipe_write,
5e5d7a222   Pekka Enberg   [PATCH] pipe: rem...
726
  	.poll		= pipe_poll,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727
728
729
730
731
  	.ioctl		= pipe_ioctl,
  	.open		= pipe_rdwr_open,
  	.release	= pipe_rdwr_release,
  	.fasync		= pipe_rdwr_fasync,
  };
a19cbd4bf   Linus Torvalds   Mark the pipe fil...
732
  static struct file_operations read_pipe_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
733
  	.llseek		= no_llseek,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
734
735
  	.read		= do_sync_read,
  	.aio_read	= pipe_read,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
736
737
738
739
740
741
742
  	.write		= bad_pipe_w,
  	.poll		= pipe_poll,
  	.ioctl		= pipe_ioctl,
  	.open		= pipe_read_open,
  	.release	= pipe_read_release,
  	.fasync		= pipe_read_fasync,
  };
a19cbd4bf   Linus Torvalds   Mark the pipe fil...
743
  static struct file_operations write_pipe_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
744
745
  	.llseek		= no_llseek,
  	.read		= bad_pipe_r,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
746
747
  	.write		= do_sync_write,
  	.aio_write	= pipe_write,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
748
749
750
751
752
753
  	.poll		= pipe_poll,
  	.ioctl		= pipe_ioctl,
  	.open		= pipe_write_open,
  	.release	= pipe_write_release,
  	.fasync		= pipe_write_fasync,
  };
a19cbd4bf   Linus Torvalds   Mark the pipe fil...
754
  static struct file_operations rdwr_pipe_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
755
  	.llseek		= no_llseek,
ee0b3e671   Badari Pulavarty   [PATCH] Remove re...
756
757
758
759
  	.read		= do_sync_read,
  	.aio_read	= pipe_read,
  	.write		= do_sync_write,
  	.aio_write	= pipe_write,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
760
761
762
763
764
765
  	.poll		= pipe_poll,
  	.ioctl		= pipe_ioctl,
  	.open		= pipe_rdwr_open,
  	.release	= pipe_rdwr_release,
  	.fasync		= pipe_rdwr_fasync,
  };
3a326a2ce   Ingo Molnar   [PATCH] introduce...
766
767
  struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
  {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
768
  	struct pipe_inode_info *pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
769

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
770
771
772
773
774
  	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...
775
  	}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
776
  	return pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
777
  }
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
778
  void __free_pipe_info(struct pipe_inode_info *pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779
780
  {
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
781

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
782
  	for (i = 0; i < PIPE_BUFFERS; i++) {
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
783
  		struct pipe_buffer *buf = pipe->bufs + i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
784
  		if (buf->ops)
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
785
  			buf->ops->release(pipe, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
786
  	}
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
787
788
789
  	if (pipe->tmp_page)
  		__free_page(pipe->tmp_page);
  	kfree(pipe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
790
  }
b92ce5589   Jens Axboe   [PATCH] splice: a...
791
792
793
794
795
  void free_pipe_info(struct inode *inode)
  {
  	__free_pipe_info(inode->i_pipe);
  	inode->i_pipe = NULL;
  }
fa3536cc1   Eric Dumazet   [PATCH] Use __rea...
796
  static struct vfsmount *pipe_mnt __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
797
798
799
800
  static int pipefs_delete_dentry(struct dentry *dentry)
  {
  	return 1;
  }
341b446bc   Ingo Molnar   [PATCH] another r...
801

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
802
803
804
805
806
807
808
  static struct dentry_operations pipefs_dentry_operations = {
  	.d_delete	= pipefs_delete_dentry,
  };
  
  static struct inode * get_pipe_inode(void)
  {
  	struct inode *inode = new_inode(pipe_mnt->mnt_sb);
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
809
  	struct pipe_inode_info *pipe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
810
811
812
  
  	if (!inode)
  		goto fail_inode;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
813
814
  	pipe = alloc_pipe_info(inode);
  	if (!pipe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
  		goto fail_iput;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
816
  	inode->i_pipe = pipe;
3a326a2ce   Ingo Molnar   [PATCH] introduce...
817

923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
818
  	pipe->readers = pipe->writers = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
819
820
821
822
823
824
825
826
827
828
829
830
831
  	inode->i_fop = &rdwr_pipe_fops;
  
  	/*
  	 * 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;
  	inode->i_uid = current->fsuid;
  	inode->i_gid = current->fsgid;
  	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
923f4f239   Ingo Molnar   [PATCH] pipe.c/fi...
832

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
838
839
840
  fail_inode:
  	return NULL;
  }
d6cbd281d   Andi Kleen   [PATCH] Some clea...
841
  struct file *create_write_pipe(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
842
  {
d6cbd281d   Andi Kleen   [PATCH] Some clea...
843
844
845
  	int err;
  	struct inode *inode;
  	struct file *f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
846
  	struct dentry *dentry;
d6cbd281d   Andi Kleen   [PATCH] Some clea...
847
848
  	char name[32];
  	struct qstr this;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
849

d6cbd281d   Andi Kleen   [PATCH] Some clea...
850
851
852
853
  	f = get_empty_filp();
  	if (!f)
  		return ERR_PTR(-ENFILE);
  	err = -ENFILE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
854
855
  	inode = get_pipe_inode();
  	if (!inode)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
856
  		goto err_file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
857

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858
859
860
861
  	sprintf(name, "[%lu]", inode->i_ino);
  	this.name = name;
  	this.len = strlen(name);
  	this.hash = inode->i_ino; /* will go */
d6cbd281d   Andi Kleen   [PATCH] Some clea...
862
  	err = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
864
  	dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this);
  	if (!dentry)
d6cbd281d   Andi Kleen   [PATCH] Some clea...
865
  		goto err_inode;
341b446bc   Ingo Molnar   [PATCH] another r...
866

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
867
868
  	dentry->d_op = &pipefs_dentry_operations;
  	d_add(dentry, inode);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
869
870
871
  	f->f_vfsmnt = mntget(pipe_mnt);
  	f->f_dentry = dentry;
  	f->f_mapping = inode->i_mapping;
341b446bc   Ingo Molnar   [PATCH] another r...
872

d6cbd281d   Andi Kleen   [PATCH] Some clea...
873
874
875
876
877
878
  	f->f_flags = O_WRONLY;
  	f->f_op = &write_pipe_fops;
  	f->f_mode = FMODE_WRITE;
  	f->f_version = 0;
  
  	return f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879

d6cbd281d   Andi Kleen   [PATCH] Some clea...
880
   err_inode:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
881
882
  	free_pipe_info(inode);
  	iput(inode);
d6cbd281d   Andi Kleen   [PATCH] Some clea...
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
   err_file:
  	put_filp(f);
  	return ERR_PTR(err);
  }
  
  void free_write_pipe(struct file *f)
  {
  	mntput(f->f_vfsmnt);
  	dput(f->f_dentry);
  	put_filp(f);
  }
  
  struct file *create_read_pipe(struct file *wrf)
  {
  	struct file *f = get_empty_filp();
  	if (!f)
  		return ERR_PTR(-ENFILE);
  
  	/* Grab pipe from the writer */
  	f->f_vfsmnt = mntget(wrf->f_vfsmnt);
  	f->f_dentry = dget(wrf->f_dentry);
  	f->f_mapping = wrf->f_dentry->d_inode->i_mapping;
  
  	f->f_pos = 0;
  	f->f_flags = O_RDONLY;
  	f->f_op = &read_pipe_fops;
  	f->f_mode = FMODE_READ;
  	f->f_version = 0;
  
  	return f;
  }
  
  int do_pipe(int *fd)
  {
  	struct file *fw, *fr;
  	int error;
  	int fdw, fdr;
  
  	fw = create_write_pipe();
  	if (IS_ERR(fw))
  		return PTR_ERR(fw);
  	fr = create_read_pipe(fw);
  	error = PTR_ERR(fr);
  	if (IS_ERR(fr))
  		goto err_write_pipe;
  
  	error = get_unused_fd();
  	if (error < 0)
  		goto err_read_pipe;
  	fdr = error;
  
  	error = get_unused_fd();
  	if (error < 0)
  		goto err_fdr;
  	fdw = error;
  
  	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:
  	put_filp(fr);
   err_write_pipe:
  	free_write_pipe(fw);
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
953
954
955
956
957
958
959
960
  }
  
  /*
   * 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...
961
962
963
  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
964
  {
454e2398b   David Howells   [PATCH] VFS: Perm...
965
  	return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC, mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
966
967
968
969
970
971
972
973
974
975
976
  }
  
  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...
977

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
  	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);