[LTP] [PATCH] name_to_handle_at: Add test cases for AT_HANDLE_FID

Jan Kara jack@suse.cz
Tue Oct 21 11:58:28 CEST 2025


Add a few testcases verifying AT_HANDLE_FID flag.

Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 include/lapi/fcntl.h                          |  4 +
 .../name_to_handle_at/name_to_handle_at03.c   | 88 +++++++++++++++++++
 2 files changed, 92 insertions(+)
 create mode 100644 testcases/kernel/syscalls/name_to_handle_at/name_to_handle_at03.c

Changes since v1:
* Added kernel commit fixing the issue
* Fixed up test description

diff --git a/include/lapi/fcntl.h b/include/lapi/fcntl.h
index 7c050248892e..55a5e8b40432 100644
--- a/include/lapi/fcntl.h
+++ b/include/lapi/fcntl.h
@@ -98,6 +98,10 @@
 # define AT_HANDLE_FID		AT_REMOVEDIR
 #endif
 
+#ifndef AT_HANDLE_CONNECTABLE
+# define AT_HANDLE_CONNECTABLE	0x002
+#endif
+
 #ifndef AT_SYMLINK_FOLLOW
 # define AT_SYMLINK_FOLLOW	0x400
 #endif
diff --git a/testcases/kernel/syscalls/name_to_handle_at/name_to_handle_at03.c b/testcases/kernel/syscalls/name_to_handle_at/name_to_handle_at03.c
new file mode 100644
index 000000000000..d1f53c39d1df
--- /dev/null
+++ b/testcases/kernel/syscalls/name_to_handle_at/name_to_handle_at03.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*\
+ * name_to_handle_at() tests for AT_HANDLE_FID handles.
+ */
+
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include "lapi/name_to_handle_at.h"
+
+#define TEST_FILE "test_file"
+
+static int fd_atcwd = AT_FDCWD;
+static struct file_handle *fhp;
+
+static struct tcase {
+	const char *name;
+	int *dfd;
+	const char *pathname;
+	int name_flags;
+	int exp_errno;
+} tcases[] = {
+	{"test-file", &fd_atcwd, TEST_FILE, AT_HANDLE_FID, 0},
+	{"unexportable-file", &fd_atcwd, "/proc/filesystems", AT_HANDLE_FID, 0},
+	{"test-file-connectable", &fd_atcwd, TEST_FILE, AT_HANDLE_FID | AT_HANDLE_CONNECTABLE, EINVAL},
+};
+
+static bool handle_type_supported(unsigned int flag, const char *name)
+{
+	/*
+	 * For kernels which don't support the flag, name_to_handle_at()
+	 * returns EINVAL, otherwise we should get back EBADF because dirfd is
+	 * invalid.
+	 */
+	if (name_to_handle_at(-1, ".", NULL, NULL, flag) && errno == EINVAL) {
+		tst_brk(TCONF, "%s not supported by the kernel.", name);
+		return false;
+	}
+	return true;
+}
+
+#define REQUIRE_HANDLE_TYPE_SUPPORT(flag) handle_type_supported(flag, #flag)
+
+static void setup(void)
+{
+	SAFE_TOUCH(TEST_FILE, 0600, NULL);
+	fhp = malloc(MAX_HANDLE_SZ);
+	if (!fhp)
+		tst_brk(TBROK, "malloc failed");
+
+	REQUIRE_HANDLE_TYPE_SUPPORT(AT_HANDLE_FID);
+	REQUIRE_HANDLE_TYPE_SUPPORT(AT_HANDLE_CONNECTABLE);
+}
+
+static void run(unsigned int n)
+{
+	struct tcase *tc = &tcases[n];
+	int mount_id;
+
+	fhp->handle_bytes = MAX_HANDLE_SZ;
+	TEST(name_to_handle_at(*tc->dfd, tc->pathname, fhp, &mount_id,
+			       tc->name_flags));
+	if (!tc->exp_errno) {
+		if (TST_RET)
+			tst_res(TFAIL | TTERRNO, "%s: name_to_handle_at() failed", tc->name);
+		else
+			tst_res(TPASS, "%s: name_to_handle_at() passed", tc->name);
+		return;
+	}
+
+	if (TST_RET != -1)
+		tst_res(TFAIL, "%s: name_to_handle_at() unexpectedly succeeded", tc->name);
+	else if (TST_ERR != tc->exp_errno)
+		tst_res(TFAIL | TTERRNO, "%s: name_to_handle_at() should fail with errno %s",
+			tc->name, tst_strerrno(tc->exp_errno));
+	else
+		tst_res(TPASS, "%s: name_to_handle_at() failed as expected", tc->name);
+}
+
+static struct tst_test test = {
+	.tcnt = ARRAY_SIZE(tcases),
+	.test = run,
+	.setup = setup,
+	.needs_tmpdir = 1,
+	.tags = (const struct tst_tag[]) {
+		{"linux-git", "48b77733d0db"},
+		{}
+	},
+};
-- 
2.51.0



More information about the ltp mailing list