diff options
Diffstat (limited to 'fs/pipe.c')
-rw-r--r-- | fs/pipe.c | 51 |
1 files changed, 26 insertions, 25 deletions
@@ -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 */ |
39 | void pipe_wait(struct inode * inode) | 39 | void 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 | ||
54 | static int | 56 | static 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 | } |
376 | out: | 378 | out: |
@@ -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 | ||
680 | struct 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 | |||
678 | void free_pipe_info(struct inode *inode) | 694 | void 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 | ||
694 | struct 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; | ||
707 | fail_page: | ||
708 | return NULL; | ||
709 | } | ||
710 | |||
711 | static struct vfsmount *pipe_mnt __read_mostly; | 710 | static struct vfsmount *pipe_mnt __read_mostly; |
712 | static int pipefs_delete_dentry(struct dentry *dentry) | 711 | static 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 | ||