summaryrefslogtreecommitdiffstats
path: root/fs/pipe.c
diff options
context:
space:
mode:
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 795df987cd3..705b4869262 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -36,7 +36,7 @@
*/
/* Drop the inode semaphore and wait for a pipe event, atomically */
-void pipe_wait(struct inode * inode)
+void pipe_wait(struct pipe_inode_info *pipe)
{
DEFINE_WAIT(wait);
@@ -44,11 +44,13 @@ void pipe_wait(struct inode * inode)
* Pipes are system-local resources, so sleeping on them
* is considered a noninteractive wait:
*/
- prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
- mutex_unlock(PIPE_MUTEX(*inode));
+ prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
+ if (pipe->inode)
+ mutex_unlock(&pipe->inode->i_mutex);
schedule();
- finish_wait(PIPE_WAIT(*inode), &wait);
- mutex_lock(PIPE_MUTEX(*inode));
+ finish_wait(&pipe->wait, &wait);
+ if (pipe->inode)
+ mutex_lock(&pipe->inode->i_mutex);
}
static int
@@ -223,7 +225,7 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
wake_up_interruptible_sync(PIPE_WAIT(*inode));
kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
}
- pipe_wait(inode);
+ pipe_wait(inode->i_pipe);
}
mutex_unlock(PIPE_MUTEX(*inode));
/* Signal writers asynchronously that there is more room. */
@@ -370,7 +372,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
do_wakeup = 0;
}
PIPE_WAITING_WRITERS(*inode)++;
- pipe_wait(inode);
+ pipe_wait(inode->i_pipe);
PIPE_WAITING_WRITERS(*inode)--;
}
out:
@@ -675,6 +677,20 @@ static struct file_operations rdwr_pipe_fops = {
.fasync = pipe_rdwr_fasync,
};
+struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
+{
+ struct pipe_inode_info *info;
+
+ info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
+ if (info) {
+ init_waitqueue_head(&info->wait);
+ info->r_counter = info->w_counter = 1;
+ info->inode = inode;
+ }
+
+ return info;
+}
+
void free_pipe_info(struct inode *inode)
{
int i;
@@ -691,23 +707,6 @@ void free_pipe_info(struct inode *inode)
kfree(info);
}
-struct inode* pipe_new(struct inode* inode)
-{
- struct pipe_inode_info *info;
-
- info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
- if (!info)
- goto fail_page;
- inode->i_pipe = info;
-
- init_waitqueue_head(PIPE_WAIT(*inode));
- PIPE_RCOUNTER(*inode) = PIPE_WCOUNTER(*inode) = 1;
-
- return inode;
-fail_page:
- return NULL;
-}
-
static struct vfsmount *pipe_mnt __read_mostly;
static int pipefs_delete_dentry(struct dentry *dentry)
{
@@ -724,8 +723,10 @@ static struct inode * get_pipe_inode(void)
if (!inode)
goto fail_inode;
- if(!pipe_new(inode))
+ inode->i_pipe = alloc_pipe_info(inode);
+ if (!inode->i_pipe)
goto fail_iput;
+
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
inode->i_fop = &rdwr_pipe_fops;