diff options
| author | Ingo Molnar <mingo@elte.hu> | 2006-04-11 07:57:45 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@suse.de> | 2006-04-11 07:57:45 -0400 |
| commit | 341b446bc5aa36d1d5b8159c1e66716b5d89024d (patch) | |
| tree | 6ccd0b90df84a94a4b7b4f8a6622d11786d74714 | |
| parent | 73d62d83ec3627782ba6f55defc76f3ffbef46ee (diff) | |
[PATCH] another round of fs/pipe.c cleanups
make pipe.c a bit more readable and hackable.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Jens Axboe <axboe@suse.de>
| -rw-r--r-- | fs/pipe.c | 76 |
1 files changed, 48 insertions, 28 deletions
| @@ -44,7 +44,8 @@ void pipe_wait(struct pipe_inode_info *pipe) | |||
| 44 | * Pipes are system-local resources, so sleeping on them | 44 | * Pipes are system-local resources, so sleeping on them |
| 45 | * is considered a noninteractive wait: | 45 | * is considered a noninteractive wait: |
| 46 | */ | 46 | */ |
| 47 | prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE); | 47 | prepare_to_wait(&pipe->wait, &wait, |
| 48 | TASK_INTERRUPTIBLE | TASK_NONINTERACTIVE); | ||
| 48 | if (pipe->inode) | 49 | if (pipe->inode) |
| 49 | mutex_unlock(&pipe->inode->i_mutex); | 50 | mutex_unlock(&pipe->inode->i_mutex); |
| 50 | schedule(); | 51 | schedule(); |
| @@ -93,7 +94,8 @@ pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len) | |||
| 93 | return 0; | 94 | return 0; |
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf) | 97 | static void anon_pipe_buf_release(struct pipe_inode_info *pipe, |
| 98 | struct pipe_buffer *buf) | ||
| 97 | { | 99 | { |
| 98 | struct page *page = buf->page; | 100 | struct page *page = buf->page; |
| 99 | 101 | ||
| @@ -102,25 +104,22 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buff | |||
| 102 | /* | 104 | /* |
| 103 | * If nobody else uses this page, and we don't already have a | 105 | * If nobody else uses this page, and we don't already have a |
| 104 | * temporary page, let's keep track of it as a one-deep | 106 | * temporary page, let's keep track of it as a one-deep |
| 105 | * allocation cache | 107 | * allocation cache. (Otherwise just release our reference to it) |
| 106 | */ | 108 | */ |
| 107 | if (page_count(page) == 1 && !pipe->tmp_page) { | 109 | if (page_count(page) == 1 && !pipe->tmp_page) |
| 108 | pipe->tmp_page = page; | 110 | pipe->tmp_page = page; |
| 109 | return; | 111 | else |
| 110 | } | 112 | page_cache_release(page); |
| 111 | |||
| 112 | /* | ||
| 113 | * Otherwise just release our reference to it | ||
| 114 | */ | ||
| 115 | page_cache_release(page); | ||
| 116 | } | 113 | } |
| 117 | 114 | ||
| 118 | static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe, struct pipe_buffer *buf) | 115 | static void * anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe, |
| 116 | struct pipe_buffer *buf) | ||
| 119 | { | 117 | { |
| 120 | return kmap(buf->page); | 118 | return kmap(buf->page); |
| 121 | } | 119 | } |
| 122 | 120 | ||
| 123 | static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe, struct pipe_buffer *buf) | 121 | static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe, |
| 122 | struct pipe_buffer *buf) | ||
| 124 | { | 123 | { |
| 125 | kunmap(buf->page); | 124 | kunmap(buf->page); |
| 126 | } | 125 | } |
| @@ -182,7 +181,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
| 182 | error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars); | 181 | error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars); |
| 183 | ops->unmap(pipe, buf); | 182 | ops->unmap(pipe, buf); |
| 184 | if (unlikely(error)) { | 183 | if (unlikely(error)) { |
| 185 | if (!ret) ret = -EFAULT; | 184 | if (!ret) |
| 185 | ret = -EFAULT; | ||
| 186 | break; | 186 | break; |
| 187 | } | 187 | } |
| 188 | ret += chars; | 188 | ret += chars; |
| @@ -218,7 +218,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
| 218 | } | 218 | } |
| 219 | } | 219 | } |
| 220 | if (signal_pending(current)) { | 220 | if (signal_pending(current)) { |
| 221 | if (!ret) ret = -ERESTARTSYS; | 221 | if (!ret) |
| 222 | ret = -ERESTARTSYS; | ||
| 222 | break; | 223 | break; |
| 223 | } | 224 | } |
| 224 | if (do_wakeup) { | 225 | if (do_wakeup) { |
| @@ -228,7 +229,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
| 228 | pipe_wait(pipe); | 229 | pipe_wait(pipe); |
| 229 | } | 230 | } |
| 230 | mutex_unlock(&inode->i_mutex); | 231 | mutex_unlock(&inode->i_mutex); |
| 231 | /* Signal writers asynchronously that there is more room. */ | 232 | |
| 233 | /* Signal writers asynchronously that there is more room. */ | ||
| 232 | if (do_wakeup) { | 234 | if (do_wakeup) { |
| 233 | wake_up_interruptible(&pipe->wait); | 235 | wake_up_interruptible(&pipe->wait); |
| 234 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | 236 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
| @@ -242,6 +244,7 @@ static ssize_t | |||
| 242 | pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | 244 | pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) |
| 243 | { | 245 | { |
| 244 | struct iovec iov = { .iov_base = buf, .iov_len = count }; | 246 | struct iovec iov = { .iov_base = buf, .iov_len = count }; |
| 247 | |||
| 245 | return pipe_readv(filp, &iov, 1, ppos); | 248 | return pipe_readv(filp, &iov, 1, ppos); |
| 246 | } | 249 | } |
| 247 | 250 | ||
| @@ -276,10 +279,12 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
| 276 | /* We try to merge small writes */ | 279 | /* We try to merge small writes */ |
| 277 | chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */ | 280 | chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */ |
| 278 | if (pipe->nrbufs && chars != 0) { | 281 | if (pipe->nrbufs && chars != 0) { |
| 279 | int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & (PIPE_BUFFERS-1); | 282 | int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & |
| 283 | (PIPE_BUFFERS-1); | ||
| 280 | struct pipe_buffer *buf = pipe->bufs + lastbuf; | 284 | struct pipe_buffer *buf = pipe->bufs + lastbuf; |
| 281 | struct pipe_buf_operations *ops = buf->ops; | 285 | struct pipe_buf_operations *ops = buf->ops; |
| 282 | int offset = buf->offset + buf->len; | 286 | int offset = buf->offset + buf->len; |
| 287 | |||
| 283 | if (ops->can_merge && offset + chars <= PAGE_SIZE) { | 288 | if (ops->can_merge && offset + chars <= PAGE_SIZE) { |
| 284 | void *addr; | 289 | void *addr; |
| 285 | int error; | 290 | int error; |
| @@ -306,9 +311,11 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
| 306 | 311 | ||
| 307 | for (;;) { | 312 | for (;;) { |
| 308 | int bufs; | 313 | int bufs; |
| 314 | |||
| 309 | if (!pipe->readers) { | 315 | if (!pipe->readers) { |
| 310 | send_sig(SIGPIPE, current, 0); | 316 | send_sig(SIGPIPE, current, 0); |
| 311 | if (!ret) ret = -EPIPE; | 317 | if (!ret) |
| 318 | ret = -EPIPE; | ||
| 312 | break; | 319 | break; |
| 313 | } | 320 | } |
| 314 | bufs = pipe->nrbufs; | 321 | bufs = pipe->nrbufs; |
| @@ -326,7 +333,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
| 326 | } | 333 | } |
| 327 | pipe->tmp_page = page; | 334 | pipe->tmp_page = page; |
| 328 | } | 335 | } |
| 329 | /* Always wakeup, even if the copy fails. Otherwise | 336 | /* Always wake up, even if the copy fails. Otherwise |
| 330 | * we lock up (O_NONBLOCK-)readers that sleep due to | 337 | * we lock up (O_NONBLOCK-)readers that sleep due to |
| 331 | * syscall merging. | 338 | * syscall merging. |
| 332 | * FIXME! Is this really true? | 339 | * FIXME! Is this really true? |
| @@ -339,7 +346,8 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
| 339 | error = pipe_iov_copy_from_user(kmap(page), iov, chars); | 346 | error = pipe_iov_copy_from_user(kmap(page), iov, chars); |
| 340 | kunmap(page); | 347 | kunmap(page); |
| 341 | if (unlikely(error)) { | 348 | if (unlikely(error)) { |
| 342 | if (!ret) ret = -EFAULT; | 349 | if (!ret) |
| 350 | ret = -EFAULT; | ||
| 343 | break; | 351 | break; |
| 344 | } | 352 | } |
| 345 | ret += chars; | 353 | ret += chars; |
| @@ -359,11 +367,13 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
| 359 | if (bufs < PIPE_BUFFERS) | 367 | if (bufs < PIPE_BUFFERS) |
| 360 | continue; | 368 | continue; |
| 361 | if (filp->f_flags & O_NONBLOCK) { | 369 | if (filp->f_flags & O_NONBLOCK) { |
| 362 | if (!ret) ret = -EAGAIN; | 370 | if (!ret) |
| 371 | ret = -EAGAIN; | ||
| 363 | break; | 372 | break; |
| 364 | } | 373 | } |
| 365 | if (signal_pending(current)) { | 374 | if (signal_pending(current)) { |
| 366 | if (!ret) ret = -ERESTARTSYS; | 375 | if (!ret) |
| 376 | ret = -ERESTARTSYS; | ||
| 367 | break; | 377 | break; |
| 368 | } | 378 | } |
| 369 | if (do_wakeup) { | 379 | if (do_wakeup) { |
| @@ -391,6 +401,7 @@ pipe_write(struct file *filp, const char __user *buf, | |||
| 391 | size_t count, loff_t *ppos) | 401 | size_t count, loff_t *ppos) |
| 392 | { | 402 | { |
| 393 | struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; | 403 | struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; |
| 404 | |||
| 394 | return pipe_writev(filp, &iov, 1, ppos); | 405 | return pipe_writev(filp, &iov, 1, ppos); |
| 395 | } | 406 | } |
| 396 | 407 | ||
| @@ -401,7 +412,8 @@ bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | |||
| 401 | } | 412 | } |
| 402 | 413 | ||
| 403 | static ssize_t | 414 | static ssize_t |
| 404 | bad_pipe_w(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) | 415 | bad_pipe_w(struct file *filp, const char __user *buf, size_t count, |
| 416 | loff_t *ppos) | ||
| 405 | { | 417 | { |
| 406 | return -EBADF; | 418 | return -EBADF; |
| 407 | } | 419 | } |
| @@ -475,6 +487,7 @@ pipe_release(struct inode *inode, int decr, int decw) | |||
| 475 | pipe = inode->i_pipe; | 487 | pipe = inode->i_pipe; |
| 476 | pipe->readers -= decr; | 488 | pipe->readers -= decr; |
| 477 | pipe->writers -= decw; | 489 | pipe->writers -= decw; |
| 490 | |||
| 478 | if (!pipe->readers && !pipe->writers) { | 491 | if (!pipe->readers && !pipe->writers) { |
| 479 | free_pipe_info(inode); | 492 | free_pipe_info(inode); |
| 480 | } else { | 493 | } else { |
| @@ -525,14 +538,15 @@ static int | |||
| 525 | pipe_rdwr_fasync(int fd, struct file *filp, int on) | 538 | pipe_rdwr_fasync(int fd, struct file *filp, int on) |
| 526 | { | 539 | { |
| 527 | struct inode *inode = filp->f_dentry->d_inode; | 540 | struct inode *inode = filp->f_dentry->d_inode; |
| 541 | struct pipe_inode_info *pipe = inode->i_pipe; | ||
| 528 | int retval; | 542 | int retval; |
| 529 | 543 | ||
| 530 | mutex_lock(&inode->i_mutex); | 544 | mutex_lock(&inode->i_mutex); |
| 531 | 545 | ||
| 532 | retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers); | 546 | retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); |
| 533 | 547 | ||
| 534 | if (retval >= 0) | 548 | if (retval >= 0) |
| 535 | retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers); | 549 | retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); |
| 536 | 550 | ||
| 537 | mutex_unlock(&inode->i_mutex); | 551 | mutex_unlock(&inode->i_mutex); |
| 538 | 552 | ||
| @@ -720,6 +734,7 @@ static int pipefs_delete_dentry(struct dentry *dentry) | |||
| 720 | { | 734 | { |
| 721 | return 1; | 735 | return 1; |
| 722 | } | 736 | } |
| 737 | |||
| 723 | static struct dentry_operations pipefs_dentry_operations = { | 738 | static struct dentry_operations pipefs_dentry_operations = { |
| 724 | .d_delete = pipefs_delete_dentry, | 739 | .d_delete = pipefs_delete_dentry, |
| 725 | }; | 740 | }; |
| @@ -757,6 +772,7 @@ static struct inode * get_pipe_inode(void) | |||
| 757 | 772 | ||
| 758 | fail_iput: | 773 | fail_iput: |
| 759 | iput(inode); | 774 | iput(inode); |
| 775 | |||
| 760 | fail_inode: | 776 | fail_inode: |
| 761 | return NULL; | 777 | return NULL; |
| 762 | } | 778 | } |
| @@ -769,7 +785,7 @@ int do_pipe(int *fd) | |||
| 769 | struct inode * inode; | 785 | struct inode * inode; |
| 770 | struct file *f1, *f2; | 786 | struct file *f1, *f2; |
| 771 | int error; | 787 | int error; |
| 772 | int i,j; | 788 | int i, j; |
| 773 | 789 | ||
| 774 | error = -ENFILE; | 790 | error = -ENFILE; |
| 775 | f1 = get_empty_filp(); | 791 | f1 = get_empty_filp(); |
| @@ -802,6 +818,7 @@ int do_pipe(int *fd) | |||
| 802 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); | 818 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); |
| 803 | if (!dentry) | 819 | if (!dentry) |
| 804 | goto close_f12_inode_i_j; | 820 | goto close_f12_inode_i_j; |
| 821 | |||
| 805 | dentry->d_op = &pipefs_dentry_operations; | 822 | dentry->d_op = &pipefs_dentry_operations; |
| 806 | d_add(dentry, inode); | 823 | d_add(dentry, inode); |
| 807 | f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt)); | 824 | f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt)); |
| @@ -825,6 +842,7 @@ int do_pipe(int *fd) | |||
| 825 | fd_install(j, f2); | 842 | fd_install(j, f2); |
| 826 | fd[0] = i; | 843 | fd[0] = i; |
| 827 | fd[1] = j; | 844 | fd[1] = j; |
| 845 | |||
| 828 | return 0; | 846 | return 0; |
| 829 | 847 | ||
| 830 | close_f12_inode_i_j: | 848 | close_f12_inode_i_j: |
| @@ -849,8 +867,9 @@ no_files: | |||
| 849 | * d_name - pipe: will go nicely and kill the special-casing in procfs. | 867 | * d_name - pipe: will go nicely and kill the special-casing in procfs. |
| 850 | */ | 868 | */ |
| 851 | 869 | ||
| 852 | static struct super_block *pipefs_get_sb(struct file_system_type *fs_type, | 870 | static struct super_block * |
| 853 | int flags, const char *dev_name, void *data) | 871 | pipefs_get_sb(struct file_system_type *fs_type, int flags, |
| 872 | const char *dev_name, void *data) | ||
| 854 | { | 873 | { |
| 855 | return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC); | 874 | return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC); |
| 856 | } | 875 | } |
| @@ -864,6 +883,7 @@ static struct file_system_type pipe_fs_type = { | |||
| 864 | static int __init init_pipe_fs(void) | 883 | static int __init init_pipe_fs(void) |
| 865 | { | 884 | { |
| 866 | int err = register_filesystem(&pipe_fs_type); | 885 | int err = register_filesystem(&pipe_fs_type); |
| 886 | |||
| 867 | if (!err) { | 887 | if (!err) { |
| 868 | pipe_mnt = kern_mount(&pipe_fs_type); | 888 | pipe_mnt = kern_mount(&pipe_fs_type); |
| 869 | if (IS_ERR(pipe_mnt)) { | 889 | if (IS_ERR(pipe_mnt)) { |
