@@ -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)
{
@@ -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 *);