diff mbox series

[6/6] io_pgetevents: deduplicate compat logic

Message ID 20210112003017.4010304-7-willemdebruijn.kernel@gmail.com (mailing list archive)
State New, archived
Headers show
Series fs: deduplicate compat logic | expand

Commit Message

Willem de Bruijn Jan. 12, 2021, 12:30 a.m. UTC
From: Willem de Bruijn <willemb@google.com>

io_pgetevents has four variants, including compat variants of both
timespec and sigmask.

With set_maybe_compat_user_sigmask helper, the latter can be
deduplicated. Move the shared logic to new do_io_pgetevents,
analogous to do_io_getevents.

Signed-off-by: Willem de Bruijn <willemb@google.com>
Cc: Benjamin LaHaise <bcrl@kvack.org>
---
 fs/aio.c | 94 ++++++++++++++++++++++----------------------------------
 1 file changed, 37 insertions(+), 57 deletions(-)
diff mbox series

Patch

diff --git a/fs/aio.c b/fs/aio.c
index d213be7b8a7e..56460ab47d64 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -2101,6 +2101,31 @@  struct __aio_sigset {
 	size_t		sigsetsize;
 };
 
+static long do_io_pgetevents(aio_context_t ctx_id,
+		long min_nr,
+		long nr,
+		struct io_event __user *events,
+		struct timespec64 *ts,
+		const void __user *umask,
+		size_t sigsetsize)
+{
+	bool interrupted;
+	int ret;
+
+	ret = set_maybe_compat_user_sigmask(umask, sigsetsize);
+	if (ret)
+		return ret;
+
+	ret = do_io_getevents(ctx_id, min_nr, nr, events, ts);
+
+	interrupted = signal_pending(current);
+	restore_saved_sigmask_unless(interrupted);
+	if (interrupted && !ret)
+		ret = -ERESTARTNOHAND;
+
+	return ret;
+}
+
 SYSCALL_DEFINE6(io_pgetevents,
 		aio_context_t, ctx_id,
 		long, min_nr,
@@ -2111,8 +2136,6 @@  SYSCALL_DEFINE6(io_pgetevents,
 {
 	struct __aio_sigset	ksig = { NULL, };
 	struct timespec64	ts;
-	bool interrupted;
-	int ret;
 
 	if (timeout && unlikely(get_timespec64(&ts, timeout)))
 		return -EFAULT;
@@ -2120,18 +2143,9 @@  SYSCALL_DEFINE6(io_pgetevents,
 	if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
 		return -EFAULT;
 
-	ret = set_user_sigmask(ksig.sigmask, ksig.sigsetsize);
-	if (ret)
-		return ret;
-
-	ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
-
-	interrupted = signal_pending(current);
-	restore_saved_sigmask_unless(interrupted);
-	if (interrupted && !ret)
-		ret = -ERESTARTNOHAND;
-
-	return ret;
+	return do_io_pgetevents(ctx_id, min_nr, nr, events,
+				timeout ? &ts : NULL,
+				ksig.sigmask, ksig.sigsetsize);
 }
 
 #if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
@@ -2146,8 +2160,6 @@  SYSCALL_DEFINE6(io_pgetevents_time32,
 {
 	struct __aio_sigset	ksig = { NULL, };
 	struct timespec64	ts;
-	bool interrupted;
-	int ret;
 
 	if (timeout && unlikely(get_old_timespec32(&ts, timeout)))
 		return -EFAULT;
@@ -2155,19 +2167,9 @@  SYSCALL_DEFINE6(io_pgetevents_time32,
 	if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
 		return -EFAULT;
 
-
-	ret = set_user_sigmask(ksig.sigmask, ksig.sigsetsize);
-	if (ret)
-		return ret;
-
-	ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
-
-	interrupted = signal_pending(current);
-	restore_saved_sigmask_unless(interrupted);
-	if (interrupted && !ret)
-		ret = -ERESTARTNOHAND;
-
-	return ret;
+	return do_io_pgetevents(ctx_id, min_nr, nr, events,
+				timeout ? &ts : NULL,
+				ksig.sigmask, ksig.sigsetsize);
 }
 
 #endif
@@ -2213,8 +2215,6 @@  COMPAT_SYSCALL_DEFINE6(io_pgetevents,
 {
 	struct __compat_aio_sigset ksig = { 0, };
 	struct timespec64 t;
-	bool interrupted;
-	int ret;
 
 	if (timeout && get_old_timespec32(&t, timeout))
 		return -EFAULT;
@@ -2222,18 +2222,9 @@  COMPAT_SYSCALL_DEFINE6(io_pgetevents,
 	if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
 		return -EFAULT;
 
-	ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), ksig.sigsetsize);
-	if (ret)
-		return ret;
-
-	ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
-
-	interrupted = signal_pending(current);
-	restore_saved_sigmask_unless(interrupted);
-	if (interrupted && !ret)
-		ret = -ERESTARTNOHAND;
-
-	return ret;
+	return do_io_pgetevents(ctx_id, min_nr, nr, events,
+				timeout ? &t : NULL,
+				compat_ptr(ksig.sigmask), ksig.sigsetsize);
 }
 
 #endif
@@ -2248,8 +2239,6 @@  COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
 {
 	struct __compat_aio_sigset ksig = { 0, };
 	struct timespec64 t;
-	bool interrupted;
-	int ret;
 
 	if (timeout && get_timespec64(&t, timeout))
 		return -EFAULT;
@@ -2257,17 +2246,8 @@  COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
 	if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
 		return -EFAULT;
 
-	ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), ksig.sigsetsize);
-	if (ret)
-		return ret;
-
-	ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
-
-	interrupted = signal_pending(current);
-	restore_saved_sigmask_unless(interrupted);
-	if (interrupted && !ret)
-		ret = -ERESTARTNOHAND;
-
-	return ret;
+	return do_io_pgetevents(ctx_id, min_nr, nr, events,
+				timeout ? &t : NULL,
+				compat_ptr(ksig.sigmask), ksig.sigsetsize);
 }
 #endif