Re: [PATCH libaio v2 10/10] Add time64 public functions on 32-bit architectures

Guillem Jover <[email protected]>
Newsgroups gmane.linux.kernel.aio.general
Message-ID <[email protected]>
Hi!

On Wed, 2024-06-05 at 09:01:27 +0000, Guillem Jover wrote:
> From: Guillem Jover <[email protected]>
> 
> This adds new time64 functions for io_getevents() and io_pgetevents()
> that will get redirected when building with _TIME_BITS=64.
> 
> Ideally we should generate the .map file and not include these symbols
> on 64-bit architectures, but this will do for now.
> 
> Signed-off-by: Guillem Jover <[email protected]>

[…]
> diff --git a/src/io_getevents.c b/src/io_getevents_time64.c
> similarity index 80%
> copy from src/io_getevents.c
> copy to src/io_getevents_time64.c
> index c06e803..942743d 100644
> --- a/src/io_getevents.c
> +++ b/src/io_getevents_time64.c
> @@ -1,4 +1,4 @@
> -/* io_getevents.c
> +/* io_getevents_time64.c
>     libaio Linux async I/O interface
>     Copyright 2002 Red Hat, Inc.
>     Copyright 2024 Guillem Jover <[email protected]>
> @@ -24,14 +24,14 @@
>  #include "syscall.h"
>  #include "aio_time.h"
>  
> -int io_getevents_0_4(io_context_t ctx, long min_nr, long nr,
> +#if __BITS_PER_LONG == 32
> +int io_getevents_time64(io_context_t ctx, long min_nr, long nr,
>  		struct io_event * events, struct timespec * timeout)
>  {
> -	struct __kernel_timespec ts;
> +	struct __kernel_timespec kts;
>  
>  	if (timeout)
> -		aio_get_timespec(&ts, timeout);
> -	return aio_getevents(ctx, min_nr, nr, events, timeout ? &ts : NULL);
> +		aio_get_timespec(&kts, timeout);
> +	return aio_getevents(ctx, min_nr, nr, events, timeout ? &kts : NULL);
>  }
> -
> -DEFSYMVER(io_getevents_0_4, io_getevents, 0.4);
> +#endif


> diff --git a/src/io_pgetevents.c b/src/io_pgetevents_time64.c
> similarity index 82%
> copy from src/io_pgetevents.c
> copy to src/io_pgetevents_time64.c
> index d960a05..55e4ad1 100644
> --- a/src/io_pgetevents.c
> +++ b/src/io_pgetevents_time64.c
> @@ -24,14 +24,16 @@
>  #include <signal.h>
>  #include "aio_time.h"
>  
> -int io_pgetevents(io_context_t ctx, long min_nr, long nr,
> +#if __BITS_PER_LONG == 32
> +int io_pgetevents_time64(io_context_t ctx, long min_nr, long nr,
>  		struct io_event *events, struct timespec *timeout,
>  		sigset_t *sigmask)
>  {
> -	struct __kernel_timespec ts;
> +	struct __kernel_timespec kts;
>  
>  	if (timeout)
> -		aio_get_timespec(&ts, timeout);
> -	return aio_pgetevents(ctx, min_nr, nr, events, timeout ? &ts : NULL,
> +		aio_get_timespec(&kts, timeout);
> +	return aio_pgetevents(ctx, min_nr, nr, events, timeout ? &kts : NULL,
>  			sigmask);
>  }
> +#endif

As I mentioned to Jeff off-list, these variable renames should be done
in the earlier patch introducing these functions, as this is an
unnecessary diff. I've got this changed locally, but I didn't reroll
another version to avoid spamming the list (I'm attaching the two
modified patches for now, will be included in the next version after
the review).

Thanks,
Guillem
0001-Add-time64-syscall-support.patch (text/x-diff, 13.8 KB)
From 0e9857170c3d63c2c6e5f23b4f9a1ab3a43c7d19 Mon Sep 17 00:00:00 2001
From: Guillem Jover <[email protected]>
Date: Fri, 1 Mar 2024 01:52:51 +0100
Subject: [PATCH libaio] Add time64 syscall support

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 <[email protected]>
---
 src/Makefile                              |  1 +
 src/{io_getevents.c => aio_getevents.c}   | 26 +++++++----
 src/{io_pgetevents.c => aio_pgetevents.c} | 50 ++++++++++++++++-----
 src/aio_ring.h                            |  3 +-
 src/aio_time.h                            | 54 +++++++++++++++++++++++
 src/compat-0_1.c                          | 14 +++---
 src/io_getevents.c                        | 15 +++----
 src/io_pgetevents.c                       | 33 +++-----------
 src/io_queue_run.c                        |  5 ++-
 src/io_queue_wait.c                       |  8 +++-
 10 files changed, 146 insertions(+), 63 deletions(-)
 copy src/{io_getevents.c => aio_getevents.c} (64%)
 copy src/{io_pgetevents.c => aio_pgetevents.c} (53%)
 create mode 100644 src/aio_time.h

diff --git a/src/Makefile b/src/Makefile
index 803760d..7e56172 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -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/io_getevents.c b/src/aio_getevents.c
similarity index 64%
copy from src/io_getevents.c
copy to src/aio_getevents.c
index f39d1af..53104d5 100644
--- a/src/io_getevents.c
+++ b/src/aio_getevents.c
@@ -1,6 +1,7 @@
-/* io_getevents.c
+/* aio_getevents.c
    libaio Linux async I/O interface
    Copyright 2002 Red Hat, Inc.
+   Copyright 2024 Guillem Jover <[email protected]>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -21,18 +22,27 @@
 #include <stdlib.h>
 #include <time.h>
 #include "syscall.h"
+#include "aio_time.h"
 #include "aio_ring.h"
 
-io_syscall5(int, __io_getevents_0_4, io_getevents, io_context_t, ctx,
+io_syscall5(int, __aio_getevents, io_getevents, io_context_t, ctx,
 		long, min_nr, long, nr, struct io_event *, events,
-		struct timespec *, timeout)
+		struct sys_timespec *, timeout)
 
-int io_getevents_0_4(io_context_t ctx, long min_nr, long nr,
-		struct io_event * events, struct 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 sts;
+	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;
-	return __io_getevents_0_4(ctx, min_nr, nr, events, timeout);
-}
 
-DEFSYMVER(io_getevents_0_4, io_getevents, 0.4);
+	if (timeout)
+		sys_get_timespec(&sts, timeout);
+	return __aio_getevents(ctx, min_nr, nr, events, timeout ? &sts : NULL);
+}
diff --git a/src/io_pgetevents.c b/src/aio_pgetevents.c
similarity index 53%
copy from src/io_pgetevents.c
copy to src/aio_pgetevents.c
index 63ff806..69704d0 100644
--- a/src/io_pgetevents.c
+++ b/src/aio_pgetevents.c
@@ -1,6 +1,7 @@
 /*
    libaio Linux async I/O interface
    Copyright 2018 Christoph Hellwig.
+   Copyright 2024 Guillem Jover <[email protected]>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -22,35 +23,62 @@
 #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 timespec *, timeout, void *, sigmask);
+		struct sys_timespec *, timeout, void *, sigmask);
+#endif
 
-int io_pgetevents(io_context_t ctx, long min_nr, long nr,
-		struct io_event *events, struct timespec *timeout,
+#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 sts;
 
 	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);
-}
+#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(&sts, timeout);
+
+	ret = __io_pgetevents(ctx, min_nr, nr, events,
+			timeout ? &sts : NULL, &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)
+	ret = -ENOSYS;
+#endif
 
-{
-	return -ENOSYS;
+	return ret;
 }
-#endif /* __NR_io_pgetevents */
diff --git a/src/aio_ring.h b/src/aio_ring.h
index 3842c4b..17fe838 100644
--- a/src/aio_ring.h
+++ b/src/aio_ring.h
@@ -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
index 0000000..373a1b0
--- /dev/null
+++ b/src/aio_time.h
@@ -0,0 +1,54 @@
+/*
+   libaio Linux async I/O interface
+   Copyright 2024 Guillem Jover <[email protected]>
+
+   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 */
diff --git a/src/compat-0_1.c b/src/compat-0_1.c
index 459586c..25b789a 100644
--- a/src/compat-0_1.c
+++ b/src/compat-0_1.c
@@ -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 <[email protected]>
 
    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);
diff --git a/src/io_getevents.c b/src/io_getevents.c
index f39d1af..f3eaaed 100644
--- a/src/io_getevents.c
+++ b/src/io_getevents.c
@@ -1,6 +1,7 @@
 /* io_getevents.c
    libaio Linux async I/O interface
    Copyright 2002 Red Hat, Inc.
+   Copyright 2024 Guillem Jover <[email protected]>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -21,18 +22,16 @@
 #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 kts;
+
+	if (timeout)
+		aio_get_timespec(&kts, timeout);
+	return aio_getevents(ctx, min_nr, nr, events, timeout ? &kts : NULL);
 }
 
 DEFSYMVER(io_getevents_0_4, io_getevents, 0.4);
diff --git a/src/io_pgetevents.c b/src/io_pgetevents.c
index 63ff806..ca821a9 100644
--- a/src/io_pgetevents.c
+++ b/src/io_pgetevents.c
@@ -1,6 +1,7 @@
 /*
    libaio Linux async I/O interface
    Copyright 2018 Christoph Hellwig.
+   Copyright 2024 Guillem Jover <[email protected]>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -21,36 +22,16 @@
 #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 kts;
 
-{
-	return -ENOSYS;
+	if (timeout)
+		aio_get_timespec(&kts, timeout);
+	return aio_pgetevents(ctx, min_nr, nr, events, timeout ? &kts : NULL,
+			sigmask);
 }
-#endif /* __NR_io_pgetevents */
diff --git a/src/io_queue_run.c b/src/io_queue_run.c
index e0132f4..7b5a1be 100644
--- a/src/io_queue_run.c
+++ b/src/io_queue_run.c
@@ -20,15 +20,16 @@
 #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;
 
diff --git a/src/io_queue_wait.c b/src/io_queue_wait.c
index 6f69a51..e4e223c 100644
--- a/src/io_queue_wait.c
+++ b/src/io_queue_wait.c
@@ -1,6 +1,7 @@
 /* io_submit
    libaio Linux async I/O interface
    Copyright 2002 Red Hat, Inc.
+   Copyright 2024 Guillem Jover <[email protected]>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -20,12 +21,17 @@
 #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 kts;
+
+	if (timeout)
+		aio_get_timespec(&kts, timeout);
+	return aio_getevents(ctx, 0, 0, NULL, timeout ? &kts : NULL);
 }
 DEFSYMVER(io_queue_wait_0_4, io_queue_wait, 0.4);
-- 
2.45.1
0001-Add-time64-public-functions-on-32-bit-architectures.patch (text/x-diff, 7.8 KB)
From 24889e280f9ed09f91e9bd6a7802ef0dc8844d46 Mon Sep 17 00:00:00 2001
From: Guillem Jover <[email protected]>
Date: Fri, 1 Mar 2024 01:52:51 +0100
Subject: [PATCH libaio] Add time64 public functions on 32-bit architectures

This adds new time64 functions for io_getevents() and io_pgetevents()
that will get redirected when building with _TIME_BITS=64.

Ideally we should generate the .map file and not include these symbols
on 64-bit architectures, but this will do for now.

Signed-off-by: Guillem Jover <[email protected]>
---
 harness/Makefile                               |  2 +-
 src/Makefile                                   |  3 ++-
 src/compat-0_1.c                               |  7 +++++++
 src/io_getevents.c                             |  7 +++++++
 src/{io_getevents.c => io_getevents_time64.c}  |  8 ++++----
 src/io_pgetevents.c                            |  7 +++++++
 ...{io_pgetevents.c => io_pgetevents_time64.c} |  4 +++-
 src/io_queue_wait.c                            |  7 +++++++
 src/libaio.h                                   | 18 ++++++++++++++++++
 src/libaio.map                                 |  6 ++++++
 10 files changed, 62 insertions(+), 7 deletions(-)
 copy src/{io_getevents.c => io_getevents_time64.c} (90%)
 copy src/{io_pgetevents.c => io_pgetevents_time64.c} (92%)

diff --git a/harness/Makefile b/harness/Makefile
index 4f225d3..470d46e 100644
--- a/harness/Makefile
+++ b/harness/Makefile
@@ -6,7 +6,7 @@ PROGS:=$(PARTPROGS) $(EXTRAPROGS)
 HARNESS_SRCS:=main.c
 # io_queue.c
 
-CFLAGS+=-Wall -Werror -I../src -g -O2
+CFLAGS+=-Wall -Werror -I../src -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 -g -O2
 #-lpthread -lrt
 
 # gcc-11 does not like the test case in 3.t that
diff --git a/src/Makefile b/src/Makefile
index 7e56172..13618a6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -3,7 +3,7 @@ includedir=$(prefix)/include
 libdir=$(prefix)/lib
 
 CFLAGS ?= -g -fomit-frame-pointer -O2
-CFLAGS += -Wall -I. -fPIC
+CFLAGS += -Wall -I. -fPIC -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
 SO_CFLAGS=-shared $(CFLAGS)
 L_CFLAGS=$(CFLAGS)
 LINK_FLAGS=
@@ -30,6 +30,7 @@ libaio_srcs += io_queue_wait.c io_queue_run.c
 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
+libaio_srcs += io_pgetevents_time64.c io_getevents_time64.c
 
 # old symbols
 libaio_srcs += compat-0_1.c
diff --git a/src/compat-0_1.c b/src/compat-0_1.c
index 25b789a..61df3b3 100644
--- a/src/compat-0_1.c
+++ b/src/compat-0_1.c
@@ -19,6 +19,13 @@
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
  */
+
+/*
+ * On 32-bit systems these were using 32-bit struct timespec, keep these
+ * backward compatibility functions that way.
+ */
+#undef _TIME_BITS
+
 #include <stdlib.h>
 #include <asm/errno.h>
 
diff --git a/src/io_getevents.c b/src/io_getevents.c
index f3eaaed..88a95dc 100644
--- a/src/io_getevents.c
+++ b/src/io_getevents.c
@@ -17,6 +17,13 @@
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
  */
+
+/*
+ * On 32-bit systems these were using 32-bit struct timespec, keep this
+ * backward compatibility function that way.
+ */
+#undef _TIME_BITS
+
 #include <libaio.h>
 #include <errno.h>
 #include <stdlib.h>
diff --git a/src/io_getevents.c b/src/io_getevents_time64.c
similarity index 90%
copy from src/io_getevents.c
copy to src/io_getevents_time64.c
index f3eaaed..942743d 100644
--- a/src/io_getevents.c
+++ b/src/io_getevents_time64.c
@@ -1,4 +1,4 @@
-/* io_getevents.c
+/* io_getevents_time64.c
    libaio Linux async I/O interface
    Copyright 2002 Red Hat, Inc.
    Copyright 2024 Guillem Jover <[email protected]>
@@ -24,7 +24,8 @@
 #include "syscall.h"
 #include "aio_time.h"
 
-int io_getevents_0_4(io_context_t ctx, long min_nr, long nr,
+#if __BITS_PER_LONG == 32
+int io_getevents_time64(io_context_t ctx, long min_nr, long nr,
 		struct io_event * events, struct timespec * timeout)
 {
 	struct __kernel_timespec kts;
@@ -33,5 +34,4 @@ int io_getevents_0_4(io_context_t ctx, long min_nr, long nr,
 		aio_get_timespec(&kts, timeout);
 	return aio_getevents(ctx, min_nr, nr, events, timeout ? &kts : NULL);
 }
-
-DEFSYMVER(io_getevents_0_4, io_getevents, 0.4);
+#endif
diff --git a/src/io_pgetevents.c b/src/io_pgetevents.c
index ca821a9..2d98e90 100644
--- a/src/io_pgetevents.c
+++ b/src/io_pgetevents.c
@@ -17,6 +17,13 @@
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
  */
+
+/*
+ * On 32-bit systems these were using 32-bit struct timespec, keep this
+ * backward compatibility function that way.
+ */
+#undef _TIME_BITS
+
 #include <libaio.h>
 #include <errno.h>
 #include <stdlib.h>
diff --git a/src/io_pgetevents.c b/src/io_pgetevents_time64.c
similarity index 92%
copy from src/io_pgetevents.c
copy to src/io_pgetevents_time64.c
index ca821a9..55e4ad1 100644
--- a/src/io_pgetevents.c
+++ b/src/io_pgetevents_time64.c
@@ -24,7 +24,8 @@
 #include <signal.h>
 #include "aio_time.h"
 
-int io_pgetevents(io_context_t ctx, long min_nr, long nr,
+#if __BITS_PER_LONG == 32
+int io_pgetevents_time64(io_context_t ctx, long min_nr, long nr,
 		struct io_event *events, struct timespec *timeout,
 		sigset_t *sigmask)
 {
@@ -35,3 +36,4 @@ int io_pgetevents(io_context_t ctx, long min_nr, long nr,
 	return aio_pgetevents(ctx, min_nr, nr, events, timeout ? &kts : NULL,
 			sigmask);
 }
+#endif
diff --git a/src/io_queue_wait.c b/src/io_queue_wait.c
index e4e223c..e61b208 100644
--- a/src/io_queue_wait.c
+++ b/src/io_queue_wait.c
@@ -17,6 +17,13 @@
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
  */
+
+/*
+ * On 32-bit systems these were using 32-bit struct timespec, keep this
+ * backward compatibility function that way.
+ */
+#undef _TIME_BITS
+
 #define NO_SYSCALL_ERRNO
 #include <sys/types.h>
 #include <libaio.h>
diff --git a/src/libaio.h b/src/libaio.h
index f247c96..8198047 100644
--- a/src/libaio.h
+++ b/src/libaio.h
@@ -27,6 +27,7 @@
 extern "C" {
 #endif
 
+#include <linux/types.h>
 #include <sys/types.h>
 #include <string.h>
 #include <signal.h>
@@ -50,6 +51,12 @@ typedef enum io_iocb_cmd {
 	IO_CMD_PWRITEV = 8,
 } io_iocb_cmd_t;
 
+#define LIBAIO_STRING(x) #x
+
+#define LIBAIO_REDIRECT(name, proto, alias) name proto __asm__(LIBAIO_ASMNAME(#alias))
+#define LIBAIO_ASMNAME(cname) LIBAIO_ASMNAME_PREFIX(__USER_LABEL_PREFIX__, cname)
+#define LIBAIO_ASMNAME_PREFIX(prefix, cname) LIBAIO_STRING(prefix) cname
+
 /* little endian, 32 bits */
 #if defined(__i386__) || (defined(__arm__) && !defined(__ARMEB__)) || \
     defined(__sh__) || defined(__bfin__) || defined(__MIPSEL__) || \
@@ -170,6 +177,17 @@ extern int io_getevents(io_context_t ctx, long min_nr, long nr,
 extern int io_pgetevents(io_context_t ctx, long min_nr, long nr,
 		struct io_event *events, struct timespec *timeout,
 		sigset_t *sigmask);
+#if __BITS_PER_LONG == 32 && defined(_TIME_BITS) && _TIME_BITS == 64
+extern int LIBAIO_REDIRECT(io_getevents, (io_context_t ctx,
+		long min_nr, long nr,
+		struct io_event *events, struct timespec *timeout),
+		io_getevents_time64);
+extern int LIBAIO_REDIRECT(io_pgetevents, (io_context_t ctx,
+		long min_nr, long nr,
+		struct io_event *events, struct timespec *timeout,
+		sigset_t *sigmask),
+		io_pgetevents_time64);
+#endif
 
 
 static inline void io_set_callback(struct iocb *iocb, io_callback_t cb)
diff --git a/src/libaio.map b/src/libaio.map
index ec9d13b..74b2c08 100644
--- a/src/libaio.map
+++ b/src/libaio.map
@@ -25,3 +25,9 @@ LIBAIO_0.5 {
 	global:
 		io_pgetevents;
 } LIBAIO_0.4;
+
+LIBAIO_0.6 {
+	global:
+		io_getevents_time64;
+		io_pgetevents_time64;
+} LIBAIO_0.5;
-- 
2.45.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.