diff options
| author | Christian Brauner <brauner@kernel.org> | 2026-10-02 15:52:52 +0200 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-10-04 12:36:15 +0200 |
| commit | 098bf3be6cecb9b297f5a5865e89d36d16edf19e (patch) | |
| tree | 4a9a195c7f2b18d247b3aa89d8c84d6a50f42417 /tools/testing | |
| parent | fa15a241f0a862904d673d2514baf9a26c0893e8 (diff) | |
selftests/filesystems: check that reading the root of an empty mount namespace stalls nobody
A readdir of the root of an empty mount namespace stuck in the page
fault of its buffer must stall neither a create nor a lookup in that
directory. The test needs userfaultfd and skips without it.
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-21-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Diffstat (limited to 'tools/testing')
3 files changed, 50 insertions, 1 deletions
diff --git a/tools/testing/selftests/filesystems/empty_mntns/.gitignore b/tools/testing/selftests/filesystems/empty_mntns/.gitignore index 8ea166068d6b..27bcbcaeb1d1 100644 --- a/tools/testing/selftests/filesystems/empty_mntns/.gitignore +++ b/tools/testing/selftests/filesystems/empty_mntns/.gitignore @@ -4,3 +4,4 @@ empty_mntns_test overmount_chroot_test internal_sb_reconfigure_test nullfs_atime_test +root_readdir_test diff --git a/tools/testing/selftests/filesystems/empty_mntns/Makefile b/tools/testing/selftests/filesystems/empty_mntns/Makefile index 4b2ea6acec1c..22af2164c54e 100644 --- a/tools/testing/selftests/filesystems/empty_mntns/Makefile +++ b/tools/testing/selftests/filesystems/empty_mntns/Makefile @@ -4,7 +4,9 @@ CFLAGS += -Wall -O2 -g $(KHDR_INCLUDES) $(TOOLS_INCLUDES) LDLIBS += -lcap TEST_GEN_PROGS := empty_mntns_test overmount_chroot_test clone3_empty_mntns_test -TEST_GEN_PROGS += internal_sb_reconfigure_test nullfs_atime_test +TEST_GEN_PROGS += internal_sb_reconfigure_test nullfs_atime_test root_readdir_test + +LOCAL_HDRS += ../readdir_hold.h include ../../lib.mk @@ -12,3 +14,4 @@ $(OUTPUT)/empty_mntns_test: ../utils.c $(OUTPUT)/overmount_chroot_test: ../utils.c $(OUTPUT)/clone3_empty_mntns_test: ../utils.c $(OUTPUT)/internal_sb_reconfigure_test: ../utils.c +$(OUTPUT)/root_readdir_test: LDLIBS += -pthread diff --git a/tools/testing/selftests/filesystems/empty_mntns/root_readdir_test.c b/tools/testing/selftests/filesystems/empty_mntns/root_readdir_test.c new file mode 100644 index 000000000000..0ff544247027 --- /dev/null +++ b/tools/testing/selftests/filesystems/empty_mntns/root_readdir_test.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Reading the root of an empty mount namespace holds nothing that anybody + * else waits for: the directory never has an entry, so a readdir stuck in + * the page fault of its buffer stalls neither a create nor a lookup in it. + */ +#define _GNU_SOURCE +#include <errno.h> +#include <fcntl.h> +#include <sched.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "../../kselftest_harness.h" +#include "../readdir_hold.h" +#include "empty_mntns.h" + +TEST(readdir_blocks_nobody) +{ + struct readdir_hold hold; + bool stalled; + int dfd; + + if (geteuid()) + SKIP(return, "test requires root"); + if (readdir_hold_init(&hold)) + SKIP(return, "test requires userfaultfd"); + if (unshare(UNSHARE_EMPTY_MNTNS)) { + readdir_hold_destroy(&hold); + if (errno == EINVAL) + SKIP(return, "UNSHARE_EMPTY_MNTNS not supported"); + ASSERT_TRUE(false) + TH_LOG("unshare(UNSHARE_EMPTY_MNTNS): %m"); + } + dfd = open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC); + ASSERT_GE(dfd, 0); + ASSERT_EQ(readdir_hold_check(&hold, dfd, &stalled), 0); + /* the lookup came back while the readdir was stuck in its fault */ + EXPECT_FALSE(stalled); + close(dfd); + readdir_hold_destroy(&hold); +} + +TEST_HARNESS_MAIN |
