Blame view
fs/pipe.c
29.2 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* * linux/fs/pipe.c * * Copyright (C) 1991, 1992, 1999 Linus Torvalds */ #include <linux/mm.h> #include <linux/file.h> #include <linux/poll.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> |
35f3d14db pipe: add support... |
14 |
#include <linux/log2.h> |
1da177e4c Linux-2.6.12-rc2 |
15 |
#include <linux/mount.h> |
b502bd115 magic.h: move som... |
16 |
#include <linux/magic.h> |
1da177e4c Linux-2.6.12-rc2 |
17 18 19 |
#include <linux/pipe_fs_i.h> #include <linux/uio.h> #include <linux/highmem.h> |
5274f052e [PATCH] Introduce... |
20 |
#include <linux/pagemap.h> |
db3495099 [PATCH] AUDIT_FD_... |
21 |
#include <linux/audit.h> |
ba719baea sys_pipe(): fix f... |
22 |
#include <linux/syscalls.h> |
b492e95be pipe: set lower a... |
23 |
#include <linux/fcntl.h> |
a27bb332c aio: don't includ... |
24 |
#include <linux/aio.h> |
1da177e4c Linux-2.6.12-rc2 |
25 26 27 |
#include <asm/uaccess.h> #include <asm/ioctls.h> |
599a0ac14 pipe: fold file_o... |
28 |
#include "internal.h" |
1da177e4c Linux-2.6.12-rc2 |
29 |
/* |
b492e95be pipe: set lower a... |
30 |
* The max size that a non-root user is allowed to grow the pipe. Can |
ff9da691c pipe: change /pro... |
31 |
* be set by root in /proc/sys/fs/pipe-max-size |
b492e95be pipe: set lower a... |
32 |
*/ |
ff9da691c pipe: change /pro... |
33 34 35 36 37 38 |
unsigned int pipe_max_size = 1048576; /* * Minimum pipe size, as required by POSIX */ unsigned int pipe_min_size = PAGE_SIZE; |
b492e95be pipe: set lower a... |
39 40 |
/* |
1da177e4c Linux-2.6.12-rc2 |
41 42 43 44 45 46 47 48 49 50 51 52 53 |
* We use a start+len construction, which provides full use of the * allocated memory. * -- Florian Coosmann (FGC) * * Reads with count = 0 should always return 0. * -- Julian Bradfield 1999-06-07. * * FIFOs and Pipes now generate SIGIO for both readers and writers. * -- Jeremy Elson <jelson@circlemud.org> 2001-08-16 * * pipe_read & write cleanup * -- Manfred Spraul <manfred@colorfullife.com> 2002-05-09 */ |
61e0d47c3 splice: add helpe... |
54 55 |
static void pipe_lock_nested(struct pipe_inode_info *pipe, int subclass) { |
6447a3cf1 get rid of pipe->... |
56 |
if (pipe->files) |
72b0d9aac pipe: don't use -... |
57 |
mutex_lock_nested(&pipe->mutex, subclass); |
61e0d47c3 splice: add helpe... |
58 59 60 61 62 63 64 65 66 67 68 69 70 |
} void pipe_lock(struct pipe_inode_info *pipe) { /* * pipe_lock() nests non-pipe inode locks (for writing to a file) */ pipe_lock_nested(pipe, I_MUTEX_PARENT); } EXPORT_SYMBOL(pipe_lock); void pipe_unlock(struct pipe_inode_info *pipe) { |
6447a3cf1 get rid of pipe->... |
71 |
if (pipe->files) |
72b0d9aac pipe: don't use -... |
72 |
mutex_unlock(&pipe->mutex); |
61e0d47c3 splice: add helpe... |
73 74 |
} EXPORT_SYMBOL(pipe_unlock); |
ebec73f47 introduce variant... |
75 76 77 78 79 80 81 82 83 |
static inline void __pipe_lock(struct pipe_inode_info *pipe) { mutex_lock_nested(&pipe->mutex, I_MUTEX_PARENT); } static inline void __pipe_unlock(struct pipe_inode_info *pipe) { mutex_unlock(&pipe->mutex); } |
61e0d47c3 splice: add helpe... |
84 85 86 87 88 89 90 91 92 |
void pipe_double_lock(struct pipe_inode_info *pipe1, struct pipe_inode_info *pipe2) { BUG_ON(pipe1 == pipe2); if (pipe1 < pipe2) { pipe_lock_nested(pipe1, I_MUTEX_PARENT); pipe_lock_nested(pipe2, I_MUTEX_CHILD); } else { |
023d43c7b lockdep: Fix lock... |
93 94 |
pipe_lock_nested(pipe2, I_MUTEX_PARENT); pipe_lock_nested(pipe1, I_MUTEX_CHILD); |
61e0d47c3 splice: add helpe... |
95 96 |
} } |
1da177e4c Linux-2.6.12-rc2 |
97 |
/* Drop the inode semaphore and wait for a pipe event, atomically */ |
3a326a2ce [PATCH] introduce... |
98 |
void pipe_wait(struct pipe_inode_info *pipe) |
1da177e4c Linux-2.6.12-rc2 |
99 100 |
{ DEFINE_WAIT(wait); |
d79fc0fc6 [PATCH] sched: TA... |
101 102 103 104 |
/* * Pipes are system-local resources, so sleeping on them * is considered a noninteractive wait: */ |
af9272326 sched: cleanup, r... |
105 |
prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE); |
61e0d47c3 splice: add helpe... |
106 |
pipe_unlock(pipe); |
1da177e4c Linux-2.6.12-rc2 |
107 |
schedule(); |
3a326a2ce [PATCH] introduce... |
108 |
finish_wait(&pipe->wait, &wait); |
61e0d47c3 splice: add helpe... |
109 |
pipe_lock(pipe); |
1da177e4c Linux-2.6.12-rc2 |
110 |
} |
858119e15 [PATCH] Unlinline... |
111 |
static int |
f6762b7ad [PATCH] pipe: ena... |
112 113 |
pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len, int atomic) |
1da177e4c Linux-2.6.12-rc2 |
114 115 116 117 118 119 120 |
{ unsigned long copy; while (len > 0) { while (!iov->iov_len) iov++; copy = min_t(unsigned long, len, iov->iov_len); |
f6762b7ad [PATCH] pipe: ena... |
121 122 123 124 125 126 127 |
if (atomic) { if (__copy_from_user_inatomic(to, iov->iov_base, copy)) return -EFAULT; } else { if (copy_from_user(to, iov->iov_base, copy)) return -EFAULT; } |
1da177e4c Linux-2.6.12-rc2 |
128 129 130 131 132 133 134 |
to += copy; len -= copy; iov->iov_base += copy; iov->iov_len -= copy; } return 0; } |
858119e15 [PATCH] Unlinline... |
135 |
static int |
f6762b7ad [PATCH] pipe: ena... |
136 137 |
pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len, int atomic) |
1da177e4c Linux-2.6.12-rc2 |
138 139 140 141 142 143 144 |
{ unsigned long copy; while (len > 0) { while (!iov->iov_len) iov++; copy = min_t(unsigned long, len, iov->iov_len); |
f6762b7ad [PATCH] pipe: ena... |
145 146 147 148 149 150 151 |
if (atomic) { if (__copy_to_user_inatomic(iov->iov_base, from, copy)) return -EFAULT; } else { if (copy_to_user(iov->iov_base, from, copy)) return -EFAULT; } |
1da177e4c Linux-2.6.12-rc2 |
152 153 154 155 156 157 158 |
from += copy; len -= copy; iov->iov_base += copy; iov->iov_len -= copy; } return 0; } |
f6762b7ad [PATCH] pipe: ena... |
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
/* * Attempt to pre-fault in the user memory, so we can use atomic copies. * Returns the number of bytes not faulted in. */ static int iov_fault_in_pages_write(struct iovec *iov, unsigned long len) { while (!iov->iov_len) iov++; while (len > 0) { unsigned long this_len; this_len = min_t(unsigned long, len, iov->iov_len); if (fault_in_pages_writeable(iov->iov_base, this_len)) break; len -= this_len; iov++; } return len; } /* * Pre-fault in the user memory, so we can use atomic copies. */ static void iov_fault_in_pages_read(struct iovec *iov, unsigned long len) { while (!iov->iov_len) iov++; while (len > 0) { unsigned long this_len; this_len = min_t(unsigned long, len, iov->iov_len); fault_in_pages_readable(iov->iov_base, this_len); len -= this_len; iov++; } } |
341b446bc [PATCH] another r... |
199 200 |
static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf) |
1da177e4c Linux-2.6.12-rc2 |
201 202 |
{ struct page *page = buf->page; |
5274f052e [PATCH] Introduce... |
203 204 205 |
/* * If nobody else uses this page, and we don't already have a * temporary page, let's keep track of it as a one-deep |
341b446bc [PATCH] another r... |
206 |
* allocation cache. (Otherwise just release our reference to it) |
5274f052e [PATCH] Introduce... |
207 |
*/ |
341b446bc [PATCH] another r... |
208 |
if (page_count(page) == 1 && !pipe->tmp_page) |
923f4f239 [PATCH] pipe.c/fi... |
209 |
pipe->tmp_page = page; |
341b446bc [PATCH] another r... |
210 211 |
else page_cache_release(page); |
1da177e4c Linux-2.6.12-rc2 |
212 |
} |
0845718da pipe: add documen... |
213 214 215 216 217 218 219 220 |
/** * generic_pipe_buf_map - virtually map a pipe buffer * @pipe: the pipe that the buffer belongs to * @buf: the buffer that should be mapped * @atomic: whether to use an atomic map * * Description: * This function returns a kernel virtual address mapping for the |
b51d63c6d kernel-doc: fix f... |
221 |
* pipe_buffer passed in @buf. If @atomic is set, an atomic map is provided |
0845718da pipe: add documen... |
222 223 224 |
* and the caller has to be careful not to fault before calling * the unmap function. * |
2164d3344 pipe: remove KM_U... |
225 |
* Note that this function calls kmap_atomic() if @atomic != 0. |
0845718da pipe: add documen... |
226 |
*/ |
f84d75199 [PATCH] pipe: int... |
227 |
void *generic_pipe_buf_map(struct pipe_inode_info *pipe, |
f6762b7ad [PATCH] pipe: ena... |
228 |
struct pipe_buffer *buf, int atomic) |
1da177e4c Linux-2.6.12-rc2 |
229 |
{ |
f6762b7ad [PATCH] pipe: ena... |
230 231 |
if (atomic) { buf->flags |= PIPE_BUF_FLAG_ATOMIC; |
e8e3c3d66 fs: remove the se... |
232 |
return kmap_atomic(buf->page); |
f6762b7ad [PATCH] pipe: ena... |
233 |
} |
1da177e4c Linux-2.6.12-rc2 |
234 235 |
return kmap(buf->page); } |
51921cb74 mm: export generi... |
236 |
EXPORT_SYMBOL(generic_pipe_buf_map); |
1da177e4c Linux-2.6.12-rc2 |
237 |
|
0845718da pipe: add documen... |
238 239 240 241 242 243 244 245 246 |
/** * generic_pipe_buf_unmap - unmap a previously mapped pipe buffer * @pipe: the pipe that the buffer belongs to * @buf: the buffer that should be unmapped * @map_data: the data that the mapping function returned * * Description: * This function undoes the mapping that ->map() provided. */ |
f84d75199 [PATCH] pipe: int... |
247 |
void generic_pipe_buf_unmap(struct pipe_inode_info *pipe, |
f6762b7ad [PATCH] pipe: ena... |
248 |
struct pipe_buffer *buf, void *map_data) |
1da177e4c Linux-2.6.12-rc2 |
249 |
{ |
f6762b7ad [PATCH] pipe: ena... |
250 251 |
if (buf->flags & PIPE_BUF_FLAG_ATOMIC) { buf->flags &= ~PIPE_BUF_FLAG_ATOMIC; |
e8e3c3d66 fs: remove the se... |
252 |
kunmap_atomic(map_data); |
f6762b7ad [PATCH] pipe: ena... |
253 254 |
} else kunmap(buf->page); |
1da177e4c Linux-2.6.12-rc2 |
255 |
} |
51921cb74 mm: export generi... |
256 |
EXPORT_SYMBOL(generic_pipe_buf_unmap); |
1da177e4c Linux-2.6.12-rc2 |
257 |
|
0845718da pipe: add documen... |
258 |
/** |
b51d63c6d kernel-doc: fix f... |
259 |
* generic_pipe_buf_steal - attempt to take ownership of a &pipe_buffer |
0845718da pipe: add documen... |
260 261 262 263 |
* @pipe: the pipe that the buffer belongs to * @buf: the buffer to attempt to steal * * Description: |
b51d63c6d kernel-doc: fix f... |
264 |
* This function attempts to steal the &struct page attached to |
0845718da pipe: add documen... |
265 266 |
* @buf. If successful, this function returns 0 and returns with * the page locked. The caller may then reuse the page for whatever |
b51d63c6d kernel-doc: fix f... |
267 |
* he wishes; the typical use is insertion into a different file |
0845718da pipe: add documen... |
268 269 |
* page cache. */ |
330ab7161 [PATCH] vmsplice:... |
270 271 |
int generic_pipe_buf_steal(struct pipe_inode_info *pipe, struct pipe_buffer *buf) |
5abc97aa2 [PATCH] splice: a... |
272 |
{ |
46e678c96 [PATCH] splice: f... |
273 |
struct page *page = buf->page; |
0845718da pipe: add documen... |
274 275 276 277 278 |
/* * A reference of one is golden, that means that the owner of this * page is the only one holding a reference to it. lock the page * and return OK. */ |
46e678c96 [PATCH] splice: f... |
279 |
if (page_count(page) == 1) { |
46e678c96 [PATCH] splice: f... |
280 281 282 283 284 |
lock_page(page); return 0; } return 1; |
5abc97aa2 [PATCH] splice: a... |
285 |
} |
51921cb74 mm: export generi... |
286 |
EXPORT_SYMBOL(generic_pipe_buf_steal); |
5abc97aa2 [PATCH] splice: a... |
287 |
|
0845718da pipe: add documen... |
288 |
/** |
b51d63c6d kernel-doc: fix f... |
289 |
* generic_pipe_buf_get - get a reference to a &struct pipe_buffer |
0845718da pipe: add documen... |
290 291 292 293 294 295 296 297 298 |
* @pipe: the pipe that the buffer belongs to * @buf: the buffer to get a reference to * * Description: * This function grabs an extra reference to @buf. It's used in * in the tee() system call, when we duplicate the buffers in one * pipe into another. */ void generic_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf) |
70524490e [PATCH] splice: a... |
299 300 301 |
{ page_cache_get(buf->page); } |
51921cb74 mm: export generi... |
302 |
EXPORT_SYMBOL(generic_pipe_buf_get); |
70524490e [PATCH] splice: a... |
303 |
|
0845718da pipe: add documen... |
304 305 |
/** * generic_pipe_buf_confirm - verify contents of the pipe buffer |
79685b8de docbook: add pipe... |
306 |
* @info: the pipe that the buffer belongs to |
0845718da pipe: add documen... |
307 308 309 310 311 312 |
* @buf: the buffer to confirm * * Description: * This function does nothing, because the generic pipe code uses * pages that are always good when inserted into the pipe. */ |
cac36bb06 pipe: change the ... |
313 314 |
int generic_pipe_buf_confirm(struct pipe_inode_info *info, struct pipe_buffer *buf) |
f84d75199 [PATCH] pipe: int... |
315 316 317 |
{ return 0; } |
51921cb74 mm: export generi... |
318 |
EXPORT_SYMBOL(generic_pipe_buf_confirm); |
f84d75199 [PATCH] pipe: int... |
319 |
|
6818173bd splice: implement... |
320 321 322 323 324 325 326 327 328 329 330 331 332 |
/** * generic_pipe_buf_release - put a reference to a &struct pipe_buffer * @pipe: the pipe that the buffer belongs to * @buf: the buffer to put a reference to * * Description: * This function releases a reference to @buf. */ void generic_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { page_cache_release(buf->page); } |
51921cb74 mm: export generi... |
333 |
EXPORT_SYMBOL(generic_pipe_buf_release); |
6818173bd splice: implement... |
334 |
|
d4c3cca94 [PATCH] constify ... |
335 |
static const struct pipe_buf_operations anon_pipe_buf_ops = { |
1da177e4c Linux-2.6.12-rc2 |
336 |
.can_merge = 1, |
f84d75199 [PATCH] pipe: int... |
337 338 |
.map = generic_pipe_buf_map, .unmap = generic_pipe_buf_unmap, |
cac36bb06 pipe: change the ... |
339 |
.confirm = generic_pipe_buf_confirm, |
1da177e4c Linux-2.6.12-rc2 |
340 |
.release = anon_pipe_buf_release, |
330ab7161 [PATCH] vmsplice:... |
341 |
.steal = generic_pipe_buf_steal, |
f84d75199 [PATCH] pipe: int... |
342 |
.get = generic_pipe_buf_get, |
1da177e4c Linux-2.6.12-rc2 |
343 |
}; |
9883035ae pipes: add a "pac... |
344 345 346 347 348 349 350 351 352 |
static const struct pipe_buf_operations packet_pipe_buf_ops = { .can_merge = 0, .map = generic_pipe_buf_map, .unmap = generic_pipe_buf_unmap, .confirm = generic_pipe_buf_confirm, .release = anon_pipe_buf_release, .steal = generic_pipe_buf_steal, .get = generic_pipe_buf_get, }; |
1da177e4c Linux-2.6.12-rc2 |
353 |
static ssize_t |
ee0b3e671 [PATCH] Remove re... |
354 355 |
pipe_read(struct kiocb *iocb, const struct iovec *_iov, unsigned long nr_segs, loff_t pos) |
1da177e4c Linux-2.6.12-rc2 |
356 |
{ |
ee0b3e671 [PATCH] Remove re... |
357 |
struct file *filp = iocb->ki_filp; |
de32ec4cf pipe: set file->p... |
358 |
struct pipe_inode_info *pipe = filp->private_data; |
1da177e4c Linux-2.6.12-rc2 |
359 360 361 362 363 364 365 366 367 368 369 370 |
int do_wakeup; ssize_t ret; struct iovec *iov = (struct iovec *)_iov; size_t total_len; total_len = iov_length(iov, nr_segs); /* Null read succeeds. */ if (unlikely(total_len == 0)) return 0; do_wakeup = 0; ret = 0; |
ebec73f47 introduce variant... |
371 |
__pipe_lock(pipe); |
1da177e4c Linux-2.6.12-rc2 |
372 |
for (;;) { |
923f4f239 [PATCH] pipe.c/fi... |
373 |
int bufs = pipe->nrbufs; |
1da177e4c Linux-2.6.12-rc2 |
374 |
if (bufs) { |
923f4f239 [PATCH] pipe.c/fi... |
375 376 |
int curbuf = pipe->curbuf; struct pipe_buffer *buf = pipe->bufs + curbuf; |
d4c3cca94 [PATCH] constify ... |
377 |
const struct pipe_buf_operations *ops = buf->ops; |
1da177e4c Linux-2.6.12-rc2 |
378 379 |
void *addr; size_t chars = buf->len; |
f6762b7ad [PATCH] pipe: ena... |
380 |
int error, atomic; |
1da177e4c Linux-2.6.12-rc2 |
381 382 383 |
if (chars > total_len) chars = total_len; |
cac36bb06 pipe: change the ... |
384 |
error = ops->confirm(pipe, buf); |
f84d75199 [PATCH] pipe: int... |
385 |
if (error) { |
5274f052e [PATCH] Introduce... |
386 |
if (!ret) |
e5953cbdf pipe: fix failure... |
387 |
ret = error; |
5274f052e [PATCH] Introduce... |
388 389 |
break; } |
f84d75199 [PATCH] pipe: int... |
390 |
|
f6762b7ad [PATCH] pipe: ena... |
391 392 393 394 395 |
atomic = !iov_fault_in_pages_write(iov, chars); redo: addr = ops->map(pipe, buf, atomic); error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars, atomic); ops->unmap(pipe, buf, addr); |
1da177e4c Linux-2.6.12-rc2 |
396 |
if (unlikely(error)) { |
f6762b7ad [PATCH] pipe: ena... |
397 398 399 400 401 402 403 |
/* * Just retry with the slow path if we failed. */ if (atomic) { atomic = 0; goto redo; } |
341b446bc [PATCH] another r... |
404 |
if (!ret) |
f6762b7ad [PATCH] pipe: ena... |
405 |
ret = error; |
1da177e4c Linux-2.6.12-rc2 |
406 407 408 409 410 |
break; } ret += chars; buf->offset += chars; buf->len -= chars; |
9883035ae pipes: add a "pac... |
411 412 413 414 415 416 |
/* Was it a packet buffer? Clean up and exit */ if (buf->flags & PIPE_BUF_FLAG_PACKET) { total_len = chars; buf->len = 0; } |
1da177e4c Linux-2.6.12-rc2 |
417 418 |
if (!buf->len) { buf->ops = NULL; |
923f4f239 [PATCH] pipe.c/fi... |
419 |
ops->release(pipe, buf); |
35f3d14db pipe: add support... |
420 |
curbuf = (curbuf + 1) & (pipe->buffers - 1); |
923f4f239 [PATCH] pipe.c/fi... |
421 422 |
pipe->curbuf = curbuf; pipe->nrbufs = --bufs; |
1da177e4c Linux-2.6.12-rc2 |
423 424 425 426 427 428 429 430 |
do_wakeup = 1; } total_len -= chars; if (!total_len) break; /* common path: read succeeded */ } if (bufs) /* More to do? */ continue; |
923f4f239 [PATCH] pipe.c/fi... |
431 |
if (!pipe->writers) |
1da177e4c Linux-2.6.12-rc2 |
432 |
break; |
923f4f239 [PATCH] pipe.c/fi... |
433 |
if (!pipe->waiting_writers) { |
1da177e4c Linux-2.6.12-rc2 |
434 435 436 437 438 439 440 441 442 443 444 445 446 |
/* syscall merging: Usually we must not sleep * if O_NONBLOCK is set, or if we got some data. * But if a writer sleeps in kernel space, then * we can wait for that data without violating POSIX. */ if (ret) break; if (filp->f_flags & O_NONBLOCK) { ret = -EAGAIN; break; } } if (signal_pending(current)) { |
341b446bc [PATCH] another r... |
447 448 |
if (!ret) ret = -ERESTARTSYS; |
1da177e4c Linux-2.6.12-rc2 |
449 450 451 |
break; } if (do_wakeup) { |
28e58ee8c Fix broken "pipe:... |
452 |
wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM); |
923f4f239 [PATCH] pipe.c/fi... |
453 |
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
1da177e4c Linux-2.6.12-rc2 |
454 |
} |
923f4f239 [PATCH] pipe.c/fi... |
455 |
pipe_wait(pipe); |
1da177e4c Linux-2.6.12-rc2 |
456 |
} |
ebec73f47 introduce variant... |
457 |
__pipe_unlock(pipe); |
341b446bc [PATCH] another r... |
458 459 |
/* Signal writers asynchronously that there is more room. */ |
1da177e4c Linux-2.6.12-rc2 |
460 |
if (do_wakeup) { |
28e58ee8c Fix broken "pipe:... |
461 |
wake_up_interruptible_sync_poll(&pipe->wait, POLLOUT | POLLWRNORM); |
923f4f239 [PATCH] pipe.c/fi... |
462 |
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
1da177e4c Linux-2.6.12-rc2 |
463 464 465 466 467 |
} if (ret > 0) file_accessed(filp); return ret; } |
9883035ae pipes: add a "pac... |
468 469 470 471 |
static inline int is_packetized(struct file *file) { return (file->f_flags & O_DIRECT) != 0; } |
1da177e4c Linux-2.6.12-rc2 |
472 |
static ssize_t |
ee0b3e671 [PATCH] Remove re... |
473 474 |
pipe_write(struct kiocb *iocb, const struct iovec *_iov, unsigned long nr_segs, loff_t ppos) |
1da177e4c Linux-2.6.12-rc2 |
475 |
{ |
ee0b3e671 [PATCH] Remove re... |
476 |
struct file *filp = iocb->ki_filp; |
de32ec4cf pipe: set file->p... |
477 |
struct pipe_inode_info *pipe = filp->private_data; |
1da177e4c Linux-2.6.12-rc2 |
478 479 480 481 482 483 484 485 486 487 488 489 490 |
ssize_t ret; int do_wakeup; struct iovec *iov = (struct iovec *)_iov; size_t total_len; ssize_t chars; total_len = iov_length(iov, nr_segs); /* Null write succeeds. */ if (unlikely(total_len == 0)) return 0; do_wakeup = 0; ret = 0; |
ebec73f47 introduce variant... |
491 |
__pipe_lock(pipe); |
1da177e4c Linux-2.6.12-rc2 |
492 |
|
923f4f239 [PATCH] pipe.c/fi... |
493 |
if (!pipe->readers) { |
1da177e4c Linux-2.6.12-rc2 |
494 495 496 497 498 499 500 |
send_sig(SIGPIPE, current, 0); ret = -EPIPE; goto out; } /* We try to merge small writes */ chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */ |
923f4f239 [PATCH] pipe.c/fi... |
501 |
if (pipe->nrbufs && chars != 0) { |
341b446bc [PATCH] another r... |
502 |
int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & |
35f3d14db pipe: add support... |
503 |
(pipe->buffers - 1); |
923f4f239 [PATCH] pipe.c/fi... |
504 |
struct pipe_buffer *buf = pipe->bufs + lastbuf; |
d4c3cca94 [PATCH] constify ... |
505 |
const struct pipe_buf_operations *ops = buf->ops; |
1da177e4c Linux-2.6.12-rc2 |
506 |
int offset = buf->offset + buf->len; |
341b446bc [PATCH] another r... |
507 |
|
1da177e4c Linux-2.6.12-rc2 |
508 |
if (ops->can_merge && offset + chars <= PAGE_SIZE) { |
f6762b7ad [PATCH] pipe: ena... |
509 |
int error, atomic = 1; |
5274f052e [PATCH] Introduce... |
510 |
void *addr; |
5274f052e [PATCH] Introduce... |
511 |
|
cac36bb06 pipe: change the ... |
512 |
error = ops->confirm(pipe, buf); |
f84d75199 [PATCH] pipe: int... |
513 |
if (error) |
5274f052e [PATCH] Introduce... |
514 |
goto out; |
f84d75199 [PATCH] pipe: int... |
515 |
|
f6762b7ad [PATCH] pipe: ena... |
516 517 518 |
iov_fault_in_pages_read(iov, chars); redo1: addr = ops->map(pipe, buf, atomic); |
5274f052e [PATCH] Introduce... |
519 |
error = pipe_iov_copy_from_user(offset + addr, iov, |
f6762b7ad [PATCH] pipe: ena... |
520 521 |
chars, atomic); ops->unmap(pipe, buf, addr); |
1da177e4c Linux-2.6.12-rc2 |
522 523 |
ret = error; do_wakeup = 1; |
f6762b7ad [PATCH] pipe: ena... |
524 525 526 527 528 |
if (error) { if (atomic) { atomic = 0; goto redo1; } |
1da177e4c Linux-2.6.12-rc2 |
529 |
goto out; |
f6762b7ad [PATCH] pipe: ena... |
530 |
} |
1da177e4c Linux-2.6.12-rc2 |
531 532 533 534 535 536 537 538 539 540 |
buf->len += chars; total_len -= chars; ret = chars; if (!total_len) goto out; } } for (;;) { int bufs; |
341b446bc [PATCH] another r... |
541 |
|
923f4f239 [PATCH] pipe.c/fi... |
542 |
if (!pipe->readers) { |
1da177e4c Linux-2.6.12-rc2 |
543 |
send_sig(SIGPIPE, current, 0); |
341b446bc [PATCH] another r... |
544 545 |
if (!ret) ret = -EPIPE; |
1da177e4c Linux-2.6.12-rc2 |
546 547 |
break; } |
923f4f239 [PATCH] pipe.c/fi... |
548 |
bufs = pipe->nrbufs; |
35f3d14db pipe: add support... |
549 550 |
if (bufs < pipe->buffers) { int newbuf = (pipe->curbuf + bufs) & (pipe->buffers-1); |
923f4f239 [PATCH] pipe.c/fi... |
551 552 |
struct pipe_buffer *buf = pipe->bufs + newbuf; struct page *page = pipe->tmp_page; |
f6762b7ad [PATCH] pipe: ena... |
553 554 |
char *src; int error, atomic = 1; |
1da177e4c Linux-2.6.12-rc2 |
555 556 557 558 559 560 561 |
if (!page) { page = alloc_page(GFP_HIGHUSER); if (unlikely(!page)) { ret = ret ? : -ENOMEM; break; } |
923f4f239 [PATCH] pipe.c/fi... |
562 |
pipe->tmp_page = page; |
1da177e4c Linux-2.6.12-rc2 |
563 |
} |
341b446bc [PATCH] another r... |
564 |
/* Always wake up, even if the copy fails. Otherwise |
1da177e4c Linux-2.6.12-rc2 |
565 566 567 568 569 570 571 572 |
* we lock up (O_NONBLOCK-)readers that sleep due to * syscall merging. * FIXME! Is this really true? */ do_wakeup = 1; chars = PAGE_SIZE; if (chars > total_len) chars = total_len; |
f6762b7ad [PATCH] pipe: ena... |
573 574 575 |
iov_fault_in_pages_read(iov, chars); redo2: if (atomic) |
e8e3c3d66 fs: remove the se... |
576 |
src = kmap_atomic(page); |
f6762b7ad [PATCH] pipe: ena... |
577 578 579 580 581 582 |
else src = kmap(page); error = pipe_iov_copy_from_user(src, iov, chars, atomic); if (atomic) |
e8e3c3d66 fs: remove the se... |
583 |
kunmap_atomic(src); |
f6762b7ad [PATCH] pipe: ena... |
584 585 |
else kunmap(page); |
1da177e4c Linux-2.6.12-rc2 |
586 |
if (unlikely(error)) { |
f6762b7ad [PATCH] pipe: ena... |
587 588 589 590 |
if (atomic) { atomic = 0; goto redo2; } |
341b446bc [PATCH] another r... |
591 |
if (!ret) |
f6762b7ad [PATCH] pipe: ena... |
592 |
ret = error; |
1da177e4c Linux-2.6.12-rc2 |
593 594 595 596 597 598 599 600 601 |
break; } ret += chars; /* Insert it into the buffer array */ buf->page = page; buf->ops = &anon_pipe_buf_ops; buf->offset = 0; buf->len = chars; |
9883035ae pipes: add a "pac... |
602 603 604 605 606 |
buf->flags = 0; if (is_packetized(filp)) { buf->ops = &packet_pipe_buf_ops; buf->flags = PIPE_BUF_FLAG_PACKET; } |
923f4f239 [PATCH] pipe.c/fi... |
607 608 |
pipe->nrbufs = ++bufs; pipe->tmp_page = NULL; |
1da177e4c Linux-2.6.12-rc2 |
609 610 611 612 613 |
total_len -= chars; if (!total_len) break; } |
35f3d14db pipe: add support... |
614 |
if (bufs < pipe->buffers) |
1da177e4c Linux-2.6.12-rc2 |
615 616 |
continue; if (filp->f_flags & O_NONBLOCK) { |
341b446bc [PATCH] another r... |
617 618 |
if (!ret) ret = -EAGAIN; |
1da177e4c Linux-2.6.12-rc2 |
619 620 621 |
break; } if (signal_pending(current)) { |
341b446bc [PATCH] another r... |
622 623 |
if (!ret) ret = -ERESTARTSYS; |
1da177e4c Linux-2.6.12-rc2 |
624 625 626 |
break; } if (do_wakeup) { |
28e58ee8c Fix broken "pipe:... |
627 |
wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM); |
923f4f239 [PATCH] pipe.c/fi... |
628 |
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
1da177e4c Linux-2.6.12-rc2 |
629 630 |
do_wakeup = 0; } |
923f4f239 [PATCH] pipe.c/fi... |
631 632 633 |
pipe->waiting_writers++; pipe_wait(pipe); pipe->waiting_writers--; |
1da177e4c Linux-2.6.12-rc2 |
634 635 |
} out: |
ebec73f47 introduce variant... |
636 |
__pipe_unlock(pipe); |
1da177e4c Linux-2.6.12-rc2 |
637 |
if (do_wakeup) { |
28e58ee8c Fix broken "pipe:... |
638 |
wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM); |
923f4f239 [PATCH] pipe.c/fi... |
639 |
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
1da177e4c Linux-2.6.12-rc2 |
640 |
} |
c3b2da314 fs: introduce ino... |
641 642 643 644 645 |
if (ret > 0) { int err = file_update_time(filp); if (err) ret = err; } |
1da177e4c Linux-2.6.12-rc2 |
646 647 |
return ret; } |
d59d0b1b8 BKL-Removal: conv... |
648 |
static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
1da177e4c Linux-2.6.12-rc2 |
649 |
{ |
de32ec4cf pipe: set file->p... |
650 |
struct pipe_inode_info *pipe = filp->private_data; |
1da177e4c Linux-2.6.12-rc2 |
651 652 653 654 |
int count, buf, nrbufs; switch (cmd) { case FIONREAD: |
ebec73f47 introduce variant... |
655 |
__pipe_lock(pipe); |
1da177e4c Linux-2.6.12-rc2 |
656 |
count = 0; |
923f4f239 [PATCH] pipe.c/fi... |
657 658 |
buf = pipe->curbuf; nrbufs = pipe->nrbufs; |
1da177e4c Linux-2.6.12-rc2 |
659 |
while (--nrbufs >= 0) { |
923f4f239 [PATCH] pipe.c/fi... |
660 |
count += pipe->bufs[buf].len; |
35f3d14db pipe: add support... |
661 |
buf = (buf+1) & (pipe->buffers - 1); |
1da177e4c Linux-2.6.12-rc2 |
662 |
} |
ebec73f47 introduce variant... |
663 |
__pipe_unlock(pipe); |
923f4f239 [PATCH] pipe.c/fi... |
664 |
|
1da177e4c Linux-2.6.12-rc2 |
665 666 |
return put_user(count, (int __user *)arg); default: |
46ce341b2 pipe: return -ENO... |
667 |
return -ENOIOCTLCMD; |
1da177e4c Linux-2.6.12-rc2 |
668 669 670 671 672 673 674 675 |
} } /* No kernel lock held - fine */ static unsigned int pipe_poll(struct file *filp, poll_table *wait) { unsigned int mask; |
de32ec4cf pipe: set file->p... |
676 |
struct pipe_inode_info *pipe = filp->private_data; |
1da177e4c Linux-2.6.12-rc2 |
677 |
int nrbufs; |
923f4f239 [PATCH] pipe.c/fi... |
678 |
poll_wait(filp, &pipe->wait, wait); |
1da177e4c Linux-2.6.12-rc2 |
679 680 |
/* Reading only -- no need for acquiring the semaphore. */ |
923f4f239 [PATCH] pipe.c/fi... |
681 |
nrbufs = pipe->nrbufs; |
1da177e4c Linux-2.6.12-rc2 |
682 683 684 |
mask = 0; if (filp->f_mode & FMODE_READ) { mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0; |
923f4f239 [PATCH] pipe.c/fi... |
685 |
if (!pipe->writers && filp->f_version != pipe->w_counter) |
1da177e4c Linux-2.6.12-rc2 |
686 687 688 689 |
mask |= POLLHUP; } if (filp->f_mode & FMODE_WRITE) { |
35f3d14db pipe: add support... |
690 |
mask |= (nrbufs < pipe->buffers) ? POLLOUT | POLLWRNORM : 0; |
5e5d7a222 [PATCH] pipe: rem... |
691 692 693 694 |
/* * Most Unices do not set POLLERR for FIFOs but on Linux they * behave exactly like pipes for poll(). */ |
923f4f239 [PATCH] pipe.c/fi... |
695 |
if (!pipe->readers) |
1da177e4c Linux-2.6.12-rc2 |
696 697 698 699 700 |
mask |= POLLERR; } return mask; } |
b0d8d2292 vfs: fix subtle u... |
701 702 703 704 705 706 707 708 709 710 711 712 713 714 |
static void put_pipe_info(struct inode *inode, struct pipe_inode_info *pipe) { int kill = 0; spin_lock(&inode->i_lock); if (!--pipe->files) { inode->i_pipe = NULL; kill = 1; } spin_unlock(&inode->i_lock); if (kill) free_pipe_info(pipe); } |
1da177e4c Linux-2.6.12-rc2 |
715 |
static int |
599a0ac14 pipe: fold file_o... |
716 |
pipe_release(struct inode *inode, struct file *file) |
1da177e4c Linux-2.6.12-rc2 |
717 |
{ |
b0d8d2292 vfs: fix subtle u... |
718 |
struct pipe_inode_info *pipe = file->private_data; |
923f4f239 [PATCH] pipe.c/fi... |
719 |
|
ebec73f47 introduce variant... |
720 |
__pipe_lock(pipe); |
599a0ac14 pipe: fold file_o... |
721 722 723 724 |
if (file->f_mode & FMODE_READ) pipe->readers--; if (file->f_mode & FMODE_WRITE) pipe->writers--; |
341b446bc [PATCH] another r... |
725 |
|
ba5bb1473 pipe: take alloca... |
726 |
if (pipe->readers || pipe->writers) { |
28e58ee8c Fix broken "pipe:... |
727 |
wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM | POLLERR | POLLHUP); |
923f4f239 [PATCH] pipe.c/fi... |
728 729 |
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
1da177e4c Linux-2.6.12-rc2 |
730 |
} |
ebec73f47 introduce variant... |
731 |
__pipe_unlock(pipe); |
ba5bb1473 pipe: take alloca... |
732 |
|
b0d8d2292 vfs: fix subtle u... |
733 |
put_pipe_info(inode, pipe); |
1da177e4c Linux-2.6.12-rc2 |
734 735 736 737 |
return 0; } static int |
599a0ac14 pipe: fold file_o... |
738 |
pipe_fasync(int fd, struct file *filp, int on) |
1da177e4c Linux-2.6.12-rc2 |
739 |
{ |
de32ec4cf pipe: set file->p... |
740 |
struct pipe_inode_info *pipe = filp->private_data; |
599a0ac14 pipe: fold file_o... |
741 |
int retval = 0; |
1da177e4c Linux-2.6.12-rc2 |
742 |
|
ebec73f47 introduce variant... |
743 |
__pipe_lock(pipe); |
599a0ac14 pipe: fold file_o... |
744 745 746 |
if (filp->f_mode & FMODE_READ) retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); if ((filp->f_mode & FMODE_WRITE) && retval >= 0) { |
341b446bc [PATCH] another r... |
747 |
retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); |
599a0ac14 pipe: fold file_o... |
748 749 |
if (retval < 0 && (filp->f_mode & FMODE_READ)) /* this can happen only if on == T */ |
e5bc49ba7 pipe_rdwr_fasync:... |
750 751 |
fasync_helper(-1, filp, 0, &pipe->fasync_readers); } |
ebec73f47 introduce variant... |
752 |
__pipe_unlock(pipe); |
60aa49243 Rationalize fasyn... |
753 |
return retval; |
1da177e4c Linux-2.6.12-rc2 |
754 |
} |
7bee130e2 get rid of alloc_... |
755 |
struct pipe_inode_info *alloc_pipe_info(void) |
3a326a2ce [PATCH] introduce... |
756 |
{ |
923f4f239 [PATCH] pipe.c/fi... |
757 |
struct pipe_inode_info *pipe; |
3a326a2ce [PATCH] introduce... |
758 |
|
923f4f239 [PATCH] pipe.c/fi... |
759 760 |
pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL); if (pipe) { |
35f3d14db pipe: add support... |
761 762 763 764 |
pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * PIPE_DEF_BUFFERS, GFP_KERNEL); if (pipe->bufs) { init_waitqueue_head(&pipe->wait); pipe->r_counter = pipe->w_counter = 1; |
35f3d14db pipe: add support... |
765 |
pipe->buffers = PIPE_DEF_BUFFERS; |
72b0d9aac pipe: don't use -... |
766 |
mutex_init(&pipe->mutex); |
35f3d14db pipe: add support... |
767 768 769 |
return pipe; } kfree(pipe); |
3a326a2ce [PATCH] introduce... |
770 |
} |
35f3d14db pipe: add support... |
771 |
return NULL; |
3a326a2ce [PATCH] introduce... |
772 |
} |
4b8a8f1e4 get rid of the la... |
773 |
void free_pipe_info(struct pipe_inode_info *pipe) |
1da177e4c Linux-2.6.12-rc2 |
774 775 |
{ int i; |
1da177e4c Linux-2.6.12-rc2 |
776 |
|
35f3d14db pipe: add support... |
777 |
for (i = 0; i < pipe->buffers; i++) { |
923f4f239 [PATCH] pipe.c/fi... |
778 |
struct pipe_buffer *buf = pipe->bufs + i; |
1da177e4c Linux-2.6.12-rc2 |
779 |
if (buf->ops) |
923f4f239 [PATCH] pipe.c/fi... |
780 |
buf->ops->release(pipe, buf); |
1da177e4c Linux-2.6.12-rc2 |
781 |
} |
923f4f239 [PATCH] pipe.c/fi... |
782 783 |
if (pipe->tmp_page) __free_page(pipe->tmp_page); |
35f3d14db pipe: add support... |
784 |
kfree(pipe->bufs); |
923f4f239 [PATCH] pipe.c/fi... |
785 |
kfree(pipe); |
1da177e4c Linux-2.6.12-rc2 |
786 |
} |
fa3536cc1 [PATCH] Use __rea... |
787 |
static struct vfsmount *pipe_mnt __read_mostly; |
341b446bc [PATCH] another r... |
788 |
|
c23fbb6bc VFS: delay the de... |
789 790 791 792 793 794 795 796 |
/* * pipefs_dname() is called from d_path(). */ static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen) { return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]", dentry->d_inode->i_ino); } |
3ba13d179 constify dentry_o... |
797 |
static const struct dentry_operations pipefs_dentry_operations = { |
c23fbb6bc VFS: delay the de... |
798 |
.d_dname = pipefs_dname, |
1da177e4c Linux-2.6.12-rc2 |
799 800 801 802 |
}; static struct inode * get_pipe_inode(void) { |
a209dfc7b vfs: dont chain p... |
803 |
struct inode *inode = new_inode_pseudo(pipe_mnt->mnt_sb); |
923f4f239 [PATCH] pipe.c/fi... |
804 |
struct pipe_inode_info *pipe; |
1da177e4c Linux-2.6.12-rc2 |
805 806 807 |
if (!inode) goto fail_inode; |
85fe4025c fs: do not assign... |
808 |
inode->i_ino = get_next_ino(); |
7bee130e2 get rid of alloc_... |
809 |
pipe = alloc_pipe_info(); |
923f4f239 [PATCH] pipe.c/fi... |
810 |
if (!pipe) |
1da177e4c Linux-2.6.12-rc2 |
811 |
goto fail_iput; |
3a326a2ce [PATCH] introduce... |
812 |
|
ba5bb1473 pipe: take alloca... |
813 814 |
inode->i_pipe = pipe; pipe->files = 2; |
923f4f239 [PATCH] pipe.c/fi... |
815 |
pipe->readers = pipe->writers = 1; |
599a0ac14 pipe: fold file_o... |
816 |
inode->i_fop = &pipefifo_fops; |
1da177e4c Linux-2.6.12-rc2 |
817 818 819 820 821 822 823 824 825 |
/* * Mark the inode dirty from the very beginning, * that way it will never be moved to the dirty * list because "mark_inode_dirty()" will think * that it already _is_ on the dirty list. */ inode->i_state = I_DIRTY; inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR; |
da9592ede CRED: Wrap task c... |
826 827 |
inode->i_uid = current_fsuid(); inode->i_gid = current_fsgid(); |
1da177e4c Linux-2.6.12-rc2 |
828 |
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
923f4f239 [PATCH] pipe.c/fi... |
829 |
|
1da177e4c Linux-2.6.12-rc2 |
830 831 832 833 |
return inode; fail_iput: iput(inode); |
341b446bc [PATCH] another r... |
834 |
|
1da177e4c Linux-2.6.12-rc2 |
835 836 837 |
fail_inode: return NULL; } |
e4fad8e5d consolidate pipe ... |
838 |
int create_pipe_files(struct file **res, int flags) |
1da177e4c Linux-2.6.12-rc2 |
839 |
{ |
d6cbd281d [PATCH] Some clea... |
840 |
int err; |
e4fad8e5d consolidate pipe ... |
841 |
struct inode *inode = get_pipe_inode(); |
d6cbd281d [PATCH] Some clea... |
842 |
struct file *f; |
2c48b9c45 switch alloc_file... |
843 |
struct path path; |
e4fad8e5d consolidate pipe ... |
844 |
static struct qstr name = { .name = "" }; |
1da177e4c Linux-2.6.12-rc2 |
845 |
|
1da177e4c Linux-2.6.12-rc2 |
846 |
if (!inode) |
e4fad8e5d consolidate pipe ... |
847 |
return -ENFILE; |
1da177e4c Linux-2.6.12-rc2 |
848 |
|
d6cbd281d [PATCH] Some clea... |
849 |
err = -ENOMEM; |
4b936885a fs: improve scala... |
850 |
path.dentry = d_alloc_pseudo(pipe_mnt->mnt_sb, &name); |
2c48b9c45 switch alloc_file... |
851 |
if (!path.dentry) |
d6cbd281d [PATCH] Some clea... |
852 |
goto err_inode; |
2c48b9c45 switch alloc_file... |
853 |
path.mnt = mntget(pipe_mnt); |
341b446bc [PATCH] another r... |
854 |
|
2c48b9c45 switch alloc_file... |
855 |
d_instantiate(path.dentry, inode); |
430e285e0 [PATCH] fix up ne... |
856 857 |
err = -ENFILE; |
599a0ac14 pipe: fold file_o... |
858 |
f = alloc_file(&path, FMODE_WRITE, &pipefifo_fops); |
39b652527 fs: Preserve erro... |
859 |
if (IS_ERR(f)) |
430e285e0 [PATCH] fix up ne... |
860 |
goto err_dentry; |
341b446bc [PATCH] another r... |
861 |
|
9883035ae pipes: add a "pac... |
862 |
f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)); |
de32ec4cf pipe: set file->p... |
863 |
f->private_data = inode->i_pipe; |
d6cbd281d [PATCH] Some clea... |
864 |
|
599a0ac14 pipe: fold file_o... |
865 |
res[0] = alloc_file(&path, FMODE_READ, &pipefifo_fops); |
39b652527 fs: Preserve erro... |
866 |
if (IS_ERR(res[0])) |
e4fad8e5d consolidate pipe ... |
867 868 869 |
goto err_file; path_get(&path); |
de32ec4cf pipe: set file->p... |
870 |
res[0]->private_data = inode->i_pipe; |
e4fad8e5d consolidate pipe ... |
871 872 873 |
res[0]->f_flags = O_RDONLY | (flags & O_NONBLOCK); res[1] = f; return 0; |
1da177e4c Linux-2.6.12-rc2 |
874 |
|
e4fad8e5d consolidate pipe ... |
875 876 877 |
err_file: put_filp(f); err_dentry: |
4b8a8f1e4 get rid of the la... |
878 |
free_pipe_info(inode->i_pipe); |
2c48b9c45 switch alloc_file... |
879 |
path_put(&path); |
e4fad8e5d consolidate pipe ... |
880 |
return err; |
ed1524371 [PATCH] double-fr... |
881 |
|
e4fad8e5d consolidate pipe ... |
882 |
err_inode: |
4b8a8f1e4 get rid of the la... |
883 |
free_pipe_info(inode->i_pipe); |
1da177e4c Linux-2.6.12-rc2 |
884 |
iput(inode); |
e4fad8e5d consolidate pipe ... |
885 |
return err; |
d6cbd281d [PATCH] Some clea... |
886 |
} |
5b249b1b0 pipe(2) - race-fr... |
887 |
static int __do_pipe_flags(int *fd, struct file **files, int flags) |
d6cbd281d [PATCH] Some clea... |
888 |
{ |
d6cbd281d [PATCH] Some clea... |
889 890 |
int error; int fdw, fdr; |
9883035ae pipes: add a "pac... |
891 |
if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT)) |
ed8cae8ba flag parameters: ... |
892 |
return -EINVAL; |
e4fad8e5d consolidate pipe ... |
893 894 895 |
error = create_pipe_files(files, flags); if (error) return error; |
d6cbd281d [PATCH] Some clea... |
896 |
|
ed8cae8ba flag parameters: ... |
897 |
error = get_unused_fd_flags(flags); |
d6cbd281d [PATCH] Some clea... |
898 899 900 |
if (error < 0) goto err_read_pipe; fdr = error; |
ed8cae8ba flag parameters: ... |
901 |
error = get_unused_fd_flags(flags); |
d6cbd281d [PATCH] Some clea... |
902 903 904 |
if (error < 0) goto err_fdr; fdw = error; |
157cf649a sanitize audit_fd... |
905 |
audit_fd_pair(fdr, fdw); |
d6cbd281d [PATCH] Some clea... |
906 907 |
fd[0] = fdr; fd[1] = fdw; |
d6cbd281d [PATCH] Some clea... |
908 909 910 911 912 |
return 0; err_fdr: put_unused_fd(fdr); err_read_pipe: |
e4fad8e5d consolidate pipe ... |
913 914 |
fput(files[0]); fput(files[1]); |
d6cbd281d [PATCH] Some clea... |
915 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
916 |
} |
5b249b1b0 pipe(2) - race-fr... |
917 918 919 920 921 922 923 924 925 926 |
int do_pipe_flags(int *fd, int flags) { struct file *files[2]; int error = __do_pipe_flags(fd, files, flags); if (!error) { fd_install(fd[0], files[0]); fd_install(fd[1], files[1]); } return error; } |
1da177e4c Linux-2.6.12-rc2 |
927 |
/* |
d35c7b0e5 unified (weak) sy... |
928 929 930 |
* sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way Unix traditionally does this, though. */ |
d4e82042c [CVE-2009-0029] S... |
931 |
SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags) |
d35c7b0e5 unified (weak) sy... |
932 |
{ |
5b249b1b0 pipe(2) - race-fr... |
933 |
struct file *files[2]; |
d35c7b0e5 unified (weak) sy... |
934 935 |
int fd[2]; int error; |
5b249b1b0 pipe(2) - race-fr... |
936 |
error = __do_pipe_flags(fd, files, flags); |
d35c7b0e5 unified (weak) sy... |
937 |
if (!error) { |
5b249b1b0 pipe(2) - race-fr... |
938 939 940 941 942 |
if (unlikely(copy_to_user(fildes, fd, sizeof(fd)))) { fput(files[0]); fput(files[1]); put_unused_fd(fd[0]); put_unused_fd(fd[1]); |
d35c7b0e5 unified (weak) sy... |
943 |
error = -EFAULT; |
5b249b1b0 pipe(2) - race-fr... |
944 945 946 |
} else { fd_install(fd[0], files[0]); fd_install(fd[1], files[1]); |
ba719baea sys_pipe(): fix f... |
947 |
} |
d35c7b0e5 unified (weak) sy... |
948 949 950 |
} return error; } |
2b6642199 [CVE-2009-0029] S... |
951 |
SYSCALL_DEFINE1(pipe, int __user *, fildes) |
ed8cae8ba flag parameters: ... |
952 953 954 |
{ return sys_pipe2(fildes, 0); } |
fc7478a2b pipe: switch wait... |
955 |
static int wait_for_partner(struct pipe_inode_info *pipe, unsigned int *cnt) |
f776c7388 fold fifo.c into ... |
956 957 958 959 |
{ int cur = *cnt; while (cur == *cnt) { |
fc7478a2b pipe: switch wait... |
960 |
pipe_wait(pipe); |
f776c7388 fold fifo.c into ... |
961 962 963 964 965 |
if (signal_pending(current)) break; } return cur == *cnt ? -ERESTARTSYS : 0; } |
fc7478a2b pipe: switch wait... |
966 |
static void wake_up_partner(struct pipe_inode_info *pipe) |
f776c7388 fold fifo.c into ... |
967 |
{ |
fc7478a2b pipe: switch wait... |
968 |
wake_up_interruptible(&pipe->wait); |
f776c7388 fold fifo.c into ... |
969 970 971 972 973 |
} static int fifo_open(struct inode *inode, struct file *filp) { struct pipe_inode_info *pipe; |
599a0ac14 pipe: fold file_o... |
974 |
bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC; |
f776c7388 fold fifo.c into ... |
975 |
int ret; |
ba5bb1473 pipe: take alloca... |
976 977 978 979 980 981 982 983 984 |
filp->f_version = 0; spin_lock(&inode->i_lock); if (inode->i_pipe) { pipe = inode->i_pipe; pipe->files++; spin_unlock(&inode->i_lock); } else { spin_unlock(&inode->i_lock); |
7bee130e2 get rid of alloc_... |
985 |
pipe = alloc_pipe_info(); |
f776c7388 fold fifo.c into ... |
986 |
if (!pipe) |
ba5bb1473 pipe: take alloca... |
987 988 989 990 991 992 |
return -ENOMEM; pipe->files = 1; spin_lock(&inode->i_lock); if (unlikely(inode->i_pipe)) { inode->i_pipe->files++; spin_unlock(&inode->i_lock); |
4b8a8f1e4 get rid of the la... |
993 |
free_pipe_info(pipe); |
ba5bb1473 pipe: take alloca... |
994 995 996 997 998 |
pipe = inode->i_pipe; } else { inode->i_pipe = pipe; spin_unlock(&inode->i_lock); } |
f776c7388 fold fifo.c into ... |
999 |
} |
de32ec4cf pipe: set file->p... |
1000 |
filp->private_data = pipe; |
ba5bb1473 pipe: take alloca... |
1001 |
/* OK, we have a pipe and it's pinned down */ |
ebec73f47 introduce variant... |
1002 |
__pipe_lock(pipe); |
f776c7388 fold fifo.c into ... |
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 |
/* We can only do regular read/write on fifos */ filp->f_mode &= (FMODE_READ | FMODE_WRITE); switch (filp->f_mode) { case FMODE_READ: /* * O_RDONLY * POSIX.1 says that O_NONBLOCK means return with the FIFO * opened, even when there is no process writing the FIFO. */ |
f776c7388 fold fifo.c into ... |
1014 1015 |
pipe->r_counter++; if (pipe->readers++ == 0) |
fc7478a2b pipe: switch wait... |
1016 |
wake_up_partner(pipe); |
f776c7388 fold fifo.c into ... |
1017 |
|
599a0ac14 pipe: fold file_o... |
1018 |
if (!is_pipe && !pipe->writers) { |
f776c7388 fold fifo.c into ... |
1019 1020 1021 1022 1023 |
if ((filp->f_flags & O_NONBLOCK)) { /* suppress POLLHUP until we have * seen a writer */ filp->f_version = pipe->w_counter; } else { |
fc7478a2b pipe: switch wait... |
1024 |
if (wait_for_partner(pipe, &pipe->w_counter)) |
f776c7388 fold fifo.c into ... |
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 |
goto err_rd; } } break; case FMODE_WRITE: /* * O_WRONLY * POSIX.1 says that O_NONBLOCK means return -1 with * errno=ENXIO when there is no process reading the FIFO. */ ret = -ENXIO; |
599a0ac14 pipe: fold file_o... |
1037 |
if (!is_pipe && (filp->f_flags & O_NONBLOCK) && !pipe->readers) |
f776c7388 fold fifo.c into ... |
1038 |
goto err; |
f776c7388 fold fifo.c into ... |
1039 1040 |
pipe->w_counter++; if (!pipe->writers++) |
fc7478a2b pipe: switch wait... |
1041 |
wake_up_partner(pipe); |
f776c7388 fold fifo.c into ... |
1042 |
|
599a0ac14 pipe: fold file_o... |
1043 |
if (!is_pipe && !pipe->readers) { |
fc7478a2b pipe: switch wait... |
1044 |
if (wait_for_partner(pipe, &pipe->r_counter)) |
f776c7388 fold fifo.c into ... |
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 |
goto err_wr; } break; case FMODE_READ | FMODE_WRITE: /* * O_RDWR * POSIX.1 leaves this case "undefined" when O_NONBLOCK is set. * This implementation will NEVER block on a O_RDWR open, since * the process can at least talk to itself. */ |
f776c7388 fold fifo.c into ... |
1056 1057 1058 1059 1060 1061 |
pipe->readers++; pipe->writers++; pipe->r_counter++; pipe->w_counter++; if (pipe->readers == 1 || pipe->writers == 1) |
fc7478a2b pipe: switch wait... |
1062 |
wake_up_partner(pipe); |
f776c7388 fold fifo.c into ... |
1063 1064 1065 1066 1067 1068 1069 1070 |
break; default: ret = -EINVAL; goto err; } /* Ok! */ |
ebec73f47 introduce variant... |
1071 |
__pipe_unlock(pipe); |
f776c7388 fold fifo.c into ... |
1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 |
return 0; err_rd: if (!--pipe->readers) wake_up_interruptible(&pipe->wait); ret = -ERESTARTSYS; goto err; err_wr: if (!--pipe->writers) wake_up_interruptible(&pipe->wait); ret = -ERESTARTSYS; goto err; err: |
ebec73f47 introduce variant... |
1087 |
__pipe_unlock(pipe); |
b0d8d2292 vfs: fix subtle u... |
1088 1089 |
put_pipe_info(inode, pipe); |
f776c7388 fold fifo.c into ... |
1090 1091 |
return ret; } |
599a0ac14 pipe: fold file_o... |
1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 |
const struct file_operations pipefifo_fops = { .open = fifo_open, .llseek = no_llseek, .read = do_sync_read, .aio_read = pipe_read, .write = do_sync_write, .aio_write = pipe_write, .poll = pipe_poll, .unlocked_ioctl = pipe_ioctl, .release = pipe_release, .fasync = pipe_fasync, |
f776c7388 fold fifo.c into ... |
1103 |
}; |
d35c7b0e5 unified (weak) sy... |
1104 |
/* |
35f3d14db pipe: add support... |
1105 1106 1107 |
* Allocate a new array of pipe buffers and copy the info over. Returns the * pipe size if successful, or return -ERROR on error. */ |
b9598db34 pipe: make F_{GET... |
1108 |
static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages) |
35f3d14db pipe: add support... |
1109 1110 1111 1112 |
{ struct pipe_buffer *bufs; /* |
35f3d14db pipe: add support... |
1113 1114 1115 1116 1117 |
* We can shrink the pipe, if arg >= pipe->nrbufs. Since we don't * expect a lot of shrink+grow operations, just free and allocate * again like we would do for growing. If the pipe currently * contains more buffers than arg, then return busy. */ |
b9598db34 pipe: make F_{GET... |
1118 |
if (nr_pages < pipe->nrbufs) |
35f3d14db pipe: add support... |
1119 |
return -EBUSY; |
2ccd4f4d4 pipe: fail cleanl... |
1120 |
bufs = kcalloc(nr_pages, sizeof(*bufs), GFP_KERNEL | __GFP_NOWARN); |
35f3d14db pipe: add support... |
1121 1122 1123 1124 1125 1126 1127 1128 |
if (unlikely(!bufs)) return -ENOMEM; /* * The pipe array wraps around, so just start the new one at zero * and adjust the indexes. */ if (pipe->nrbufs) { |
1d862f412 pipe: fix pipe bu... |
1129 1130 |
unsigned int tail; unsigned int head; |
35f3d14db pipe: add support... |
1131 |
|
1d862f412 pipe: fix pipe bu... |
1132 1133 1134 1135 1136 1137 1138 |
tail = pipe->curbuf + pipe->nrbufs; if (tail < pipe->buffers) tail = 0; else tail &= (pipe->buffers - 1); head = pipe->nrbufs - tail; |
35f3d14db pipe: add support... |
1139 1140 1141 |
if (head) memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer)); if (tail) |
1d862f412 pipe: fix pipe bu... |
1142 |
memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer)); |
35f3d14db pipe: add support... |
1143 1144 1145 1146 1147 |
} pipe->curbuf = 0; kfree(pipe->bufs); pipe->bufs = bufs; |
b9598db34 pipe: make F_{GET... |
1148 1149 |
pipe->buffers = nr_pages; return nr_pages * PAGE_SIZE; |
35f3d14db pipe: add support... |
1150 |
} |
ff9da691c pipe: change /pro... |
1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 |
/* * Currently we rely on the pipe array holding a power-of-2 number * of pages. */ static inline unsigned int round_pipe_size(unsigned int size) { unsigned long nr_pages; nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; return roundup_pow_of_two(nr_pages) << PAGE_SHIFT; } /* * This should work even if CONFIG_PROC_FS isn't set, as proc_dointvec_minmax * will return an error. */ int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf, size_t *lenp, loff_t *ppos) { int ret; ret = proc_dointvec_minmax(table, write, buf, lenp, ppos); if (ret < 0 || !write) return ret; pipe_max_size = round_pipe_size(pipe_max_size); return ret; } |
720836465 Un-inline get_pip... |
1179 1180 1181 1182 1183 1184 1185 |
/* * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same * location, so checking ->i_pipe is not enough to verify that this is a * pipe. */ struct pipe_inode_info *get_pipe_info(struct file *file) { |
de32ec4cf pipe: set file->p... |
1186 |
return file->f_op == &pipefifo_fops ? file->private_data : NULL; |
720836465 Un-inline get_pip... |
1187 |
} |
35f3d14db pipe: add support... |
1188 1189 1190 1191 |
long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) { struct pipe_inode_info *pipe; long ret; |
c66fb3479 Export 'get_pipe_... |
1192 |
pipe = get_pipe_info(file); |
35f3d14db pipe: add support... |
1193 1194 |
if (!pipe) return -EBADF; |
ebec73f47 introduce variant... |
1195 |
__pipe_lock(pipe); |
35f3d14db pipe: add support... |
1196 1197 |
switch (cmd) { |
b9598db34 pipe: make F_{GET... |
1198 |
case F_SETPIPE_SZ: { |
ff9da691c pipe: change /pro... |
1199 |
unsigned int size, nr_pages; |
b9598db34 pipe: make F_{GET... |
1200 |
|
ff9da691c pipe: change /pro... |
1201 1202 |
size = round_pipe_size(arg); nr_pages = size >> PAGE_SHIFT; |
b9598db34 pipe: make F_{GET... |
1203 |
|
6db40cf04 pipe: fix check i... |
1204 1205 1206 |
ret = -EINVAL; if (!nr_pages) goto out; |
ff9da691c pipe: change /pro... |
1207 |
if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) { |
b4ca76157 Merge branch 'mas... |
1208 |
ret = -EPERM; |
cc967be54 fs: Add missing m... |
1209 |
goto out; |
cc967be54 fs: Add missing m... |
1210 |
} |
ff9da691c pipe: change /pro... |
1211 |
ret = pipe_set_size(pipe, nr_pages); |
35f3d14db pipe: add support... |
1212 |
break; |
b9598db34 pipe: make F_{GET... |
1213 |
} |
35f3d14db pipe: add support... |
1214 |
case F_GETPIPE_SZ: |
b9598db34 pipe: make F_{GET... |
1215 |
ret = pipe->buffers * PAGE_SIZE; |
35f3d14db pipe: add support... |
1216 1217 1218 1219 1220 |
break; default: ret = -EINVAL; break; } |
cc967be54 fs: Add missing m... |
1221 |
out: |
ebec73f47 introduce variant... |
1222 |
__pipe_unlock(pipe); |
35f3d14db pipe: add support... |
1223 1224 |
return ret; } |
ff0c7d15f fs: avoid inode R... |
1225 1226 |
static const struct super_operations pipefs_ops = { .destroy_inode = free_inode_nonrcu, |
d70ef97ba fs/pipe.c: add ->... |
1227 |
.statfs = simple_statfs, |
ff0c7d15f fs: avoid inode R... |
1228 |
}; |
35f3d14db pipe: add support... |
1229 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1230 1231 1232 1233 1234 |
* pipefs should _never_ be mounted by userland - too much of security hassle, * no real gain from having the whole whorehouse mounted. So we don't need * any operations on the root directory. However, we need a non-trivial * d_name - pipe: will go nicely and kill the special-casing in procfs. */ |
51139adac convert get_sb_ps... |
1235 1236 |
static struct dentry *pipefs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) |
1da177e4c Linux-2.6.12-rc2 |
1237 |
{ |
c74a1cbb3 pass default dent... |
1238 1239 |
return mount_pseudo(fs_type, "pipe:", &pipefs_ops, &pipefs_dentry_operations, PIPEFS_MAGIC); |
1da177e4c Linux-2.6.12-rc2 |
1240 1241 1242 1243 |
} static struct file_system_type pipe_fs_type = { .name = "pipefs", |
51139adac convert get_sb_ps... |
1244 |
.mount = pipefs_mount, |
1da177e4c Linux-2.6.12-rc2 |
1245 1246 1247 1248 1249 1250 |
.kill_sb = kill_anon_super, }; static int __init init_pipe_fs(void) { int err = register_filesystem(&pipe_fs_type); |
341b446bc [PATCH] another r... |
1251 |
|
1da177e4c Linux-2.6.12-rc2 |
1252 1253 1254 1255 1256 1257 1258 1259 1260 |
if (!err) { pipe_mnt = kern_mount(&pipe_fs_type); if (IS_ERR(pipe_mnt)) { err = PTR_ERR(pipe_mnt); unregister_filesystem(&pipe_fs_type); } } return err; } |
1da177e4c Linux-2.6.12-rc2 |
1261 |
fs_initcall(init_pipe_fs); |