diff options
| author | Christoph Hellwig <hch@lst.de> | 2018-05-02 13:51:00 -0400 |
|---|---|---|
| committer | Christoph Hellwig <hch@lst.de> | 2018-05-02 13:57:24 -0400 |
| commit | 7a074e96dee62586c935c80cecd931431bfdd0be (patch) | |
| tree | a1a29dad896070e82827d7447cfcc9a064e5a63d /include | |
| parent | a3c0d439e4d92411c2b4b21a526a4de720d0806b (diff) | |
aio: implement io_pgetevents
This is the io_getevents equivalent of ppoll/pselect and allows to
properly mix signals and aio completions (especially with IOCB_CMD_POLL)
and atomically executes the following sequence:
sigset_t origmask;
pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
ret = io_getevents(ctx, min_nr, nr, events, timeout);
pthread_sigmask(SIG_SETMASK, &origmask, NULL);
Note that unlike many other signal related calls we do not pass a sigmask
size, as that would get us to 7 arguments, which aren't easily supported
by the syscall infrastructure. It seems a lot less painful to just add a
new syscall variant in the unlikely case we're going to increase the
sigset size.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/compat.h | 7 | ||||
| -rw-r--r-- | include/linux/syscalls.h | 6 | ||||
| -rw-r--r-- | include/uapi/asm-generic/unistd.h | 4 | ||||
| -rw-r--r-- | include/uapi/linux/aio_abi.h | 6 |
4 files changed, 22 insertions, 1 deletions
diff --git a/include/linux/compat.h b/include/linux/compat.h index 081281ad5772..ad192057b887 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
| @@ -330,6 +330,7 @@ extern int put_compat_rusage(const struct rusage *, | |||
| 330 | struct compat_rusage __user *); | 330 | struct compat_rusage __user *); |
| 331 | 331 | ||
| 332 | struct compat_siginfo; | 332 | struct compat_siginfo; |
| 333 | struct __compat_aio_sigset; | ||
| 333 | 334 | ||
| 334 | struct compat_dirent { | 335 | struct compat_dirent { |
| 335 | u32 d_ino; | 336 | u32 d_ino; |
| @@ -553,6 +554,12 @@ asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id, | |||
| 553 | compat_long_t nr, | 554 | compat_long_t nr, |
| 554 | struct io_event __user *events, | 555 | struct io_event __user *events, |
| 555 | struct compat_timespec __user *timeout); | 556 | struct compat_timespec __user *timeout); |
| 557 | asmlinkage long compat_sys_io_pgetevents(compat_aio_context_t ctx_id, | ||
| 558 | compat_long_t min_nr, | ||
| 559 | compat_long_t nr, | ||
| 560 | struct io_event __user *events, | ||
| 561 | struct compat_timespec __user *timeout, | ||
| 562 | const struct __compat_aio_sigset __user *usig); | ||
| 556 | 563 | ||
| 557 | /* fs/cookies.c */ | 564 | /* fs/cookies.c */ |
| 558 | asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, compat_size_t); | 565 | asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, compat_size_t); |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 70fcda1a9049..811172fcb916 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
| @@ -290,6 +290,12 @@ asmlinkage long sys_io_getevents(aio_context_t ctx_id, | |||
| 290 | long nr, | 290 | long nr, |
| 291 | struct io_event __user *events, | 291 | struct io_event __user *events, |
| 292 | struct timespec __user *timeout); | 292 | struct timespec __user *timeout); |
| 293 | asmlinkage long sys_io_pgetevents(aio_context_t ctx_id, | ||
| 294 | long min_nr, | ||
| 295 | long nr, | ||
| 296 | struct io_event __user *events, | ||
| 297 | struct timespec __user *timeout, | ||
| 298 | const struct __aio_sigset *sig); | ||
| 293 | 299 | ||
| 294 | /* fs/xattr.c */ | 300 | /* fs/xattr.c */ |
| 295 | asmlinkage long sys_setxattr(const char __user *path, const char __user *name, | 301 | asmlinkage long sys_setxattr(const char __user *path, const char __user *name, |
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 8bcb186c6f67..42990676a55e 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h | |||
| @@ -732,9 +732,11 @@ __SYSCALL(__NR_pkey_alloc, sys_pkey_alloc) | |||
| 732 | __SYSCALL(__NR_pkey_free, sys_pkey_free) | 732 | __SYSCALL(__NR_pkey_free, sys_pkey_free) |
| 733 | #define __NR_statx 291 | 733 | #define __NR_statx 291 |
| 734 | __SYSCALL(__NR_statx, sys_statx) | 734 | __SYSCALL(__NR_statx, sys_statx) |
| 735 | #define __NR_io_pgetevents 292 | ||
| 736 | __SC_COMP(__NR_io_pgetevents, sys_io_pgetevents, compat_sys_io_pgetevents) | ||
| 735 | 737 | ||
| 736 | #undef __NR_syscalls | 738 | #undef __NR_syscalls |
| 737 | #define __NR_syscalls 292 | 739 | #define __NR_syscalls 293 |
| 738 | 740 | ||
| 739 | /* | 741 | /* |
| 740 | * 32 bit systems traditionally used different | 742 | * 32 bit systems traditionally used different |
diff --git a/include/uapi/linux/aio_abi.h b/include/uapi/linux/aio_abi.h index a04adbc70ddf..2c0a3415beee 100644 --- a/include/uapi/linux/aio_abi.h +++ b/include/uapi/linux/aio_abi.h | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
| 31 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
| 32 | #include <linux/signal.h> | ||
| 32 | #include <asm/byteorder.h> | 33 | #include <asm/byteorder.h> |
| 33 | 34 | ||
| 34 | typedef __kernel_ulong_t aio_context_t; | 35 | typedef __kernel_ulong_t aio_context_t; |
| @@ -108,5 +109,10 @@ struct iocb { | |||
| 108 | #undef IFBIG | 109 | #undef IFBIG |
| 109 | #undef IFLITTLE | 110 | #undef IFLITTLE |
| 110 | 111 | ||
| 112 | struct __aio_sigset { | ||
| 113 | sigset_t __user *sigmask; | ||
| 114 | size_t sigsetsize; | ||
| 115 | }; | ||
| 116 | |||
| 111 | #endif /* __LINUX__AIO_ABI_H */ | 117 | #endif /* __LINUX__AIO_ABI_H */ |
| 112 | 118 | ||
