aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pipe.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2006-04-10 09:18:35 -0400
committerJens Axboe <axboe@suse.de>2006-04-10 09:18:35 -0400
commit3a326a2ce88e71d00ac0d133e314a3342a7709f8 (patch)
tree3a3cf55be19311c04d195e37baec9f49c4015b18 /fs/pipe.c
parent0b749ce3802428007a37870eb51ba3c0bdf90857 (diff)
[PATCH] introduce a "kernel-internal pipe object" abstraction
separate out the 'internal pipe object' abstraction, and make it usable to splice. This cleans up and fixes several aspects of the internal splice APIs and the pipe code: - pipes: the allocation and freeing of pipe_inode_info is now more symmetric and more streamlined with existing kernel practices. - splice: small micro-optimization: less pointer dereferencing in splice methods Signed-off-by: Ingo Molnar <mingo@elte.hu> Update XFS for the ->splice_read/->splice_write changes. Signed-off-by: Jens Axboe <axboe@suse.de>
Diffstat (limited to 'fs/pipe.c')
-rw-r--r--fs/pipe.c51
1 files changed, 26 insertions, 25 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index 795df987cd38..705b48692627 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -36,7 +36,7 @@
36 */ 36 */
37 37
38/* Drop the inode semaphore and wait for a pipe event, atomically */ 38/* Drop the inode semaphore and wait for a pipe event, atomically */
39void pipe_wait(struct inode * inode) 39void pipe_wait(struct pipe_inode_info *pipe)
40{ 40{
41 DEFINE_WAIT(wait); 41 DEFINE_WAIT(wait);
42 42
@@ -44,11 +44,13 @@ void pipe_wait(struct inode * inode)
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(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE); 47 prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
48 mutex_unlock(PIPE_MUTEX(*inode)); 48 if (pipe->inode)
49 mutex_unlock(&pipe->inode->i_mutex);
49 schedule(); 50 schedule();
50 finish_wait(PIPE_WAIT(*inode), &wait); 51 finish_wait(&pipe->wait, &wait);
51 mutex_lock(PIPE_MUTEX(*inode)); 52 if (pipe->inode)
53 mutex_lock(&pipe->inode->i_mutex);
52} 54}
53 55
54static int 56static int
@@ -223,7 +225,7 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
223 wake_up_interruptible_sync(PIPE_WAIT(*inode)); 225 wake_up_interruptible_sync(PIPE_WAIT(*inode));
224 kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); 226 kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
225 } 227 }
226 pipe_wait(inode); 228 pipe_wait(inode->i_pipe);
227 } 229 }
228 mutex_unlock(PIPE_MUTEX(*inode)); 230 mutex_unlock(PIPE_MUTEX(*inode));
229 /* Signal writers asynchronously that there is more room. */ 231 /* Signal writers asynchronously that there is more room. */
@@ -370,7 +372,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
370 do_wakeup = 0; 372 do_wakeup = 0;
371 } 373 }
372 PIPE_WAITING_WRITERS(*inode)++; 374 PIPE_WAITING_WRITERS(*inode)++;
373 pipe_wait(inode); 375 pipe_wait(inode->i_pipe);
374 PIPE_WAITING_WRITERS(*inode)--; 376 PIPE_WAITING_WRITERS(*inode)--;
375 } 377 }
376out: 378out:
@@ -675,6 +677,20 @@ static struct file_operations rdwr_pipe_fops = {
675 .fasync = pipe_rdwr_fasync, 677 .fasync = pipe_rdwr_fasync,
676}; 678};
677 679
680struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
681{
682 struct pipe_inode_info *info;
683
684 info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
685 if (info) {
686 init_waitqueue_head(&info->wait);
687 info->r_counter = info->w_counter = 1;
688 info->inode = inode;
689 }
690
691 return info;
692}
693
678void free_pipe_info(struct inode *inode) 694void free_pipe_info(struct inode *inode)
679{ 695{
680 int i; 696 int i;
@@ -691,23 +707,6 @@ void free_pipe_info(struct inode *inode)
691 kfree(info); 707 kfree(info);
692} 708}
693 709
694struct inode* pipe_new(struct inode* inode)
695{
696 struct pipe_inode_info *info;
697
698 info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
699 if (!info)
700 goto fail_page;
701 inode->i_pipe = info;
702
703 init_waitqueue_head(PIPE_WAIT(*inode));
704 PIPE_RCOUNTER(*inode) = PIPE_WCOUNTER(*inode) = 1;
705
706 return inode;
707fail_page:
708 return NULL;
709}
710
711static struct vfsmount *pipe_mnt __read_mostly; 710static struct vfsmount *pipe_mnt __read_mostly;
712static int pipefs_delete_dentry(struct dentry *dentry) 711static int pipefs_delete_dentry(struct dentry *dentry)
713{ 712{
@@ -724,8 +723,10 @@ static struct inode * get_pipe_inode(void)
724 if (!inode) 723 if (!inode)
725 goto fail_inode; 724 goto fail_inode;
726 725
727 if(!pipe_new(inode)) 726 inode->i_pipe = alloc_pipe_info(inode);
727 if (!inode->i_pipe)
728 goto fail_iput; 728 goto fail_iput;
729
729 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; 730 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
730 inode->i_fop = &rdwr_pipe_fops; 731 inode->i_fop = &rdwr_pipe_fops;
731 732