diff mbox series

[2/5] pipe: add trylock helpers for pipe lock

Message ID 20220607080619.513187-3-hao.xu@linux.dev (mailing list archive)
State New
Headers show
Series support nonblock submission for splice pipe to pipe | expand

Commit Message

Hao Xu June 7, 2022, 8:06 a.m. UTC
From: Hao Xu <howeyxu@tencent.com>

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@tencent.com>
---
 fs/pipe.c                 | 29 +++++++++++++++++++++++++++++
 include/linux/pipe_fs_i.h |  2 ++
 2 files changed, 31 insertions(+)
diff mbox series

Patch

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