* [LTP] [PATCH v2 0/2] epoll_pwait2() timeout regression test
@ 2025-06-03 15:22 Martin Doucha
2025-06-03 15:22 ` [LTP] [PATCH v2 1/2] epoll_pwait: Refactor timeout to struct timespec Martin Doucha
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Martin Doucha @ 2025-06-03 15:22 UTC (permalink / raw)
To: ltp
There seems to be a regression in kernel v6.14 where epoll_pwait2()
interprets very small timeout values (~1000ns) as infinity and waits
for events forever. This patchset adds regression test for this bug
and a necessary refactor for do_epoll_pwait() to allow high precision
timeouts.
Martin Doucha (2):
epoll_pwait: Refactor timeout to struct timespec
Add regression test for epoll_pwait2() timeout
runtest/syscalls | 1 +
.../kernel/syscalls/epoll_pwait/.gitignore | 1 +
.../syscalls/epoll_pwait/epoll_pwait01.c | 4 +-
.../syscalls/epoll_pwait/epoll_pwait02.c | 2 +-
.../syscalls/epoll_pwait/epoll_pwait03.c | 9 +-
.../syscalls/epoll_pwait/epoll_pwait04.c | 2 +-
.../syscalls/epoll_pwait/epoll_pwait06.c | 87 +++++++++++++++++++
.../syscalls/epoll_pwait/epoll_pwait_var.h | 22 ++---
8 files changed, 110 insertions(+), 18 deletions(-)
create mode 100644 testcases/kernel/syscalls/epoll_pwait/epoll_pwait06.c
--
2.49.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 10+ messages in thread* [LTP] [PATCH v2 1/2] epoll_pwait: Refactor timeout to struct timespec 2025-06-03 15:22 [LTP] [PATCH v2 0/2] epoll_pwait2() timeout regression test Martin Doucha @ 2025-06-03 15:22 ` Martin Doucha 2025-06-04 6:35 ` Petr Vorel 2025-06-04 7:01 ` Andrea Cervesato via ltp 2025-06-03 15:22 ` [LTP] [PATCH v2 2/2] Add regression test for epoll_pwait2() timeout Martin Doucha 2025-06-04 7:34 ` [LTP] [PATCH v2 0/2] epoll_pwait2() timeout regression test Petr Vorel 2 siblings, 2 replies; 10+ messages in thread From: Martin Doucha @ 2025-06-03 15:22 UTC (permalink / raw) To: ltp Support higher precision timeout in do_epoll_pwait() by passing struct timespec instead of int value in milliseconds. Only one test actually uses the parameter. Signed-off-by: Martin Doucha <mdoucha@suse.cz> --- Changes since v1: None .../syscalls/epoll_pwait/epoll_pwait01.c | 4 ++-- .../syscalls/epoll_pwait/epoll_pwait02.c | 2 +- .../syscalls/epoll_pwait/epoll_pwait03.c | 9 +++++--- .../syscalls/epoll_pwait/epoll_pwait04.c | 2 +- .../syscalls/epoll_pwait/epoll_pwait_var.h | 22 +++++++++---------- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait01.c b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait01.c index 954e77314..012ba1562 100644 --- a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait01.c +++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait01.c @@ -30,7 +30,7 @@ static void sighandler(int sig LTP_ATTRIBUTE_UNUSED) {} static void verify_sigmask(void) { - TEST(do_epoll_pwait(efd, &e, 1, -1, &signalset)); + TEST(do_epoll_pwait(efd, &e, 1, NULL, &signalset)); if (TST_RET != 1) { tst_res(TFAIL, "do_epoll_pwait() returned %li, expected 1", @@ -43,7 +43,7 @@ static void verify_sigmask(void) static void verify_nonsigmask(void) { - TST_EXP_FAIL(do_epoll_pwait(efd, &e, 1, -1, NULL), EINTR, + TST_EXP_FAIL(do_epoll_pwait(efd, &e, 1, NULL, NULL), EINTR, "do_epoll_pwait() without sigmask"); } diff --git a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait02.c b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait02.c index 069620c5d..a27c7db9e 100644 --- a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait02.c +++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait02.c @@ -19,7 +19,7 @@ static struct epoll_event e; static void run(void) { - TEST(do_epoll_pwait(efd, &e, 1, -1, NULL)); + TEST(do_epoll_pwait(efd, &e, 1, NULL, NULL)); if (TST_RET == 1) { tst_res(TPASS, "do_epoll_pwait() succeeded"); diff --git a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait03.c b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait03.c index 8217f9f80..572d347f1 100644 --- a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait03.c +++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait03.c @@ -13,17 +13,20 @@ #include "tst_timer_test.h" #include "epoll_pwait_var.h" -#define USEC_PER_MSEC (1000L) +#define USEC_PER_NSEC (1000L) +#define USEC_PER_SEC (1000000L) static int efd, sfd[2]; static struct epoll_event e; int sample_fn(int clk_id, long long usec) { - unsigned int ms = usec / USEC_PER_MSEC; + struct timespec ts; + ts.tv_sec = usec / USEC_PER_SEC; + ts.tv_nsec = (usec % USEC_PER_SEC) * USEC_PER_NSEC; tst_timer_start(clk_id); - TEST(do_epoll_pwait(efd, &e, 1, ms, NULL)); + TEST(do_epoll_pwait(efd, &e, 1, &ts, NULL)); tst_timer_stop(); tst_timer_sample(); diff --git a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait04.c b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait04.c index cc1d04e6b..b399225b9 100644 --- a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait04.c +++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait04.c @@ -20,7 +20,7 @@ static void *bad_addr; static void run(void) { - TST_EXP_FAIL(do_epoll_pwait(efd, &e, 1, -1, bad_addr), + TST_EXP_FAIL(do_epoll_pwait(efd, &e, 1, NULL, bad_addr), EFAULT, "with an invalid sigmask pointer"); } diff --git a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait_var.h b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait_var.h index 58a3f15a2..454e80a87 100644 --- a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait_var.h +++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait_var.h @@ -14,22 +14,22 @@ #define NSEC_PER_MSEC (1000000L) static int do_epoll_pwait(int epfd, struct epoll_event *events, int - maxevents, int timeout, const sigset_t *sigmask) + maxevents, struct timespec *timeout, const sigset_t *sigmask) { - if (tst_variant == 0) - return epoll_pwait(epfd, events, maxevents, timeout, sigmask); + if (tst_variant == 0) { + int timeout_ms = -1; - struct timespec ts; + if (timeout) { + timeout_ms = timeout->tv_sec * MSEC_PER_SEC; + timeout_ms += (timeout->tv_nsec + NSEC_PER_MSEC - 1) / + NSEC_PER_MSEC; + } - if (timeout < 0) { - return epoll_pwait2(epfd, events, maxevents, NULL, sigmask); - } else { - ts.tv_sec = timeout / MSEC_PER_SEC; - ts.tv_nsec = NSEC_PER_MSEC * (timeout % MSEC_PER_SEC); + return epoll_pwait(epfd, events, maxevents, timeout_ms, + sigmask); } - return epoll_pwait2(epfd, events, maxevents, &ts, sigmask); - + return epoll_pwait2(epfd, events, maxevents, timeout, sigmask); } static void epoll_pwait_init(void) -- 2.49.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [LTP] [PATCH v2 1/2] epoll_pwait: Refactor timeout to struct timespec 2025-06-03 15:22 ` [LTP] [PATCH v2 1/2] epoll_pwait: Refactor timeout to struct timespec Martin Doucha @ 2025-06-04 6:35 ` Petr Vorel 2025-06-04 12:10 ` Martin Doucha 2025-06-04 7:01 ` Andrea Cervesato via ltp 1 sibling, 1 reply; 10+ messages in thread From: Petr Vorel @ 2025-06-04 6:35 UTC (permalink / raw) To: Martin Doucha; +Cc: ltp Hi Martin, > Support higher precision timeout in do_epoll_pwait() by passing struct > timespec instead of int value in milliseconds. Only one test actually > uses the parameter. Ah, you mean epoll_pwait03.c. Reviewed-by: Petr Vorel <pvorel@suse.cz> ... > +++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait_var.h > @@ -14,22 +14,22 @@ > #define NSEC_PER_MSEC (1000000L) > static int do_epoll_pwait(int epfd, struct epoll_event *events, int > - maxevents, int timeout, const sigset_t *sigmask) > + maxevents, struct timespec *timeout, const sigset_t *sigmask) > { > - if (tst_variant == 0) > - return epoll_pwait(epfd, events, maxevents, timeout, sigmask); > + if (tst_variant == 0) { > + int timeout_ms = -1; very nit: I would reverse the condition to save indent for tst_variant == 0: if (tst_variant != 0) return epoll_pwait2(epfd, events, maxevents, timeout, sigmask); ... Kind regards, Petr > - struct timespec ts; > + if (timeout) { > + timeout_ms = timeout->tv_sec * MSEC_PER_SEC; > + timeout_ms += (timeout->tv_nsec + NSEC_PER_MSEC - 1) / > + NSEC_PER_MSEC; > + } > - if (timeout < 0) { > - return epoll_pwait2(epfd, events, maxevents, NULL, sigmask); > - } else { > - ts.tv_sec = timeout / MSEC_PER_SEC; > - ts.tv_nsec = NSEC_PER_MSEC * (timeout % MSEC_PER_SEC); > + return epoll_pwait(epfd, events, maxevents, timeout_ms, > + sigmask); > } > - return epoll_pwait2(epfd, events, maxevents, &ts, sigmask); > - > + return epoll_pwait2(epfd, events, maxevents, timeout, sigmask); > } > static void epoll_pwait_init(void) -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [LTP] [PATCH v2 1/2] epoll_pwait: Refactor timeout to struct timespec 2025-06-04 6:35 ` Petr Vorel @ 2025-06-04 12:10 ` Martin Doucha 2025-06-05 6:28 ` Petr Vorel 0 siblings, 1 reply; 10+ messages in thread From: Martin Doucha @ 2025-06-04 12:10 UTC (permalink / raw) To: Petr Vorel; +Cc: ltp Hi! On 04. 06. 25 8:35, Petr Vorel wrote: > Hi Martin, > >> Support higher precision timeout in do_epoll_pwait() by passing struct >> timespec instead of int value in milliseconds. Only one test actually >> uses the parameter. > > Ah, you mean epoll_pwait03.c. Yes. > Reviewed-by: Petr Vorel <pvorel@suse.cz> > > ... >> +++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait_var.h >> @@ -14,22 +14,22 @@ >> #define NSEC_PER_MSEC (1000000L) > >> static int do_epoll_pwait(int epfd, struct epoll_event *events, int >> - maxevents, int timeout, const sigset_t *sigmask) >> + maxevents, struct timespec *timeout, const sigset_t *sigmask) >> { >> - if (tst_variant == 0) >> - return epoll_pwait(epfd, events, maxevents, timeout, sigmask); >> + if (tst_variant == 0) { >> + int timeout_ms = -1; > > very nit: I would reverse the condition to save indent for tst_variant == 0: Feel free to do it during merge, but it'd be better to check (tst_variant == 1) instead in case there will be epoll_pwait3() in the future. > > if (tst_variant != 0) > return epoll_pwait2(epfd, events, maxevents, timeout, sigmask); > ... -- Martin Doucha mdoucha@suse.cz SW Quality Engineer SUSE LINUX, s.r.o. CORSO IIa Krizikova 148/34 186 00 Prague 8 Czech Republic -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [LTP] [PATCH v2 1/2] epoll_pwait: Refactor timeout to struct timespec 2025-06-04 12:10 ` Martin Doucha @ 2025-06-05 6:28 ` Petr Vorel 0 siblings, 0 replies; 10+ messages in thread From: Petr Vorel @ 2025-06-05 6:28 UTC (permalink / raw) To: Martin Doucha; +Cc: ltp Hi Martin, ... > > > +++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait_var.h > > > @@ -14,22 +14,22 @@ > > > #define NSEC_PER_MSEC (1000000L) > > > static int do_epoll_pwait(int epfd, struct epoll_event *events, int > > > - maxevents, int timeout, const sigset_t *sigmask) > > > + maxevents, struct timespec *timeout, const sigset_t *sigmask) > > > { > > > - if (tst_variant == 0) > > > - return epoll_pwait(epfd, events, maxevents, timeout, sigmask); > > > + if (tst_variant == 0) { > > > + int timeout_ms = -1; > > very nit: I would reverse the condition to save indent for tst_variant == 0: > Feel free to do it during merge, but it'd be better to check (tst_variant == > 1) instead in case there will be epoll_pwait3() in the future. Thanks for your ack + good point, changed as tst_variant == 1. Patchset merged, thanks! Kind regards, Petr -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [LTP] [PATCH v2 1/2] epoll_pwait: Refactor timeout to struct timespec 2025-06-03 15:22 ` [LTP] [PATCH v2 1/2] epoll_pwait: Refactor timeout to struct timespec Martin Doucha 2025-06-04 6:35 ` Petr Vorel @ 2025-06-04 7:01 ` Andrea Cervesato via ltp 1 sibling, 0 replies; 10+ messages in thread From: Andrea Cervesato via ltp @ 2025-06-04 7:01 UTC (permalink / raw) To: Martin Doucha, ltp Reviewed-by: Andrea Cervesato <andrea.cevesato@suse.com> -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 10+ messages in thread
* [LTP] [PATCH v2 2/2] Add regression test for epoll_pwait2() timeout 2025-06-03 15:22 [LTP] [PATCH v2 0/2] epoll_pwait2() timeout regression test Martin Doucha 2025-06-03 15:22 ` [LTP] [PATCH v2 1/2] epoll_pwait: Refactor timeout to struct timespec Martin Doucha @ 2025-06-03 15:22 ` Martin Doucha 2025-06-04 7:01 ` Andrea Cervesato via ltp 2025-06-04 7:29 ` Petr Vorel 2025-06-04 7:34 ` [LTP] [PATCH v2 0/2] epoll_pwait2() timeout regression test Petr Vorel 2 siblings, 2 replies; 10+ messages in thread From: Martin Doucha @ 2025-06-03 15:22 UTC (permalink / raw) To: ltp Signed-off-by: Martin Doucha <mdoucha@suse.cz> --- Changes since v1: - Added kernel fix reference - Use SAFE_EPOLL_*() functions runtest/syscalls | 1 + .../kernel/syscalls/epoll_pwait/.gitignore | 1 + .../syscalls/epoll_pwait/epoll_pwait06.c | 87 +++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 testcases/kernel/syscalls/epoll_pwait/epoll_pwait06.c diff --git a/runtest/syscalls b/runtest/syscalls index e7bc7b27b..2a968099a 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -192,6 +192,7 @@ epoll_pwait02 epoll_pwait02 epoll_pwait03 epoll_pwait03 epoll_pwait04 epoll_pwait04 epoll_pwait05 epoll_pwait05 +epoll_pwait06 epoll_pwait06 eventfd01 eventfd01 eventfd02 eventfd02 diff --git a/testcases/kernel/syscalls/epoll_pwait/.gitignore b/testcases/kernel/syscalls/epoll_pwait/.gitignore index fafb2d782..81e77b8d0 100644 --- a/testcases/kernel/syscalls/epoll_pwait/.gitignore +++ b/testcases/kernel/syscalls/epoll_pwait/.gitignore @@ -3,3 +3,4 @@ epoll_pwait02 epoll_pwait03 epoll_pwait04 epoll_pwait05 +epoll_pwait06 diff --git a/testcases/kernel/syscalls/epoll_pwait/epoll_pwait06.c b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait06.c new file mode 100644 index 000000000..3bedc2cf5 --- /dev/null +++ b/testcases/kernel/syscalls/epoll_pwait/epoll_pwait06.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2025 SUSE LLC <mdoucha@suse.cz> + */ + +/*\ + * Verify that various timeout values don't get misinterpreted as infinity + * by epoll_pwait() and epoll_pwait2(). Regression fixed in: + * + * commit d9ec73301099ec5975505e1c3effbe768bab9490 + * Author: Max Kellermann <max.kellermann@ionos.com> + * Date: Tue Apr 29 20:58:27 2025 +0200 + * + * fs/eventpoll: fix endless busy loop after timeout has expired + */ + +#include "tst_test.h" +#include "tst_timer.h" +#include "tst_epoll.h" +#include "epoll_pwait_var.h" + +static int efd = -1; + +static void run(void) +{ + struct timespec timeout = {}; + struct epoll_event e = {}; + + e.events = EPOLLIN; + + TST_FD_FOREACH(fd_in) { + /* File descriptor types not supported by epoll */ + switch (fd_in.type) { + case TST_FD_FILE: + case TST_FD_PATH: + case TST_FD_DIR: + case TST_FD_DEV_ZERO: + case TST_FD_PROC_MAPS: + case TST_FD_FSOPEN: + case TST_FD_FSPICK: + case TST_FD_OPEN_TREE: + case TST_FD_MEMFD: + case TST_FD_MEMFD_SECRET: + continue; + default: + break; + } + + tst_res(TINFO, "Testing %s", tst_fd_desc(&fd_in)); + timeout.tv_nsec = 1000000000; + SAFE_EPOLL_CTL(efd, EPOLL_CTL_ADD, fd_in.fd, &e); + + do { + alarm(1); + timeout.tv_nsec /= 10; + do_epoll_pwait(efd, &e, 1, &timeout, NULL); + alarm(0); + } while (timeout.tv_nsec); + + SAFE_EPOLL_CTL(efd, EPOLL_CTL_DEL, fd_in.fd, &e); + } + + tst_res(TPASS, "Timeout works correctly"); +} + +static void setup(void) +{ + epoll_pwait_init(); + efd = SAFE_EPOLL_CREATE1(0); +} + +static void cleanup(void) +{ + if (efd >= 0) + SAFE_CLOSE(efd); +} + +static struct tst_test test = { + .test_all = run, + .setup = setup, + .cleanup = cleanup, + .test_variants = TEST_VARIANTS, + .tags = (const struct tst_tag[]) { + {"linux-git", "d9ec73301099"}, + {} + } +}; -- 2.49.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [LTP] [PATCH v2 2/2] Add regression test for epoll_pwait2() timeout 2025-06-03 15:22 ` [LTP] [PATCH v2 2/2] Add regression test for epoll_pwait2() timeout Martin Doucha @ 2025-06-04 7:01 ` Andrea Cervesato via ltp 2025-06-04 7:29 ` Petr Vorel 1 sibling, 0 replies; 10+ messages in thread From: Andrea Cervesato via ltp @ 2025-06-04 7:01 UTC (permalink / raw) To: Martin Doucha, ltp Reviewed-by: Andrea Cervesato <andrea.cervesato@suse.com> -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [LTP] [PATCH v2 2/2] Add regression test for epoll_pwait2() timeout 2025-06-03 15:22 ` [LTP] [PATCH v2 2/2] Add regression test for epoll_pwait2() timeout Martin Doucha 2025-06-04 7:01 ` Andrea Cervesato via ltp @ 2025-06-04 7:29 ` Petr Vorel 1 sibling, 0 replies; 10+ messages in thread From: Petr Vorel @ 2025-06-04 7:29 UTC (permalink / raw) To: Martin Doucha; +Cc: ltp Hi Martin, LGTM, thanks for this regression test! Reviewed-by: Petr Vorel <pvorel@suse.cz> Kind regards, Petr -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [LTP] [PATCH v2 0/2] epoll_pwait2() timeout regression test 2025-06-03 15:22 [LTP] [PATCH v2 0/2] epoll_pwait2() timeout regression test Martin Doucha 2025-06-03 15:22 ` [LTP] [PATCH v2 1/2] epoll_pwait: Refactor timeout to struct timespec Martin Doucha 2025-06-03 15:22 ` [LTP] [PATCH v2 2/2] Add regression test for epoll_pwait2() timeout Martin Doucha @ 2025-06-04 7:34 ` Petr Vorel 2 siblings, 0 replies; 10+ messages in thread From: Petr Vorel @ 2025-06-04 7:34 UTC (permalink / raw) To: Martin Doucha; +Cc: ltp Hi Martin, > There seems to be a regression in kernel v6.14 where epoll_pwait2() > interprets very small timeout values (~1000ns) as infinity and waits > for events forever. This patchset adds regression test for this bug > and a necessary refactor for do_epoll_pwait() to allow high precision > timeouts. Good catch! BTW it looks to me 0a65bc27bd64 is from v6.15-rc3 (e.g. 6.15 development cycle), but it was backported to 6.14 stable as 99a0ad16dfd11 to v6.14.4. Obviously fixing commit d9ec73301099 has also been backported (to v6.14.8). Kind regards, Petr -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-06-05 6:28 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-06-03 15:22 [LTP] [PATCH v2 0/2] epoll_pwait2() timeout regression test Martin Doucha 2025-06-03 15:22 ` [LTP] [PATCH v2 1/2] epoll_pwait: Refactor timeout to struct timespec Martin Doucha 2025-06-04 6:35 ` Petr Vorel 2025-06-04 12:10 ` Martin Doucha 2025-06-05 6:28 ` Petr Vorel 2025-06-04 7:01 ` Andrea Cervesato via ltp 2025-06-03 15:22 ` [LTP] [PATCH v2 2/2] Add regression test for epoll_pwait2() timeout Martin Doucha 2025-06-04 7:01 ` Andrea Cervesato via ltp 2025-06-04 7:29 ` Petr Vorel 2025-06-04 7:34 ` [LTP] [PATCH v2 0/2] epoll_pwait2() timeout regression test Petr Vorel
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.