From: Hao Xu <howeyxu@xxxxxxxxxxx> Add two helpers pipe_trylock() and pipe_double_trylock(), they are used in nonblock splice(pipe to pipe) scenario in next patches. Signed-off-by: Hao Xu <howeyxu@xxxxxxxxxxx> --- fs/pipe.c | 29 +++++++++++++++++++++++++++++ include/linux/pipe_fs_i.h | 2 ++ 2 files changed, 31 insertions(+) diff --git a/fs/pipe.c b/fs/pipe.c index 74ae9fafd25a..033736eb61fb 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -98,6 +98,11 @@ void pipe_unlock(struct pipe_inode_info *pipe) } EXPORT_SYMBOL(pipe_unlock); +int pipe_trylock(struct pipe_inode_info *pipe) +{ + return mutex_trylock(&pipe->mutex); +} + static inline void __pipe_lock(struct pipe_inode_info *pipe) { mutex_lock_nested(&pipe->mutex, I_MUTEX_PARENT); @@ -122,6 +127,30 @@ void pipe_double_lock(struct pipe_inode_info *pipe1, } } +int pipe_double_trylock(struct pipe_inode_info *pipe1, + struct pipe_inode_info *pipe2) +{ + BUG_ON(pipe1 == pipe2); + + if (pipe1 < pipe2) { + if (!pipe_trylock(pipe1)) + return 0; + if (!pipe_trylock(pipe2)) { + pipe_unlock(pipe1); + return 0; + } + } else { + if (!pipe_trylock(pipe2)) + return 0; + if (!pipe_trylock(pipe1)) { + pipe_unlock(pipe2); + return 0; + } + } + + return 1; +} + static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index cb0fd633a610..78dc2c7c999f 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -235,8 +235,10 @@ static inline bool pipe_buf_try_steal(struct pipe_inode_info *pipe, /* Pipe lock and unlock operations */ void pipe_lock(struct pipe_inode_info *); +int pipe_trylock(struct pipe_inode_info *); void pipe_unlock(struct pipe_inode_info *); void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *); +int pipe_double_trylock(struct pipe_inode_info *, struct pipe_inode_info *); /* Wait for a pipe to be readable/writable while dropping the pipe lock */ void pipe_wait_readable(struct pipe_inode_info *); -- 2.25.1