]> dgit.raspbian.org Git - libaio.git/commitdiff
[PATCH libaio 21/26] Add time64 syscall support
authorGuillem Jover <guillem@hadrons.org>
Fri, 1 Mar 2024 00:52:51 +0000 (01:52 +0100)
committerPeter Michael Green <plugwash@raspbian.org>
Thu, 4 Jun 2026 18:31:38 +0000 (18:31 +0000)
This implements both io_getevents() and io_pgetevents() as wrappers over
the new aio_getevents() and aio_pgetevents() which use __kernel_timespec
as its timespec data type which should always be 64-bit. We add the
necessary conversion from __kernel_old_timespec or timsepec struct
types.

Signed-off-by: Guillem Jover <guillem@hadrons.org>
Gbp-Pq: Name 0021-Add-time64-syscall-support.patch

src/Makefile
src/aio_getevents.c [new file with mode: 0644]
src/aio_pgetevents.c [new file with mode: 0644]
src/aio_ring.h
src/aio_time.h [new file with mode: 0644]
src/compat-0_1.c
src/io_getevents.c
src/io_pgetevents.c
src/io_queue_run.c
src/io_queue_wait.c

index 387b57f93379f00ccee3a8d9a816dfc9c41bf157..da18e8c7faf4225b06da9f88243b8e250304061c 100644 (file)
@@ -27,6 +27,7 @@ libaio_srcs := io_queue_init.c io_queue_release.c
 libaio_srcs += io_queue_wait.c io_queue_run.c
 
 # real syscalls
+libaio_srcs += aio_pgetevents.c aio_getevents.c
 libaio_srcs += io_getevents.c io_submit.c io_cancel.c
 libaio_srcs += io_setup.c io_destroy.c io_pgetevents.c
 
diff --git a/src/aio_getevents.c b/src/aio_getevents.c
new file mode 100644 (file)
index 0000000..b29ae32
--- /dev/null
@@ -0,0 +1,48 @@
+/* aio_getevents.c
+   libaio Linux async I/O interface
+   Copyright 2002 Red Hat, Inc.
+   Copyright 2024 Guillem Jover <guillem@hadrons.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+#include <libaio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include "syscall.h"
+#include "aio_time.h"
+#include "aio_ring.h"
+
+io_syscall5(int, __aio_getevents, io_getevents, io_context_t, ctx,
+               long, min_nr, long, nr, struct io_event *, events,
+               struct sys_timespec *, timeout)
+
+int aio_getevents(io_context_t ctx, long min_nr, long nr,
+               struct io_event * events, struct __kernel_timespec * timeout)
+{
+       struct sys_timespec ts;
+       int ret;
+
+       ret = aio_pgetevents(ctx, min_nr, nr, events, timeout, NULL);
+       if (ret != -ENOSYS)
+               return ret;
+
+       if (aio_ring_is_empty(ctx, timeout))
+               return 0;
+
+       if (timeout)
+               sys_get_timespec(&ts, timeout);
+       return __aio_getevents(ctx, min_nr, nr, events, timeout ? &ts : NULL);
+}
diff --git a/src/aio_pgetevents.c b/src/aio_pgetevents.c
new file mode 100644 (file)
index 0000000..e12036e
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+   libaio Linux async I/O interface
+   Copyright 2018 Christoph Hellwig.
+   Copyright 2024 Guillem Jover <guillem@hadrons.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+#include <libaio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <signal.h>
+#include "syscall.h"
+#include "aio_time.h"
+#include "aio_ring.h"
+
+#ifdef __NR_io_pgetevents
+io_syscall6(int, __io_pgetevents, io_pgetevents, io_context_t, ctx,
+               long, min_nr, long, nr, struct io_event *, events,
+               struct sys_timespec *, timeout, void *, sigmask);
+#endif
+
+#ifdef __NR_io_pgetevents_time64
+io_syscall6(int, __io_pgetevents_time64, io_pgetevents_time64,
+               io_context_t, ctx,
+               long, min_nr, long, nr, struct io_event *, events,
+               struct __kernel_timespec *, timeout, void *, sigmask);
+#endif
+
+int aio_pgetevents(io_context_t ctx, long min_nr, long nr,
+               struct io_event *events, struct __kernel_timespec *timeout,
+               sigset_t *sigmask)
+{
+       int ret;
+#if defined(__NR_io_pgetevents) || defined(__NR_io_pgetevents_time64)
+       struct {
+               unsigned long ss;
+               unsigned long ss_len;
+       } aio_sigset;
+       struct sys_timespec sys_ts;
+
+       if (aio_ring_is_empty(ctx, timeout))
+               return 0;
+
+       aio_sigset.ss = (unsigned long)sigmask;
+       aio_sigset.ss_len = _NSIG / 8;
+#endif
+
+#ifdef __NR_io_pgetevents_time64
+       /*
+        * On 32-bit systems that have a time64 variant of the syscall at
+        * compile-time we try to use that, and if missing we fallback to
+        * the 32-bit variant.
+        */
+       ret = __io_pgetevents_time64(ctx, min_nr, nr, events, timeout,
+                       sigmask ? &aio_sigset : NULL);
+       if (ret != -ENOSYS)
+               return ret;
+#endif
+
+#ifdef __NR_io_pgetevents
+       if (timeout)
+               sys_get_timespec(&sys_ts, timeout);
+
+       ret = __io_pgetevents(ctx, min_nr, nr, events,
+                       timeout ? &sys_ts : NULL, &aio_sigset);
+#else
+       ret = -ENOSYS;
+#endif
+
+       return ret;
+}
index 3842c4b3c127b8cd09165859b5dc2d7771bb15ae..17fe838ecec816e17cec5b8224148cca62967127 100644 (file)
@@ -33,7 +33,8 @@ struct aio_ring {
        unsigned        header_length;  /* size of aio_ring */
 };
 
-static inline int aio_ring_is_empty(io_context_t ctx, struct timespec *timeout)
+static inline int aio_ring_is_empty(io_context_t ctx,
+       struct __kernel_timespec *timeout)
 {
        struct aio_ring *ring = (struct aio_ring *)ctx;
 
diff --git a/src/aio_time.h b/src/aio_time.h
new file mode 100644 (file)
index 0000000..373a1b0
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+   libaio Linux async I/O interface
+   Copyright 2024 Guillem Jover <guillem@hadrons.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+#ifndef _AIO_TIME_H
+#define _AIO_TIME_H
+
+#include <linux/time_types.h>
+
+#if __BITS_PER_LONG == 32
+# define sys_timespec __kernel_old_timespec
+# define sys_get_timespec(sys_ts, kern_ts) \
+       aio_get_old_timespec(sys_ts, kern_ts)
+#else
+# define sys_timespec __kernel_timespec
+# define sys_get_timespec(sys_ts, kern_ts) *sys_ts = *kern_ts
+#endif
+
+static inline void aio_get_timespec(struct __kernel_timespec *kts,
+               const struct timespec *uts)
+{
+       kts->tv_sec = uts->tv_sec;
+       kts->tv_nsec = uts->tv_nsec;
+}
+
+static inline void aio_get_old_timespec(struct __kernel_old_timespec *ots,
+               const struct __kernel_timespec *kts)
+{
+       ots->tv_sec = kts->tv_sec;
+       ots->tv_nsec = kts->tv_nsec;
+}
+
+int aio_pgetevents(io_context_t ctx, long min_nr, long nr,
+               struct io_event *events, struct __kernel_timespec *timeout,
+               sigset_t *sigmask);
+
+int aio_getevents(io_context_t ctx, long min_nr, long nr,
+               struct io_event * events, struct __kernel_timespec * timeout);
+
+#endif /* _AIO_TIME_H */
index 459586c29244d5c5acc74497fdff7b632dc4be7a..25b789a48a3be5ad3e2fd600351a006b29e69c39 100644 (file)
@@ -3,6 +3,7 @@
    compat-0_1.c : compatibility symbols for libaio 0.1.x-0.3.x
 
    Copyright 2002 Red Hat, Inc.
+   Copyright 2024 Guillem Jover <guillem@hadrons.org>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -22,6 +23,7 @@
 #include <asm/errno.h>
 
 #include "libaio.h"
+#include "aio_time.h"
 
 #include "syscall.h"
 
@@ -38,10 +40,10 @@ SYMVER(compat0_1_io_cancel, io_cancel, 0.1);
 
 int compat0_1_io_queue_wait(io_context_t ctx, struct timespec *when)
 {
-       struct timespec timeout;
+       struct __kernel_timespec timeout;
        if (when)
-               timeout = *when;
-       return io_getevents(ctx, 0, 0, NULL, when ? &timeout : NULL);
+               aio_get_timespec(&timeout, when);
+       return aio_getevents(ctx, 0, 0, NULL, when ? &timeout : NULL);
 }
 SYMVER(compat0_1_io_queue_wait, io_queue_wait, 0.1);
 
@@ -51,10 +53,10 @@ int compat0_1_io_getevents(io_context_t ctx, long nr,
                       struct io_event *events,
                       const struct timespec *const_timeout)
 {
-       struct timespec timeout;
+       struct __kernel_timespec timeout;
        if (const_timeout)
-               timeout = *const_timeout;
-       return io_getevents(ctx, 1, nr, events,
+               aio_get_timespec(&timeout, const_timeout);
+       return aio_getevents(ctx, 1, nr, events,
                        const_timeout ? &timeout : NULL);
 }
 SYMVER(compat0_1_io_getevents, io_getevents, 0.1);
index f39d1af6cdd1c40be1007bf3f6e998834699c9fc..c06e80388717f98abef67548346440f9e8e70d60 100644 (file)
@@ -1,6 +1,7 @@
 /* io_getevents.c
    libaio Linux async I/O interface
    Copyright 2002 Red Hat, Inc.
+   Copyright 2024 Guillem Jover <guillem@hadrons.org>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
 #include <stdlib.h>
 #include <time.h>
 #include "syscall.h"
-#include "aio_ring.h"
-
-io_syscall5(int, __io_getevents_0_4, io_getevents, io_context_t, ctx,
-               long, min_nr, long, nr, struct io_event *, events,
-               struct timespec *, timeout)
+#include "aio_time.h"
 
 int io_getevents_0_4(io_context_t ctx, long min_nr, long nr,
                struct io_event * events, struct timespec * timeout)
 {
-       if (aio_ring_is_empty(ctx, timeout))
-               return 0;
-       return __io_getevents_0_4(ctx, min_nr, nr, events, timeout);
+       struct __kernel_timespec ts;
+
+       if (timeout)
+               aio_get_timespec(&ts, timeout);
+       return aio_getevents(ctx, min_nr, nr, events, timeout ? &ts : NULL);
 }
 
 DEFSYMVER(io_getevents_0_4, io_getevents, 0.4);
index 63ff8066c85990dad159cbee887c7982b5e4b54f..d960a05f134c75cc37e4f653d98a0d9a50602098 100644 (file)
@@ -1,6 +1,7 @@
 /*
    libaio Linux async I/O interface
    Copyright 2018 Christoph Hellwig.
+   Copyright 2024 Guillem Jover <guillem@hadrons.org>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
 #include <stdlib.h>
 #include <time.h>
 #include <signal.h>
-#include "syscall.h"
-#include "aio_ring.h"
-
-#ifdef __NR_io_pgetevents
-io_syscall6(int, __io_pgetevents, io_pgetevents, io_context_t, ctx,
-               long, min_nr, long, nr, struct io_event *, events,
-               struct timespec *, timeout, void *, sigmask);
+#include "aio_time.h"
 
 int io_pgetevents(io_context_t ctx, long min_nr, long nr,
                struct io_event *events, struct timespec *timeout,
                sigset_t *sigmask)
 {
-       struct {
-               unsigned long ss;
-               unsigned long ss_len;
-       } aio_sigset;
-
-       if (aio_ring_is_empty(ctx, timeout))
-               return 0;
-
-       aio_sigset.ss = (unsigned long)sigmask;
-       aio_sigset.ss_len = _NSIG / 8;
-       return __io_pgetevents(ctx, min_nr, nr, events, timeout, &aio_sigset);
-}
-#else
-int io_pgetevents(io_context_t ctx, long min_nr, long nr,
-               struct io_event *events, struct timespec *timeout,
-               sigset_t *sigmask)
+       struct __kernel_timespec ts;
 
-{
-       return -ENOSYS;
+       if (timeout)
+               aio_get_timespec(&ts, timeout);
+       return aio_pgetevents(ctx, min_nr, nr, events, timeout ? &ts : NULL,
+                       sigmask);
 }
-#endif /* __NR_io_pgetevents */
index e0132f4009e827ba59d3b41e94634a93ab354b76..7b5a1bed5cf119abda641dffb16d5d1878332d81 100644 (file)
 #include <errno.h>
 #include <stdlib.h>
 #include <time.h>
+#include "aio_time.h"
 
 int io_queue_run(io_context_t ctx)
 {
-       static struct timespec timeout = { 0, 0 };
+       static struct __kernel_timespec timeout = { 0, 0 };
        struct io_event event;
        int ret;
 
        /* FIXME: batch requests? */
-       while (1 == (ret = io_getevents(ctx, 0, 1, &event, &timeout))) {
+       while (1 == (ret = aio_getevents(ctx, 0, 1, &event, &timeout))) {
                io_callback_t cb = (io_callback_t)event.data;
                struct iocb *iocb = event.obj;
 
index 6f69a51f5f72b6e38c0df8ede5687f0d98966caf..b4bb23622cd3f5213e8d81840defb522eb4875ef 100644 (file)
@@ -1,6 +1,7 @@
 /* io_submit
    libaio Linux async I/O interface
    Copyright 2002 Red Hat, Inc.
+   Copyright 2024 Guillem Jover <guillem@hadrons.org>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
 #include <sys/types.h>
 #include <libaio.h>
 #include <errno.h>
+#include "aio_time.h"
 #include "syscall.h"
 
 struct timespec;
 
 int io_queue_wait_0_4(io_context_t ctx, struct timespec *timeout)
 {
-       return io_getevents(ctx, 0, 0, NULL, timeout);
+       struct __kernel_timespec ts;
+
+       if (timeout)
+               aio_get_timespec(&ts, timeout);
+       return aio_getevents(ctx, 0, 0, NULL, timeout ? &ts : NULL);
 }
 DEFSYMVER(io_queue_wait_0_4, io_queue_wait, 0.4);