summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/filesystems
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2026-04-16 12:58:57 +0200
committerChristian Brauner <brauner@kernel.org>2026-05-21 15:33:48 +0200
commit21688d812289d11ccf3018a94e0dfa2c98e73ec4 (patch)
tree29fa743999d99a13dcfefd9e09bd90a14eecb44c /tools/testing/selftests/filesystems
parent09e8b7a428b3f52b7625870edb4cd42e621fac07 (diff)
parent6045a75399b45f6805f07a03020abf384b9f53c3 (diff)
Merge patch series "OPENAT2_REGULAR flag support for openat2"
Dorjoy Chowdhury <dorjoychy111@gmail.com> says: I came upon this "Ability to only open regular files" uapi feature suggestion from https://uapi-group.org/kernel-features/#ability-to-only-open-regular-files and thought it would be something I could do as a first patch and get to know the kernel code a bit better. The following filesystems have been tested by building and booting the kernel x86 bzImage in a Fedora 43 VM in QEMU. I have tested with OPENAT2_REGULAR that regular files can be successfully opened and non-regular files (directory, fifo etc) return -EFTYPE. - btrfs - NFS (loopback) - SMB (loopback) Christian Brauner (Amutable) <brauner@kernel.org>: All atomic_open implementations were audited for OPENAT2_REGULAR handling. Explicit checks were added to ceph, gfs2, nfs (v4), and cifs/smb — these are the filesystems whose atomic_open can encounter an existing non-regular file and would otherwise call finish_open() on it or return a misleading error code. The checks allow these filesystems to return -EFTYPE directly and avoid unnecessary open+close round-trips. The remaining implementations (9p, fuse, vboxsf, nfs v2/v3) don't need explicit checks. They only call finish_open() on freshly created files (always S_IFREG) and use finish_no_open() for lookup hits, letting the VFS catch non-regular files via the do_open() safety net. Notably, fuse also validates the server response (S_ISREG check on the reply) before reaching finish_open(). * patches from https://patch.msgid.link/20260328172314.45807-1-dorjoychy111@gmail.com: kselftest/openat2: test for OPENAT2_REGULAR flag openat2: new OPENAT2_REGULAR flag support Link: https://patch.msgid.link/20260328172314.45807-1-dorjoychy111@gmail.com Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Diffstat (limited to 'tools/testing/selftests/filesystems')
-rw-r--r--tools/testing/selftests/filesystems/openat2/openat2_test.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/tools/testing/selftests/filesystems/openat2/openat2_test.c b/tools/testing/selftests/filesystems/openat2/openat2_test.c
index 5ea3eebb7b59..6f5afbe2d8d3 100644
--- a/tools/testing/selftests/filesystems/openat2/openat2_test.c
+++ b/tools/testing/selftests/filesystems/openat2/openat2_test.c
@@ -310,4 +310,53 @@ TEST_F(openat2, flag_validation)
}
}
+#ifndef OPENAT2_REGULAR
+#define OPENAT2_REGULAR ((__u64)1 << 32)
+#endif
+
+#ifndef EFTYPE
+#define EFTYPE 134
+#endif
+
+/* Kernel-internal carrier for OPENAT2_REGULAR (see __O_REGULAR in fcntl.h). */
+#ifndef __O_REGULAR
+#define __O_REGULAR (1 << 30)
+#endif
+
+/* Verify that OPENAT2_REGULAR rejects non-regular files with EFTYPE. */
+TEST_F(openat2, regular_flag)
+{
+ struct open_how how = {
+ .flags = OPENAT2_REGULAR | O_RDONLY,
+ };
+ int fd;
+
+ fd = sys_openat2(AT_FDCWD, "/dev/null", &how);
+ if (fd == -ENOENT)
+ SKIP(return, "/dev/null does not exist");
+
+ EXPECT_EQ(-EFTYPE, fd) {
+ TH_LOG("openat2 with OPENAT2_REGULAR should fail with %d (%s), got %d (%s)",
+ -EFTYPE, strerror(EFTYPE), fd, strerror(-fd));
+ }
+ if (fd >= 0)
+ close(fd);
+}
+
+/* open()/openat() must keep ignoring the internal __O_REGULAR bit. */
+TEST(legacy_openat_ignores_o_regular)
+{
+ int fd;
+
+ fd = openat(AT_FDCWD, "/dev/null", O_RDONLY | __O_REGULAR);
+ if (fd < 0 && errno == ENOENT)
+ SKIP(return, "/dev/null does not exist");
+
+ ASSERT_GE(fd, 0) {
+ TH_LOG("legacy openat() must ignore the __O_REGULAR carrier bit, got errno %d (%s)",
+ errno, strerror(errno));
+ }
+ close(fd);
+}
+
TEST_HARNESS_MAIN