diff options
-rw-r--r-- | fs/pipe.c | 40 |
1 files changed, 25 insertions, 15 deletions
@@ -75,6 +75,16 @@ void pipe_unlock(struct pipe_inode_info *pipe) } EXPORT_SYMBOL(pipe_unlock); +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); +} + void pipe_double_lock(struct pipe_inode_info *pipe1, struct pipe_inode_info *pipe2) { @@ -376,7 +386,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, do_wakeup = 0; ret = 0; - pipe_lock(pipe); + __pipe_lock(pipe); for (;;) { int bufs = pipe->nrbufs; if (bufs) { @@ -464,7 +474,7 @@ redo: } pipe_wait(pipe); } - pipe_unlock(pipe); + __pipe_unlock(pipe); /* Signal writers asynchronously that there is more room. */ if (do_wakeup) { @@ -500,7 +510,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, do_wakeup = 0; ret = 0; - pipe_lock(pipe); + __pipe_lock(pipe); if (!pipe->readers) { send_sig(SIGPIPE, current, 0); @@ -647,7 +657,7 @@ redo2: pipe->waiting_writers--; } out: - pipe_unlock(pipe); + __pipe_unlock(pipe); if (do_wakeup) { wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM); kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); @@ -667,7 +677,7 @@ static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) switch (cmd) { case FIONREAD: - pipe_lock(pipe); + __pipe_lock(pipe); count = 0; buf = pipe->curbuf; nrbufs = pipe->nrbufs; @@ -675,7 +685,7 @@ static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) count += pipe->bufs[buf].len; buf = (buf+1) & (pipe->buffers - 1); } - pipe_unlock(pipe); + __pipe_unlock(pipe); return put_user(count, (int __user *)arg); default: @@ -721,7 +731,7 @@ pipe_release(struct inode *inode, struct file *file) struct pipe_inode_info *pipe = inode->i_pipe; int kill = 0; - pipe_lock(pipe); + __pipe_lock(pipe); if (file->f_mode & FMODE_READ) pipe->readers--; if (file->f_mode & FMODE_WRITE) @@ -738,7 +748,7 @@ pipe_release(struct inode *inode, struct file *file) kill = 1; } spin_unlock(&inode->i_lock); - pipe_unlock(pipe); + __pipe_unlock(pipe); if (kill) __free_pipe_info(pipe); @@ -752,7 +762,7 @@ pipe_fasync(int fd, struct file *filp, int on) struct pipe_inode_info *pipe = filp->private_data; int retval = 0; - pipe_lock(pipe); + __pipe_lock(pipe); if (filp->f_mode & FMODE_READ) retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); if ((filp->f_mode & FMODE_WRITE) && retval >= 0) { @@ -761,7 +771,7 @@ pipe_fasync(int fd, struct file *filp, int on) /* this can happen only if on == T */ fasync_helper(-1, filp, 0, &pipe->fasync_readers); } - pipe_unlock(pipe); + __pipe_unlock(pipe); return retval; } @@ -1040,7 +1050,7 @@ static int fifo_open(struct inode *inode, struct file *filp) filp->private_data = pipe; /* OK, we have a pipe and it's pinned down */ - pipe_lock(pipe); + __pipe_lock(pipe); /* We can only do regular read/write on fifos */ filp->f_mode &= (FMODE_READ | FMODE_WRITE); @@ -1110,7 +1120,7 @@ static int fifo_open(struct inode *inode, struct file *filp) } /* Ok! */ - pipe_unlock(pipe); + __pipe_unlock(pipe); return 0; err_rd: @@ -1132,7 +1142,7 @@ err: kill = 1; } spin_unlock(&inode->i_lock); - pipe_unlock(pipe); + __pipe_unlock(pipe); if (kill) __free_pipe_info(pipe); return ret; @@ -1248,7 +1258,7 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) if (!pipe) return -EBADF; - pipe_lock(pipe); + __pipe_lock(pipe); switch (cmd) { case F_SETPIPE_SZ: { @@ -1277,7 +1287,7 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) } out: - pipe_unlock(pipe); + __pipe_unlock(pipe); return ret; } |