* [PATCH] ceph: introduce Kunit based unit-tests for string operations
@ 2025-09-19 18:11 Viacheslav Dubeyko
2025-09-25 13:04 ` kernel test robot
0 siblings, 1 reply; 2+ messages in thread
From: Viacheslav Dubeyko @ 2025-09-19 18:11 UTC (permalink / raw)
To: ceph-devel
Cc: idryomov, linux-fsdevel, pdonnell, amarkuze, Slava.Dubeyko, slava,
vdubeyko
From: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
This patch implements the Kunit based set of
unit tests for string operations. It checks
functionality of ceph_mds_state_name(),
ceph_session_op_name(), ceph_mds_op_name(),
ceph_cap_op_name(), ceph_lease_op_name(), and
ceph_snap_op_name().
./tools/testing/kunit/kunit.py run --kunitconfig ./fs/ceph/.kunitconfig
[11:05:53] Configuring KUnit Kernel ...
[11:05:53] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=22
[11:06:01] Starting KUnit Kernel (1/1)...
[11:06:01] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[11:06:01] ================ ceph_strings (6 subtests) =================
[11:06:01] [PASSED] ceph_mds_state_name_test
[11:06:01] [PASSED] ceph_session_op_name_test
[11:06:01] [PASSED] ceph_mds_op_name_test
[11:06:01] [PASSED] ceph_cap_op_name_test
[11:06:01] [PASSED] ceph_lease_op_name_test
[11:06:01] [PASSED] ceph_snap_op_name_test
[11:06:01] ================== [PASSED] ceph_strings ===================
[11:06:01] ============================================================
[11:06:01] Testing complete. Ran 6 tests: passed: 6
[11:06:01] Elapsed time: 8.286s total, 0.002s configuring, 8.117s building, 0.128s running
Signed-off-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
cc: Alex Markuze <amarkuze@redhat.com>
cc: Ilya Dryomov <idryomov@gmail.com>
cc: Ceph Development <ceph-devel@vger.kernel.org>
---
fs/ceph/.kunitconfig | 16 +
fs/ceph/Kconfig | 12 +
fs/ceph/Makefile | 2 +
fs/ceph/kunit_tests.h | 30 ++
fs/ceph/strings.c | 381 +++++++++++++++++------
fs/ceph/strings_test.c | 588 +++++++++++++++++++++++++++++++++++
include/linux/ceph/ceph_fs.h | 191 ++++++++----
7 files changed, 1062 insertions(+), 158 deletions(-)
create mode 100644 fs/ceph/.kunitconfig
create mode 100644 fs/ceph/kunit_tests.h
create mode 100644 fs/ceph/strings_test.c
diff --git a/fs/ceph/.kunitconfig b/fs/ceph/.kunitconfig
new file mode 100644
index 000000000000..f342622020a6
--- /dev/null
+++ b/fs/ceph/.kunitconfig
@@ -0,0 +1,16 @@
+CONFIG_KUNIT=y
+CONFIG_NET=y
+CONFIG_INET=y
+CONFIG_IPV6=y
+CONFIG_CRYPTO=y
+CONFIG_CRC32=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_KEYS=y
+CONFIG_NETFS_SUPPORT=y
+CONFIG_CEPH_LIB=y
+CONFIG_CEPH_FS=y
+CONFIG_CEPH_FS_KUNIT_TEST=y
diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig
index 3e7def3d31c1..2091fa12ed26 100644
--- a/fs/ceph/Kconfig
+++ b/fs/ceph/Kconfig
@@ -50,3 +50,15 @@ config CEPH_FS_SECURITY_LABEL
If you are not using a security module that requires using
extended attributes for file security labels, say N.
+
+config CEPH_FS_KUNIT_TEST
+ tristate "KUnit tests for Ceph FS" if !KUNIT_ALL_TESTS
+ depends on CEPH_FS && KUNIT
+ default KUNIT_ALL_TESTS
+ help
+ This builds KUnit tests for Ceph file system functions.
+
+ For more information on KUnit and unit tests in general, please refer
+ to the KUnit documentation in Documentation/dev-tools/kunit.
+
+ If unsure, say N.
diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile
index 1f77ca04c426..a27309c6500a 100644
--- a/fs/ceph/Makefile
+++ b/fs/ceph/Makefile
@@ -13,3 +13,5 @@ ceph-y := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \
ceph-$(CONFIG_CEPH_FSCACHE) += cache.o
ceph-$(CONFIG_CEPH_FS_POSIX_ACL) += acl.o
ceph-$(CONFIG_FS_ENCRYPTION) += crypto.o
+
+obj-$(CONFIG_CEPH_FS_KUNIT_TEST) += strings_test.o
diff --git a/fs/ceph/kunit_tests.h b/fs/ceph/kunit_tests.h
new file mode 100644
index 000000000000..73a83e570e0a
--- /dev/null
+++ b/fs/ceph/kunit_tests.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * KUnit tests declarations
+ *
+ * Copyright (C) 2025, IBM Corporation
+ *
+ * Author: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
+ */
+
+#ifndef _CEPH_KUNIT_TESTS_H
+#define _CEPH_KUNIT_TESTS_H
+
+#include <kunit/visibility.h>
+
+#if IS_ENABLED(CONFIG_KUNIT)
+int ceph_mds_state_2_str_idx(int mds_state);
+extern const char *ceph_mds_state_name_strings[];
+int ceph_session_op_2_str_idx(int op);
+extern const char *ceph_session_op_name_strings[];
+int ceph_mds_op_2_str_idx(int op);
+extern const char *ceph_mds_op_name_strings[];
+int ceph_cap_op_2_str_idx(int op);
+extern const char *ceph_cap_op_name_strings[];
+int ceph_lease_op_2_str_idx(int op);
+extern const char *ceph_lease_op_name_strings[];
+int ceph_snap_op_2_str_idx(int op);
+extern const char *ceph_snap_op_name_strings[];
+#endif
+
+#endif /* _CEPH_KUNIT_TESTS_H */
diff --git a/fs/ceph/strings.c b/fs/ceph/strings.c
index e36e8948e728..6585a8b12028 100644
--- a/fs/ceph/strings.c
+++ b/fs/ceph/strings.c
@@ -5,126 +5,319 @@
#include <linux/module.h>
#include <linux/ceph/types.h>
+#include "kunit_tests.h"
-const char *ceph_mds_state_name(int s)
+const char *ceph_mds_state_name_strings[] = {
+/* 0 */ "down:dne",
+/* 1 */ "down:stopped",
+/* 2 */ "up:boot",
+/* 3 */ "up:standby",
+/* 4 */ "up:standby-replay",
+/* 5 */ "up:oneshot-replay",
+/* 6 */ "up:creating",
+/* 7 */ "up:starting",
+/* 8 */ "up:replay",
+/* 9 */ "up:resolve",
+/* 10 */ "up:reconnect",
+/* 11 */ "up:rejoin",
+/* 12 */ "up:clientreplay",
+/* 13 */ "up:active",
+/* 14 */ "up:stopping",
+/* 15 */ "???"
+};
+EXPORT_SYMBOL_IF_KUNIT(ceph_mds_state_name_strings);
+
+VISIBLE_IF_KUNIT
+int ceph_mds_state_2_str_idx(int mds_state)
{
- switch (s) {
+ switch (mds_state) {
/* down and out */
- case CEPH_MDS_STATE_DNE: return "down:dne";
- case CEPH_MDS_STATE_STOPPED: return "down:stopped";
+ case CEPH_MDS_STATE_DNE:
+ return CEPH_MDS_STATE_DNE_STR_IDX; /* 0 */
+ case CEPH_MDS_STATE_STOPPED:
+ return CEPH_MDS_STATE_STOPPED_STR_IDX; /* 1 */
/* up and out */
- case CEPH_MDS_STATE_BOOT: return "up:boot";
- case CEPH_MDS_STATE_STANDBY: return "up:standby";
- case CEPH_MDS_STATE_STANDBY_REPLAY: return "up:standby-replay";
- case CEPH_MDS_STATE_REPLAYONCE: return "up:oneshot-replay";
- case CEPH_MDS_STATE_CREATING: return "up:creating";
- case CEPH_MDS_STATE_STARTING: return "up:starting";
+ case CEPH_MDS_STATE_BOOT:
+ return CEPH_MDS_STATE_BOOT_STR_IDX; /* 2 */
+ case CEPH_MDS_STATE_STANDBY:
+ return CEPH_MDS_STATE_STANDBY_STR_IDX; /* 3 */
+ case CEPH_MDS_STATE_STANDBY_REPLAY:
+ return CEPH_MDS_STATE_CREATING_STR_IDX; /* 4 */
+ case CEPH_MDS_STATE_REPLAYONCE:
+ return CEPH_MDS_STATE_STARTING_STR_IDX; /* 5 */
+ case CEPH_MDS_STATE_CREATING:
+ return CEPH_MDS_STATE_STANDBY_REPLAY_STR_IDX; /* 6 */
+ case CEPH_MDS_STATE_STARTING:
+ return CEPH_MDS_STATE_REPLAYONCE_STR_IDX; /* 7 */
/* up and in */
- case CEPH_MDS_STATE_REPLAY: return "up:replay";
- case CEPH_MDS_STATE_RESOLVE: return "up:resolve";
- case CEPH_MDS_STATE_RECONNECT: return "up:reconnect";
- case CEPH_MDS_STATE_REJOIN: return "up:rejoin";
- case CEPH_MDS_STATE_CLIENTREPLAY: return "up:clientreplay";
- case CEPH_MDS_STATE_ACTIVE: return "up:active";
- case CEPH_MDS_STATE_STOPPING: return "up:stopping";
+ case CEPH_MDS_STATE_REPLAY:
+ return CEPH_MDS_STATE_REPLAY_STR_IDX; /* 8 */
+ case CEPH_MDS_STATE_RESOLVE:
+ return CEPH_MDS_STATE_RESOLVE_STR_IDX; /* 9 */
+ case CEPH_MDS_STATE_RECONNECT:
+ return CEPH_MDS_STATE_RECONNECT_STR_IDX; /* 10 */
+ case CEPH_MDS_STATE_REJOIN:
+ return CEPH_MDS_STATE_REJOIN_STR_IDX; /* 11 */
+ case CEPH_MDS_STATE_CLIENTREPLAY:
+ return CEPH_MDS_STATE_CLIENTREPLAY_STR_IDX; /* 12 */
+ case CEPH_MDS_STATE_ACTIVE:
+ return CEPH_MDS_STATE_ACTIVE_STR_IDX; /* 13 */
+ case CEPH_MDS_STATE_STOPPING:
+ return CEPH_MDS_STATE_STOPPING_STR_IDX; /* 14 */
+ default:
+ /* do nothing */
+ break;
}
- return "???";
+
+ return CEPH_MDS_STATE_UNKNOWN_NAME_STR_IDX;
+}
+EXPORT_SYMBOL_IF_KUNIT(ceph_mds_state_2_str_idx);
+
+const char *ceph_mds_state_name(int s)
+{
+ return ceph_mds_state_name_strings[ceph_mds_state_2_str_idx(s)];
+}
+EXPORT_SYMBOL_IF_KUNIT(ceph_mds_state_name);
+
+const char *ceph_session_op_name_strings[] = {
+/* 0 */ "request_open",
+/* 1 */ "open",
+/* 2 */ "request_close",
+/* 3 */ "close",
+/* 4 */ "request_renewcaps",
+/* 5 */ "renewcaps",
+/* 6 */ "stale",
+/* 7 */ "recall_state",
+/* 8 */ "flushmsg",
+/* 9 */ "flushmsg_ack",
+/* 10 */ "force_ro",
+/* 11 */ "reject",
+/* 12 */ "flush_mdlog",
+/* 13 */ "???"
+};
+EXPORT_SYMBOL_IF_KUNIT(ceph_session_op_name_strings);
+
+VISIBLE_IF_KUNIT
+int ceph_session_op_2_str_idx(int op)
+{
+ if (op < CEPH_SESSION_REQUEST_OPEN ||
+ op >= CEPH_SESSION_UNKNOWN_NAME)
+ return CEPH_SESSION_UNKNOWN_NAME;
+
+ return op;
}
+EXPORT_SYMBOL_IF_KUNIT(ceph_session_op_2_str_idx);
const char *ceph_session_op_name(int op)
+{
+ return ceph_session_op_name_strings[ceph_session_op_2_str_idx(op)];
+}
+EXPORT_SYMBOL_IF_KUNIT(ceph_session_op_name);
+
+const char *ceph_mds_op_name_strings[] = {
+/* 0 */ "lookup",
+/* 1 */ "getattr",
+/* 2 */ "lookuphash",
+/* 3 */ "lookupparent",
+/* 4 */ "lookupino",
+/* 5 */ "lookupname",
+/* 6 */ "getvxattr",
+/* 7 */ "setxattr",
+/* 8 */ "rmxattr",
+/* 9 */ "setlayou",
+/* 10 */ "setattr",
+/* 11 */ "setfilelock",
+/* 12 */ "getfilelock",
+/* 13 */ "setdirlayout",
+/* 14 */ "mknod",
+/* 15 */ "link",
+/* 16 */ "unlink",
+/* 17 */ "rename",
+/* 18 */ "mkdir",
+/* 19 */ "rmdir",
+/* 20 */ "symlink",
+/* 21 */ "create",
+/* 22 */ "open",
+/* 23 */ "readdir",
+/* 24 */ "lookupsnap",
+/* 25 */ "mksnap",
+/* 26 */ "rmsnap",
+/* 27 */ "lssnap",
+/* 28 */ "renamesnap",
+/* 29 */ "???"
+};
+EXPORT_SYMBOL_IF_KUNIT(ceph_mds_op_name_strings);
+
+VISIBLE_IF_KUNIT
+int ceph_mds_op_2_str_idx(int op)
{
switch (op) {
- case CEPH_SESSION_REQUEST_OPEN: return "request_open";
- case CEPH_SESSION_OPEN: return "open";
- case CEPH_SESSION_REQUEST_CLOSE: return "request_close";
- case CEPH_SESSION_CLOSE: return "close";
- case CEPH_SESSION_REQUEST_RENEWCAPS: return "request_renewcaps";
- case CEPH_SESSION_RENEWCAPS: return "renewcaps";
- case CEPH_SESSION_STALE: return "stale";
- case CEPH_SESSION_RECALL_STATE: return "recall_state";
- case CEPH_SESSION_FLUSHMSG: return "flushmsg";
- case CEPH_SESSION_FLUSHMSG_ACK: return "flushmsg_ack";
- case CEPH_SESSION_FORCE_RO: return "force_ro";
- case CEPH_SESSION_REJECT: return "reject";
- case CEPH_SESSION_REQUEST_FLUSH_MDLOG: return "flush_mdlog";
+ case CEPH_MDS_OP_LOOKUP:
+ return CEPH_MDS_OP_LOOKUP_STR_IDX; /* 0 */
+ case CEPH_MDS_OP_LOOKUPHASH:
+ return CEPH_MDS_OP_LOOKUPHASH_STR_IDX; /* 2 */
+ case CEPH_MDS_OP_LOOKUPPARENT:
+ return CEPH_MDS_OP_LOOKUPPARENT_STR_IDX; /* 3 */
+ case CEPH_MDS_OP_LOOKUPINO:
+ return CEPH_MDS_OP_LOOKUPINO_STR_IDX; /* 4 */
+ case CEPH_MDS_OP_LOOKUPNAME:
+ return CEPH_MDS_OP_LOOKUPNAME_STR_IDX; /* 5 */
+ case CEPH_MDS_OP_GETATTR:
+ return CEPH_MDS_OP_GETATTR_STR_IDX; /* 1 */
+ case CEPH_MDS_OP_GETVXATTR:
+ return CEPH_MDS_OP_GETVXATTR_STR_IDX; /* 6 */
+ case CEPH_MDS_OP_SETXATTR:
+ return CEPH_MDS_OP_SETXATTR_STR_IDX; /* 7 */
+ case CEPH_MDS_OP_SETATTR:
+ return CEPH_MDS_OP_SETATTR_STR_IDX; /* 10 */
+ case CEPH_MDS_OP_RMXATTR:
+ return CEPH_MDS_OP_RMXATTR_STR_IDX; /* 8 */
+ case CEPH_MDS_OP_SETLAYOUT:
+ return CEPH_MDS_OP_SETLAYOUT_STR_IDX; /* 9 */
+ case CEPH_MDS_OP_SETDIRLAYOUT:
+ return CEPH_MDS_OP_SETDIRLAYOUT_STR_IDX; /* 13 */
+ case CEPH_MDS_OP_READDIR:
+ return CEPH_MDS_OP_READDIR_STR_IDX; /* 23 */
+ case CEPH_MDS_OP_MKNOD:
+ return CEPH_MDS_OP_MKNOD_STR_IDX; /* 14 */
+ case CEPH_MDS_OP_LINK:
+ return CEPH_MDS_OP_LINK_STR_IDX; /* 15 */
+ case CEPH_MDS_OP_UNLINK:
+ return CEPH_MDS_OP_UNLINK_STR_IDX; /* 16 */
+ case CEPH_MDS_OP_RENAME:
+ return CEPH_MDS_OP_RENAME_STR_IDX; /* 17 */
+ case CEPH_MDS_OP_MKDIR:
+ return CEPH_MDS_OP_MKDIR_STR_IDX; /* 18 */
+ case CEPH_MDS_OP_RMDIR:
+ return CEPH_MDS_OP_RMDIR_STR_IDX; /* 19 */
+ case CEPH_MDS_OP_SYMLINK:
+ return CEPH_MDS_OP_SYMLINK_STR_IDX; /* 20 */
+ case CEPH_MDS_OP_CREATE:
+ return CEPH_MDS_OP_CREATE_STR_IDX; /* 21 */
+ case CEPH_MDS_OP_OPEN:
+ return CEPH_MDS_OP_OPEN_STR_IDX; /* 22 */
+ case CEPH_MDS_OP_LOOKUPSNAP:
+ return CEPH_MDS_OP_LOOKUPSNAP_STR_IDX; /* 24 */
+ case CEPH_MDS_OP_LSSNAP:
+ return CEPH_MDS_OP_LSSNAP_STR_IDX; /* 27 */
+ case CEPH_MDS_OP_MKSNAP:
+ return CEPH_MDS_OP_MKSNAP_STR_IDX; /* 25 */
+ case CEPH_MDS_OP_RMSNAP:
+ return CEPH_MDS_OP_RMSNAP_STR_IDX; /* 26 */
+ case CEPH_MDS_OP_RENAMESNAP:
+ return CEPH_MDS_OP_RENAMESNAP_STR_IDX; /* 28 */
+ case CEPH_MDS_OP_SETFILELOCK:
+ return CEPH_MDS_OP_SETFILELOCK_STR_IDX; /* 11 */
+ case CEPH_MDS_OP_GETFILELOCK:
+ return CEPH_MDS_OP_GETFILELOCK_STR_IDX; /* 12 */
+ default:
+ /* do nothing */
+ break;
}
- return "???";
+
+ return CEPH_MDS_OP_UNKNOWN_NAME_STR_IDX;
}
+EXPORT_SYMBOL_IF_KUNIT(ceph_mds_op_2_str_idx);
const char *ceph_mds_op_name(int op)
{
- switch (op) {
- case CEPH_MDS_OP_LOOKUP: return "lookup";
- case CEPH_MDS_OP_LOOKUPHASH: return "lookuphash";
- case CEPH_MDS_OP_LOOKUPPARENT: return "lookupparent";
- case CEPH_MDS_OP_LOOKUPINO: return "lookupino";
- case CEPH_MDS_OP_LOOKUPNAME: return "lookupname";
- case CEPH_MDS_OP_GETATTR: return "getattr";
- case CEPH_MDS_OP_GETVXATTR: return "getvxattr";
- case CEPH_MDS_OP_SETXATTR: return "setxattr";
- case CEPH_MDS_OP_SETATTR: return "setattr";
- case CEPH_MDS_OP_RMXATTR: return "rmxattr";
- case CEPH_MDS_OP_SETLAYOUT: return "setlayou";
- case CEPH_MDS_OP_SETDIRLAYOUT: return "setdirlayout";
- case CEPH_MDS_OP_READDIR: return "readdir";
- case CEPH_MDS_OP_MKNOD: return "mknod";
- case CEPH_MDS_OP_LINK: return "link";
- case CEPH_MDS_OP_UNLINK: return "unlink";
- case CEPH_MDS_OP_RENAME: return "rename";
- case CEPH_MDS_OP_MKDIR: return "mkdir";
- case CEPH_MDS_OP_RMDIR: return "rmdir";
- case CEPH_MDS_OP_SYMLINK: return "symlink";
- case CEPH_MDS_OP_CREATE: return "create";
- case CEPH_MDS_OP_OPEN: return "open";
- case CEPH_MDS_OP_LOOKUPSNAP: return "lookupsnap";
- case CEPH_MDS_OP_LSSNAP: return "lssnap";
- case CEPH_MDS_OP_MKSNAP: return "mksnap";
- case CEPH_MDS_OP_RMSNAP: return "rmsnap";
- case CEPH_MDS_OP_RENAMESNAP: return "renamesnap";
- case CEPH_MDS_OP_SETFILELOCK: return "setfilelock";
- case CEPH_MDS_OP_GETFILELOCK: return "getfilelock";
- }
- return "???";
+ return ceph_mds_op_name_strings[ceph_mds_op_2_str_idx(op)];
}
+EXPORT_SYMBOL_IF_KUNIT(ceph_mds_op_name);
+
+const char *ceph_cap_op_name_strings[] = {
+/* 0 */ "grant",
+/* 1 */ "revoke",
+/* 2 */ "trunc",
+/* 3 */ "export",
+/* 4 */ "import",
+/* 5 */ "update",
+/* 6 */ "drop",
+/* 7 */ "flush",
+/* 8 */ "flush_ack",
+/* 9 */ "flushsnap",
+/* 10 */ "flushsnap_ack",
+/* 11 */ "release",
+/* 12 */ "renew",
+/* 13 */ "???"
+};
+EXPORT_SYMBOL_IF_KUNIT(ceph_cap_op_name_strings);
+
+VISIBLE_IF_KUNIT
+int ceph_cap_op_2_str_idx(int op)
+{
+ if (op < CEPH_CAP_OP_GRANT ||
+ op >= CEPH_CAP_OP_UNKNOWN_NAME)
+ return CEPH_SESSION_UNKNOWN_NAME;
+
+ return op;
+}
+EXPORT_SYMBOL_IF_KUNIT(ceph_cap_op_2_str_idx);
const char *ceph_cap_op_name(int op)
+{
+ return ceph_cap_op_name_strings[ceph_cap_op_2_str_idx(op)];
+}
+EXPORT_SYMBOL_IF_KUNIT(ceph_cap_op_name);
+
+const char *ceph_lease_op_name_strings[] = {
+/* 0 */ "revoke",
+/* 1 */ "release",
+/* 2 */ "renew",
+/* 3 */ "revoke_ack",
+/* 4 */ "???"
+};
+EXPORT_SYMBOL_IF_KUNIT(ceph_lease_op_name_strings);
+
+VISIBLE_IF_KUNIT
+int ceph_lease_op_2_str_idx(int op)
{
switch (op) {
- case CEPH_CAP_OP_GRANT: return "grant";
- case CEPH_CAP_OP_REVOKE: return "revoke";
- case CEPH_CAP_OP_TRUNC: return "trunc";
- case CEPH_CAP_OP_EXPORT: return "export";
- case CEPH_CAP_OP_IMPORT: return "import";
- case CEPH_CAP_OP_UPDATE: return "update";
- case CEPH_CAP_OP_DROP: return "drop";
- case CEPH_CAP_OP_FLUSH: return "flush";
- case CEPH_CAP_OP_FLUSH_ACK: return "flush_ack";
- case CEPH_CAP_OP_FLUSHSNAP: return "flushsnap";
- case CEPH_CAP_OP_FLUSHSNAP_ACK: return "flushsnap_ack";
- case CEPH_CAP_OP_RELEASE: return "release";
- case CEPH_CAP_OP_RENEW: return "renew";
+ case CEPH_MDS_LEASE_REVOKE:
+ return CEPH_MDS_LEASE_REVOKE_STR_IDX;
+ case CEPH_MDS_LEASE_RELEASE:
+ return CEPH_MDS_LEASE_RELEASE_STR_IDX;
+ case CEPH_MDS_LEASE_RENEW:
+ return CEPH_MDS_LEASE_RENEW_STR_IDX;
+ case CEPH_MDS_LEASE_REVOKE_ACK:
+ return CEPH_MDS_LEASE_REVOKE_ACK_STR_IDX;
+ default:
+ /* do nothing */
+ break;
}
- return "???";
+
+ return CEPH_MDS_LEASE_UNKNOWN_NAME_STR_IDX;
}
+EXPORT_SYMBOL_IF_KUNIT(ceph_lease_op_2_str_idx);
-const char *ceph_lease_op_name(int o)
+const char *ceph_lease_op_name(int op)
{
- switch (o) {
- case CEPH_MDS_LEASE_REVOKE: return "revoke";
- case CEPH_MDS_LEASE_RELEASE: return "release";
- case CEPH_MDS_LEASE_RENEW: return "renew";
- case CEPH_MDS_LEASE_REVOKE_ACK: return "revoke_ack";
- }
- return "???";
+ return ceph_lease_op_name_strings[ceph_lease_op_2_str_idx(op)];
}
+EXPORT_SYMBOL_IF_KUNIT(ceph_lease_op_name);
-const char *ceph_snap_op_name(int o)
+const char *ceph_snap_op_name_strings[] = {
+/* 0 */ "update",
+/* 1 */ "create",
+/* 2 */ "destroy",
+/* 3 */ "split",
+/* 4 */ "???"
+};
+EXPORT_SYMBOL_IF_KUNIT(ceph_snap_op_name_strings);
+
+VISIBLE_IF_KUNIT
+int ceph_snap_op_2_str_idx(int op)
{
- switch (o) {
- case CEPH_SNAP_OP_UPDATE: return "update";
- case CEPH_SNAP_OP_CREATE: return "create";
- case CEPH_SNAP_OP_DESTROY: return "destroy";
- case CEPH_SNAP_OP_SPLIT: return "split";
- }
- return "???";
+ if (op < CEPH_SNAP_OP_UPDATE ||
+ op >= CEPH_SNAP_OP_UNKNOWN_NAME)
+ return CEPH_SNAP_OP_UNKNOWN_NAME;
+
+ return op;
+}
+EXPORT_SYMBOL_IF_KUNIT(ceph_snap_op_2_str_idx);
+
+const char *ceph_snap_op_name(int op)
+{
+ return ceph_snap_op_name_strings[ceph_snap_op_2_str_idx(op)];
}
+EXPORT_SYMBOL_IF_KUNIT(ceph_snap_op_name);
diff --git a/fs/ceph/strings_test.c b/fs/ceph/strings_test.c
new file mode 100644
index 000000000000..9e5204508192
--- /dev/null
+++ b/fs/ceph/strings_test.c
@@ -0,0 +1,588 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * KUnit tests for fs/ceph/strings.c
+ *
+ * Copyright (C) 2025, IBM Corporation
+ *
+ * Author: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
+ */
+
+#include <kunit/test.h>
+#include <linux/ceph/types.h>
+
+#include "kunit_tests.h"
+
+#define CEPH_KUNIT_STRINGS_TEST_RANGE (20)
+#define CEPH_KUNIT_OP_INVALID_MIN (-999)
+#define CEPH_KUNIT_OP_INVALID_MAX (999)
+
+typedef int (*next_op_func)(int);
+
+struct ceph_op_iterator {
+ int start;
+ int cur;
+ int next;
+ int end;
+ next_op_func get_next_op;
+};
+
+static inline
+void ceph_op_iterator_init(struct ceph_op_iterator *iter,
+ int start, int end,
+ next_op_func get_next_op)
+{
+ if (!iter || !get_next_op)
+ return;
+
+ iter->start = iter->cur = start;
+ iter->end = end;
+ iter->get_next_op = get_next_op;
+ iter->next = iter->get_next_op(start);
+}
+
+static inline
+int ceph_op_iterator_next(struct ceph_op_iterator *iter)
+{
+ int threshold1, threshold2;
+
+ if (!iter)
+ return CEPH_KUNIT_OP_INVALID_MAX;
+
+ if (iter->cur >= iter->end)
+ return CEPH_KUNIT_OP_INVALID_MAX;
+
+ threshold1 = iter->start + CEPH_KUNIT_STRINGS_TEST_RANGE;
+ if (threshold1 > iter->next)
+ threshold1 = iter->next;
+
+ threshold2 = iter->next - CEPH_KUNIT_STRINGS_TEST_RANGE;
+ if (threshold2 < threshold1)
+ threshold2 = iter->next;
+
+ iter->cur++;
+
+ if (iter->cur <= threshold1)
+ goto finish_method;
+
+ if (iter->cur >= threshold2 && iter->cur <= iter->next)
+ goto finish_method;
+
+ iter->start = iter->next;
+ iter->next = iter->get_next_op(iter->start);
+
+ if (iter->start >= iter->next)
+ iter->next = iter->end;
+
+finish_method:
+ return iter->cur;
+}
+
+static inline
+bool ceph_op_iterator_valid(struct ceph_op_iterator *iter)
+{
+ if (!iter)
+ return false;
+
+ return iter->cur < iter->end;
+}
+
+static inline
+int __ceph_next_op(int prev, int lower_bound, int upper_bound)
+{
+ if (prev < lower_bound)
+ return lower_bound;
+
+ if (prev >= lower_bound && prev < upper_bound)
+ return prev + 1;
+
+ return upper_bound;
+}
+
+#define CEPH_MDS_STATE_STR_COUNT (CEPH_MDS_STATE_UNKNOWN_NAME_STR_IDX)
+const int ceph_str_idx_2_mds_state[CEPH_MDS_STATE_STR_COUNT] = {
+/* 0 */ CEPH_MDS_STATE_DNE,
+/* 1 */ CEPH_MDS_STATE_STOPPED,
+/* 2 */ CEPH_MDS_STATE_BOOT,
+/* 3 */ CEPH_MDS_STATE_STANDBY,
+/* 4 */ CEPH_MDS_STATE_STANDBY_REPLAY,
+/* 5 */ CEPH_MDS_STATE_REPLAYONCE,
+/* 6 */ CEPH_MDS_STATE_CREATING,
+/* 7 */ CEPH_MDS_STATE_STARTING,
+/* 8 */ CEPH_MDS_STATE_REPLAY,
+/* 9 */ CEPH_MDS_STATE_RESOLVE,
+/* 10 */ CEPH_MDS_STATE_RECONNECT,
+/* 11 */ CEPH_MDS_STATE_REJOIN,
+/* 12 */ CEPH_MDS_STATE_CLIENTREPLAY,
+/* 13 */ CEPH_MDS_STATE_ACTIVE,
+/* 14 */ CEPH_MDS_STATE_STOPPING
+};
+
+static int ceph_mds_state_next_op(int prev)
+{
+ if (prev < CEPH_MDS_STATE_REPLAYONCE)
+ return CEPH_MDS_STATE_REPLAYONCE;
+
+ /* [-9..-4] */
+ if (prev >= CEPH_MDS_STATE_REPLAYONCE &&
+ prev < CEPH_MDS_STATE_BOOT)
+ return prev + 1;
+
+ /* [-4..-1] */
+ if (prev == CEPH_MDS_STATE_BOOT)
+ return CEPH_MDS_STATE_STOPPED;
+
+ /* [-1..0] */
+ if (prev >= CEPH_MDS_STATE_STOPPED &&
+ prev < CEPH_MDS_STATE_DNE)
+ return prev + 1;
+
+ /* [0..8] */
+ if (prev == CEPH_MDS_STATE_DNE)
+ return CEPH_MDS_STATE_REPLAY;
+
+ /* [8..14] */
+ if (prev >= CEPH_MDS_STATE_REPLAY &&
+ prev < CEPH_MDS_STATE_STOPPING)
+ return prev + 1;
+
+ return CEPH_MDS_STATE_STOPPING;
+}
+
+static void ceph_mds_state_name_test(struct kunit *test)
+{
+ const char *unknown_name =
+ ceph_mds_state_name_strings[CEPH_MDS_STATE_UNKNOWN_NAME_STR_IDX];
+ struct ceph_op_iterator iter;
+ int start, end;
+ int i;
+
+ /* Test valid MDS states */
+ for (i = 0; i < CEPH_MDS_STATE_STR_COUNT; i++) {
+ KUNIT_EXPECT_STREQ(test,
+ ceph_mds_state_name(ceph_str_idx_2_mds_state[i]),
+ ceph_mds_state_name_strings[i]);
+ }
+
+ /* Test invalid/unknown states */
+ start = CEPH_MDS_STATE_REPLAYONCE - CEPH_KUNIT_STRINGS_TEST_RANGE;
+ end = CEPH_MDS_STATE_STOPPING + CEPH_KUNIT_STRINGS_TEST_RANGE;
+ ceph_op_iterator_init(&iter, start, end, ceph_mds_state_next_op);
+
+ while (ceph_op_iterator_valid(&iter)) {
+ switch (ceph_mds_state_2_str_idx(iter.cur)) {
+ case CEPH_MDS_STATE_UNKNOWN_NAME_STR_IDX:
+ KUNIT_EXPECT_STREQ(test,
+ ceph_mds_state_name(iter.cur),
+ unknown_name);
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ ceph_op_iterator_next(&iter);
+ }
+
+ KUNIT_EXPECT_STREQ(test,
+ ceph_mds_state_name(CEPH_KUNIT_OP_INVALID_MIN),
+ unknown_name);
+ KUNIT_EXPECT_STREQ(test,
+ ceph_mds_state_name(CEPH_KUNIT_OP_INVALID_MAX),
+ unknown_name);
+}
+
+static int ceph_session_next_op(int prev)
+{
+ return __ceph_next_op(prev,
+ CEPH_SESSION_REQUEST_OPEN,
+ CEPH_SESSION_REQUEST_FLUSH_MDLOG);
+}
+
+static void ceph_session_op_name_test(struct kunit *test)
+{
+ const char *unknown_name =
+ ceph_session_op_name_strings[CEPH_SESSION_UNKNOWN_NAME];
+ struct ceph_op_iterator iter;
+ int start, end;
+ int i;
+
+ /* Test valid session operations */
+ for (i = CEPH_SESSION_REQUEST_OPEN; i < CEPH_SESSION_UNKNOWN_NAME; i++) {
+ KUNIT_EXPECT_STREQ(test,
+ ceph_session_op_name(i),
+ ceph_session_op_name_strings[i]);
+ }
+
+ /* Test invalid/unknown operations */
+ start = CEPH_SESSION_REQUEST_OPEN - CEPH_KUNIT_STRINGS_TEST_RANGE;
+ end = CEPH_SESSION_REQUEST_FLUSH_MDLOG + CEPH_KUNIT_STRINGS_TEST_RANGE;
+ ceph_op_iterator_init(&iter, start, end, ceph_session_next_op);
+
+ while (ceph_op_iterator_valid(&iter)) {
+ switch (ceph_session_op_2_str_idx(iter.cur)) {
+ case CEPH_SESSION_UNKNOWN_NAME:
+ KUNIT_EXPECT_STREQ(test,
+ ceph_session_op_name(iter.cur),
+ unknown_name);
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ ceph_op_iterator_next(&iter);
+ }
+
+ KUNIT_EXPECT_STREQ(test,
+ ceph_session_op_name(CEPH_KUNIT_OP_INVALID_MIN),
+ unknown_name);
+ KUNIT_EXPECT_STREQ(test,
+ ceph_session_op_name(CEPH_KUNIT_OP_INVALID_MAX),
+ unknown_name);
+}
+
+#define CEPH_MDS_OP_STR_COUNT (CEPH_MDS_OP_UNKNOWN_NAME_STR_IDX)
+const int ceph_str_idx_2_mds_op[CEPH_MDS_OP_STR_COUNT] = {
+/* 0 */ CEPH_MDS_OP_LOOKUP,
+/* 1 */ CEPH_MDS_OP_GETATTR,
+/* 2 */ CEPH_MDS_OP_LOOKUPHASH,
+/* 3 */ CEPH_MDS_OP_LOOKUPPARENT,
+/* 4 */ CEPH_MDS_OP_LOOKUPINO,
+/* 5 */ CEPH_MDS_OP_LOOKUPNAME,
+/* 6 */ CEPH_MDS_OP_GETVXATTR,
+/* 7 */ CEPH_MDS_OP_SETXATTR,
+/* 8 */ CEPH_MDS_OP_RMXATTR,
+/* 9 */ CEPH_MDS_OP_SETLAYOUT,
+/* 10 */ CEPH_MDS_OP_SETATTR,
+/* 11 */ CEPH_MDS_OP_SETFILELOCK,
+/* 12 */ CEPH_MDS_OP_GETFILELOCK,
+/* 13 */ CEPH_MDS_OP_SETDIRLAYOUT,
+/* 14 */ CEPH_MDS_OP_MKNOD,
+/* 15 */ CEPH_MDS_OP_LINK,
+/* 16 */ CEPH_MDS_OP_UNLINK,
+/* 17 */ CEPH_MDS_OP_RENAME,
+/* 18 */ CEPH_MDS_OP_MKDIR,
+/* 19 */ CEPH_MDS_OP_RMDIR,
+/* 20 */ CEPH_MDS_OP_SYMLINK,
+/* 21 */ CEPH_MDS_OP_CREATE,
+/* 22 */ CEPH_MDS_OP_OPEN,
+/* 23 */ CEPH_MDS_OP_READDIR,
+/* 24 */ CEPH_MDS_OP_LOOKUPSNAP,
+/* 25 */ CEPH_MDS_OP_MKSNAP,
+/* 26 */ CEPH_MDS_OP_RMSNAP,
+/* 27 */ CEPH_MDS_OP_LSSNAP,
+/* 28 */ CEPH_MDS_OP_RENAMESNAP
+};
+
+static int ceph_mds_next_op(int prev)
+{
+ if (prev < CEPH_MDS_OP_LOOKUP)
+ return CEPH_MDS_OP_LOOKUP;
+
+ /* [0x00100..0x00106] */
+ if (prev >= CEPH_MDS_OP_LOOKUP &&
+ prev < CEPH_MDS_OP_GETVXATTR)
+ return prev + 1;
+
+ /* [0x00106..0x00110] */
+ if (prev >= CEPH_MDS_OP_GETVXATTR &&
+ prev < CEPH_MDS_OP_GETFILELOCK)
+ return CEPH_MDS_OP_GETFILELOCK;
+
+ /* [0x00110..0x00302] */
+ if (prev >= CEPH_MDS_OP_GETFILELOCK &&
+ prev < CEPH_MDS_OP_OPEN)
+ return CEPH_MDS_OP_OPEN;
+
+ /* [0x00302..0x00305] */
+ if (prev >= CEPH_MDS_OP_OPEN &&
+ prev < CEPH_MDS_OP_READDIR)
+ return CEPH_MDS_OP_READDIR;
+
+ /* [0x00305..0x00400] */
+ if (prev >= CEPH_MDS_OP_READDIR &&
+ prev < CEPH_MDS_OP_LOOKUPSNAP)
+ return CEPH_MDS_OP_LOOKUPSNAP;
+
+ /* [0x00400..0x00402] */
+ if (prev >= CEPH_MDS_OP_LOOKUPSNAP &&
+ prev < CEPH_MDS_OP_LSSNAP)
+ return CEPH_MDS_OP_LSSNAP;
+
+ /* [0x00402..0x01105] */
+ if (prev >= CEPH_MDS_OP_LSSNAP &&
+ prev < CEPH_MDS_OP_SETXATTR)
+ return CEPH_MDS_OP_SETXATTR;
+
+ /* [0x01105..0x0110a] */
+ if (prev >= CEPH_MDS_OP_SETXATTR &&
+ prev < CEPH_MDS_OP_SETDIRLAYOUT)
+ return prev + 1;
+
+ /* [0x0110a..0x01201] */
+ if (prev >= CEPH_MDS_OP_SETDIRLAYOUT &&
+ prev < CEPH_MDS_OP_MKNOD)
+ return CEPH_MDS_OP_MKNOD;
+
+ /* [0x01201..0x01204] */
+ if (prev >= CEPH_MDS_OP_MKNOD &&
+ prev < CEPH_MDS_OP_RENAME)
+ return prev + 1;
+
+ /* [0x01204..0x01220] */
+ if (prev >= CEPH_MDS_OP_RENAME &&
+ prev < CEPH_MDS_OP_MKDIR)
+ return CEPH_MDS_OP_MKDIR;
+
+ /* [0x01220..0x01222] */
+ if (prev >= CEPH_MDS_OP_MKDIR &&
+ prev < CEPH_MDS_OP_SYMLINK)
+ return prev + 1;
+
+ /* [0x01222..0x01301] */
+ if (prev >= CEPH_MDS_OP_SYMLINK &&
+ prev < CEPH_MDS_OP_CREATE)
+ return CEPH_MDS_OP_CREATE;
+
+ /* [0x01301..0x01400] */
+ if (prev >= CEPH_MDS_OP_CREATE &&
+ prev < CEPH_MDS_OP_MKSNAP)
+ return CEPH_MDS_OP_MKSNAP;
+
+ /* [0x01400..0x01401] */
+ if (prev >= CEPH_MDS_OP_MKSNAP &&
+ prev < CEPH_MDS_OP_RMSNAP)
+ return prev + 1;
+
+ /* [0x01401..0x01403] */
+ if (prev >= CEPH_MDS_OP_RMSNAP &&
+ prev < CEPH_MDS_OP_RENAMESNAP)
+ return CEPH_MDS_OP_RENAMESNAP;
+
+ return CEPH_MDS_OP_RENAMESNAP;
+}
+
+static void ceph_mds_op_name_test(struct kunit *test)
+{
+ const char *unknown_name =
+ ceph_mds_op_name_strings[CEPH_MDS_OP_UNKNOWN_NAME_STR_IDX];
+ struct ceph_op_iterator iter;
+ int start, end;
+ int i;
+
+ /* Test valid MDS operations */
+ for (i = 0; i < CEPH_MDS_OP_STR_COUNT; i++) {
+ KUNIT_EXPECT_STREQ(test,
+ ceph_mds_op_name(ceph_str_idx_2_mds_op[i]),
+ ceph_mds_op_name_strings[i]);
+ }
+
+ /* Test invalid/unknown operations */
+ start = CEPH_MDS_OP_LOOKUP - CEPH_KUNIT_STRINGS_TEST_RANGE;
+ end = CEPH_MDS_OP_RENAMESNAP + CEPH_KUNIT_STRINGS_TEST_RANGE;
+ ceph_op_iterator_init(&iter, start, end, ceph_mds_next_op);
+
+ while (ceph_op_iterator_valid(&iter)) {
+ switch (ceph_mds_op_2_str_idx(iter.cur)) {
+ case CEPH_MDS_OP_UNKNOWN_NAME_STR_IDX:
+ KUNIT_EXPECT_STREQ(test,
+ ceph_mds_op_name(iter.cur),
+ unknown_name);
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ ceph_op_iterator_next(&iter);
+ }
+
+ KUNIT_EXPECT_STREQ(test, ceph_mds_op_name(-0x99999), unknown_name);
+ KUNIT_EXPECT_STREQ(test, ceph_mds_op_name(0x99999), unknown_name);
+}
+
+static int ceph_cap_next_op(int prev)
+{
+ return __ceph_next_op(prev,
+ CEPH_CAP_OP_GRANT,
+ CEPH_CAP_OP_RENEW);
+}
+
+static void ceph_cap_op_name_test(struct kunit *test)
+{
+ const char *unknown_name =
+ ceph_cap_op_name_strings[CEPH_CAP_OP_UNKNOWN_NAME];
+ struct ceph_op_iterator iter;
+ int start, end;
+ int i;
+
+ /* Test valid capability operations */
+ for (i = 0; i < CEPH_CAP_OP_UNKNOWN_NAME; i++) {
+ KUNIT_EXPECT_STREQ(test,
+ ceph_cap_op_name(i),
+ ceph_cap_op_name_strings[i]);
+ }
+
+ /* Test invalid/unknown operations */
+ start = CEPH_CAP_OP_GRANT - CEPH_KUNIT_STRINGS_TEST_RANGE;
+ end = CEPH_CAP_OP_RENEW + CEPH_KUNIT_STRINGS_TEST_RANGE;
+ ceph_op_iterator_init(&iter, start, end, ceph_cap_next_op);
+
+ while (ceph_op_iterator_valid(&iter)) {
+ switch (ceph_cap_op_2_str_idx(iter.cur)) {
+ case CEPH_CAP_OP_UNKNOWN_NAME:
+ KUNIT_EXPECT_STREQ(test,
+ ceph_cap_op_name(iter.cur),
+ unknown_name);
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ ceph_op_iterator_next(&iter);
+ }
+
+ KUNIT_EXPECT_STREQ(test,
+ ceph_cap_op_name(CEPH_KUNIT_OP_INVALID_MIN),
+ unknown_name);
+ KUNIT_EXPECT_STREQ(test,
+ ceph_cap_op_name(CEPH_KUNIT_OP_INVALID_MAX),
+ unknown_name);
+}
+
+#define CEPH_MDS_LEASE_OP_STR_COUNT (CEPH_MDS_LEASE_UNKNOWN_NAME_STR_IDX)
+const int ceph_str_idx_2_lease_op[CEPH_MDS_LEASE_OP_STR_COUNT] = {
+/* 0 */ CEPH_MDS_LEASE_REVOKE,
+/* 1 */ CEPH_MDS_LEASE_RELEASE,
+/* 2 */ CEPH_MDS_LEASE_RENEW,
+/* 3 */ CEPH_MDS_LEASE_REVOKE_ACK
+};
+
+static int ceph_lease_next_op(int prev)
+{
+ return __ceph_next_op(prev,
+ CEPH_MDS_LEASE_REVOKE,
+ CEPH_MDS_LEASE_REVOKE_ACK);
+}
+
+static void ceph_lease_op_name_test(struct kunit *test)
+{
+ const char *unknown_name =
+ ceph_lease_op_name_strings[CEPH_MDS_LEASE_UNKNOWN_NAME_STR_IDX];
+ struct ceph_op_iterator iter;
+ int start, end;
+ int i;
+
+ /* Test valid lease operations */
+ for (i = 0; i < CEPH_MDS_LEASE_OP_STR_COUNT; i++) {
+ KUNIT_EXPECT_STREQ(test,
+ ceph_lease_op_name(ceph_str_idx_2_lease_op[i]),
+ ceph_lease_op_name_strings[i]);
+ }
+
+ /* Test invalid/unknown operations */
+ start = CEPH_MDS_LEASE_REVOKE - CEPH_KUNIT_STRINGS_TEST_RANGE;
+ end = CEPH_MDS_LEASE_REVOKE_ACK + CEPH_KUNIT_STRINGS_TEST_RANGE;
+ ceph_op_iterator_init(&iter, start, end, ceph_lease_next_op);
+
+ while (ceph_op_iterator_valid(&iter)) {
+ switch (ceph_lease_op_2_str_idx(iter.cur)) {
+ case CEPH_MDS_LEASE_UNKNOWN_NAME_STR_IDX:
+ KUNIT_EXPECT_STREQ(test,
+ ceph_lease_op_name(iter.cur),
+ unknown_name);
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ ceph_op_iterator_next(&iter);
+ }
+
+ KUNIT_EXPECT_STREQ(test,
+ ceph_lease_op_name(CEPH_KUNIT_OP_INVALID_MIN),
+ unknown_name);
+ KUNIT_EXPECT_STREQ(test,
+ ceph_lease_op_name(CEPH_KUNIT_OP_INVALID_MAX),
+ unknown_name);
+}
+
+static int ceph_snap_next_op(int prev)
+{
+ return __ceph_next_op(prev,
+ CEPH_SNAP_OP_UPDATE,
+ CEPH_SNAP_OP_SPLIT);
+}
+
+static void ceph_snap_op_name_test(struct kunit *test)
+{
+ const char *unknown_name =
+ ceph_snap_op_name_strings[CEPH_SNAP_OP_UNKNOWN_NAME];
+ struct ceph_op_iterator iter;
+ int start, end;
+ int i;
+
+ /* Test valid snapshot operations */
+ for (i = 0; i < CEPH_SNAP_OP_UNKNOWN_NAME; i++) {
+ KUNIT_EXPECT_STREQ(test,
+ ceph_snap_op_name(i),
+ ceph_snap_op_name_strings[i]);
+ }
+
+ /* Test invalid/unknown operations */
+ start = CEPH_SNAP_OP_UPDATE - CEPH_KUNIT_STRINGS_TEST_RANGE;
+ end = CEPH_SNAP_OP_SPLIT + CEPH_KUNIT_STRINGS_TEST_RANGE;
+ ceph_op_iterator_init(&iter, start, end, ceph_snap_next_op);
+
+ while (ceph_op_iterator_valid(&iter)) {
+ switch (ceph_snap_op_2_str_idx(iter.cur)) {
+ case CEPH_MDS_LEASE_UNKNOWN_NAME_STR_IDX:
+ KUNIT_EXPECT_STREQ(test,
+ ceph_snap_op_name(iter.cur),
+ unknown_name);
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ ceph_op_iterator_next(&iter);
+ }
+
+ KUNIT_EXPECT_STREQ(test,
+ ceph_snap_op_name(CEPH_KUNIT_OP_INVALID_MIN),
+ unknown_name);
+ KUNIT_EXPECT_STREQ(test,
+ ceph_snap_op_name(CEPH_KUNIT_OP_INVALID_MAX),
+ unknown_name);
+}
+
+static struct kunit_case ceph_strings_test_cases[] = {
+ KUNIT_CASE(ceph_mds_state_name_test),
+ KUNIT_CASE(ceph_session_op_name_test),
+ KUNIT_CASE(ceph_mds_op_name_test),
+ KUNIT_CASE(ceph_cap_op_name_test),
+ KUNIT_CASE(ceph_lease_op_name_test),
+ KUNIT_CASE(ceph_snap_op_name_test),
+ {}
+};
+
+static struct kunit_suite ceph_strings_test_suite = {
+ .name = "ceph_strings",
+ .test_cases = ceph_strings_test_cases,
+};
+
+kunit_test_suites(&ceph_strings_test_suite);
+
+MODULE_AUTHOR("Viacheslav Dubeyko <slava@dubeyko.com>");
+MODULE_DESCRIPTION("KUnit tests for ceph strings functions");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h
index c7f2c63b3bc3..c41d3996a2b1 100644
--- a/include/linux/ceph/ceph_fs.h
+++ b/include/linux/ceph/ceph_fs.h
@@ -262,6 +262,25 @@ struct ceph_mon_subscribe_ack {
#define CEPH_MDS_STATE_ACTIVE 13 /* up, active */
#define CEPH_MDS_STATE_STOPPING 14 /* up, but exporting metadata */
+enum {
+/* 0 */ CEPH_MDS_STATE_DNE_STR_IDX,
+/* 1 */ CEPH_MDS_STATE_STOPPED_STR_IDX,
+/* 2 */ CEPH_MDS_STATE_BOOT_STR_IDX,
+/* 3 */ CEPH_MDS_STATE_STANDBY_STR_IDX,
+/* 4 */ CEPH_MDS_STATE_CREATING_STR_IDX,
+/* 5 */ CEPH_MDS_STATE_STARTING_STR_IDX,
+/* 6 */ CEPH_MDS_STATE_STANDBY_REPLAY_STR_IDX,
+/* 7 */ CEPH_MDS_STATE_REPLAYONCE_STR_IDX,
+/* 8 */ CEPH_MDS_STATE_REPLAY_STR_IDX,
+/* 9 */ CEPH_MDS_STATE_RESOLVE_STR_IDX,
+/* 10 */ CEPH_MDS_STATE_RECONNECT_STR_IDX,
+/* 11 */ CEPH_MDS_STATE_REJOIN_STR_IDX,
+/* 12 */ CEPH_MDS_STATE_CLIENTREPLAY_STR_IDX,
+/* 13 */ CEPH_MDS_STATE_ACTIVE_STR_IDX,
+/* 14 */ CEPH_MDS_STATE_STOPPING_STR_IDX,
+/* 15 */ CEPH_MDS_STATE_UNKNOWN_NAME_STR_IDX
+};
+
extern const char *ceph_mds_state_name(int s);
@@ -287,19 +306,20 @@ extern const char *ceph_mds_state_name(int s);
/* client_session ops */
enum {
- CEPH_SESSION_REQUEST_OPEN,
- CEPH_SESSION_OPEN,
- CEPH_SESSION_REQUEST_CLOSE,
- CEPH_SESSION_CLOSE,
- CEPH_SESSION_REQUEST_RENEWCAPS,
- CEPH_SESSION_RENEWCAPS,
- CEPH_SESSION_STALE,
- CEPH_SESSION_RECALL_STATE,
- CEPH_SESSION_FLUSHMSG,
- CEPH_SESSION_FLUSHMSG_ACK,
- CEPH_SESSION_FORCE_RO,
- CEPH_SESSION_REJECT,
- CEPH_SESSION_REQUEST_FLUSH_MDLOG,
+/* 0 */ CEPH_SESSION_REQUEST_OPEN,
+/* 1 */ CEPH_SESSION_OPEN,
+/* 2 */ CEPH_SESSION_REQUEST_CLOSE,
+/* 3 */ CEPH_SESSION_CLOSE,
+/* 4 */ CEPH_SESSION_REQUEST_RENEWCAPS,
+/* 5 */ CEPH_SESSION_RENEWCAPS,
+/* 6 */ CEPH_SESSION_STALE,
+/* 7 */ CEPH_SESSION_RECALL_STATE,
+/* 8 */ CEPH_SESSION_FLUSHMSG,
+/* 9 */ CEPH_SESSION_FLUSHMSG_ACK,
+/* 10 */ CEPH_SESSION_FORCE_RO,
+/* 11 */ CEPH_SESSION_REJECT,
+/* 12 */ CEPH_SESSION_REQUEST_FLUSH_MDLOG,
+/* 13 */ CEPH_SESSION_UNKNOWN_NAME
};
#define CEPH_SESSION_BLOCKLISTED (1 << 0) /* session blocklisted */
@@ -322,39 +342,39 @@ struct ceph_mds_session_head {
*/
#define CEPH_MDS_OP_WRITE 0x001000
enum {
- CEPH_MDS_OP_LOOKUP = 0x00100,
- CEPH_MDS_OP_GETATTR = 0x00101,
- CEPH_MDS_OP_LOOKUPHASH = 0x00102,
- CEPH_MDS_OP_LOOKUPPARENT = 0x00103,
- CEPH_MDS_OP_LOOKUPINO = 0x00104,
- CEPH_MDS_OP_LOOKUPNAME = 0x00105,
- CEPH_MDS_OP_GETVXATTR = 0x00106,
-
- CEPH_MDS_OP_SETXATTR = 0x01105,
- CEPH_MDS_OP_RMXATTR = 0x01106,
- CEPH_MDS_OP_SETLAYOUT = 0x01107,
- CEPH_MDS_OP_SETATTR = 0x01108,
- CEPH_MDS_OP_SETFILELOCK= 0x01109,
- CEPH_MDS_OP_GETFILELOCK= 0x00110,
- CEPH_MDS_OP_SETDIRLAYOUT=0x0110a,
-
- CEPH_MDS_OP_MKNOD = 0x01201,
- CEPH_MDS_OP_LINK = 0x01202,
- CEPH_MDS_OP_UNLINK = 0x01203,
- CEPH_MDS_OP_RENAME = 0x01204,
- CEPH_MDS_OP_MKDIR = 0x01220,
- CEPH_MDS_OP_RMDIR = 0x01221,
- CEPH_MDS_OP_SYMLINK = 0x01222,
-
- CEPH_MDS_OP_CREATE = 0x01301,
- CEPH_MDS_OP_OPEN = 0x00302,
- CEPH_MDS_OP_READDIR = 0x00305,
-
- CEPH_MDS_OP_LOOKUPSNAP = 0x00400,
- CEPH_MDS_OP_MKSNAP = 0x01400,
- CEPH_MDS_OP_RMSNAP = 0x01401,
- CEPH_MDS_OP_LSSNAP = 0x00402,
- CEPH_MDS_OP_RENAMESNAP = 0x01403,
+/* 0 */ CEPH_MDS_OP_LOOKUP = 0x00100,
+/* 1 */ CEPH_MDS_OP_GETATTR = 0x00101,
+/* 2 */ CEPH_MDS_OP_LOOKUPHASH = 0x00102,
+/* 3 */ CEPH_MDS_OP_LOOKUPPARENT = 0x00103,
+/* 4 */ CEPH_MDS_OP_LOOKUPINO = 0x00104,
+/* 5 */ CEPH_MDS_OP_LOOKUPNAME = 0x00105,
+/* 6 */ CEPH_MDS_OP_GETVXATTR = 0x00106,
+
+/* 7 */ CEPH_MDS_OP_SETXATTR = 0x01105,
+/* 8 */ CEPH_MDS_OP_RMXATTR = 0x01106,
+/* 9 */ CEPH_MDS_OP_SETLAYOUT = 0x01107,
+/* 10 */ CEPH_MDS_OP_SETATTR = 0x01108,
+/* 11 */ CEPH_MDS_OP_SETFILELOCK = 0x01109,
+/* 12 */ CEPH_MDS_OP_GETFILELOCK = 0x00110,
+/* 13 */ CEPH_MDS_OP_SETDIRLAYOUT = 0x0110a,
+
+/* 14 */ CEPH_MDS_OP_MKNOD = 0x01201,
+/* 15 */ CEPH_MDS_OP_LINK = 0x01202,
+/* 16 */ CEPH_MDS_OP_UNLINK = 0x01203,
+/* 17 */ CEPH_MDS_OP_RENAME = 0x01204,
+/* 18 */ CEPH_MDS_OP_MKDIR = 0x01220,
+/* 19 */ CEPH_MDS_OP_RMDIR = 0x01221,
+/* 20 */ CEPH_MDS_OP_SYMLINK = 0x01222,
+
+/* 21 */ CEPH_MDS_OP_CREATE = 0x01301,
+/* 22 */ CEPH_MDS_OP_OPEN = 0x00302,
+/* 23 */ CEPH_MDS_OP_READDIR = 0x00305,
+
+/* 24 */ CEPH_MDS_OP_LOOKUPSNAP = 0x00400,
+/* 25 */ CEPH_MDS_OP_MKSNAP = 0x01400,
+/* 26 */ CEPH_MDS_OP_RMSNAP = 0x01401,
+/* 27 */ CEPH_MDS_OP_LSSNAP = 0x00402,
+/* 28 */ CEPH_MDS_OP_RENAMESNAP = 0x01403,
};
#define IS_CEPH_MDS_OP_NEWINODE(op) (op == CEPH_MDS_OP_CREATE || \
@@ -362,6 +382,39 @@ enum {
op == CEPH_MDS_OP_MKDIR || \
op == CEPH_MDS_OP_SYMLINK)
+enum {
+/* 0 */ CEPH_MDS_OP_LOOKUP_STR_IDX,
+/* 1 */ CEPH_MDS_OP_GETATTR_STR_IDX,
+/* 2 */ CEPH_MDS_OP_LOOKUPHASH_STR_IDX,
+/* 3 */ CEPH_MDS_OP_LOOKUPPARENT_STR_IDX,
+/* 4 */ CEPH_MDS_OP_LOOKUPINO_STR_IDX,
+/* 5 */ CEPH_MDS_OP_LOOKUPNAME_STR_IDX,
+/* 6 */ CEPH_MDS_OP_GETVXATTR_STR_IDX,
+/* 7 */ CEPH_MDS_OP_SETXATTR_STR_IDX,
+/* 8 */ CEPH_MDS_OP_RMXATTR_STR_IDX,
+/* 9 */ CEPH_MDS_OP_SETLAYOUT_STR_IDX,
+/* 10 */ CEPH_MDS_OP_SETATTR_STR_IDX,
+/* 11 */ CEPH_MDS_OP_SETFILELOCK_STR_IDX,
+/* 12 */ CEPH_MDS_OP_GETFILELOCK_STR_IDX,
+/* 13 */ CEPH_MDS_OP_SETDIRLAYOUT_STR_IDX,
+/* 14 */ CEPH_MDS_OP_MKNOD_STR_IDX,
+/* 15 */ CEPH_MDS_OP_LINK_STR_IDX,
+/* 16 */ CEPH_MDS_OP_UNLINK_STR_IDX,
+/* 17 */ CEPH_MDS_OP_RENAME_STR_IDX,
+/* 18 */ CEPH_MDS_OP_MKDIR_STR_IDX,
+/* 19 */ CEPH_MDS_OP_RMDIR_STR_IDX,
+/* 20 */ CEPH_MDS_OP_SYMLINK_STR_IDX,
+/* 21 */ CEPH_MDS_OP_CREATE_STR_IDX,
+/* 22 */ CEPH_MDS_OP_OPEN_STR_IDX,
+/* 23 */ CEPH_MDS_OP_READDIR_STR_IDX,
+/* 24 */ CEPH_MDS_OP_LOOKUPSNAP_STR_IDX,
+/* 25 */ CEPH_MDS_OP_MKSNAP_STR_IDX,
+/* 26 */ CEPH_MDS_OP_RMSNAP_STR_IDX,
+/* 27 */ CEPH_MDS_OP_LSSNAP_STR_IDX,
+/* 28 */ CEPH_MDS_OP_RENAMESNAP_STR_IDX,
+/* 29 */ CEPH_MDS_OP_UNKNOWN_NAME_STR_IDX
+};
+
extern const char *ceph_mds_op_name(int op);
#define CEPH_SETATTR_MODE (1 << 0)
@@ -739,19 +792,20 @@ int ceph_flags_to_mode(int flags);
int ceph_caps_for_mode(int mode);
enum {
- CEPH_CAP_OP_GRANT, /* mds->client grant */
- CEPH_CAP_OP_REVOKE, /* mds->client revoke */
- CEPH_CAP_OP_TRUNC, /* mds->client trunc notify */
- CEPH_CAP_OP_EXPORT, /* mds has exported the cap */
- CEPH_CAP_OP_IMPORT, /* mds has imported the cap */
- CEPH_CAP_OP_UPDATE, /* client->mds update */
- CEPH_CAP_OP_DROP, /* client->mds drop cap bits */
- CEPH_CAP_OP_FLUSH, /* client->mds cap writeback */
- CEPH_CAP_OP_FLUSH_ACK, /* mds->client flushed */
- CEPH_CAP_OP_FLUSHSNAP, /* client->mds flush snapped metadata */
- CEPH_CAP_OP_FLUSHSNAP_ACK, /* mds->client flushed snapped metadata */
- CEPH_CAP_OP_RELEASE, /* client->mds release (clean) cap */
- CEPH_CAP_OP_RENEW, /* client->mds renewal request */
+/* 0 */ CEPH_CAP_OP_GRANT, /* mds->client grant */
+/* 1 */ CEPH_CAP_OP_REVOKE, /* mds->client revoke */
+/* 2 */ CEPH_CAP_OP_TRUNC, /* mds->client trunc notify */
+/* 3 */ CEPH_CAP_OP_EXPORT, /* mds has exported the cap */
+/* 4 */ CEPH_CAP_OP_IMPORT, /* mds has imported the cap */
+/* 5 */ CEPH_CAP_OP_UPDATE, /* client->mds update */
+/* 6 */ CEPH_CAP_OP_DROP, /* client->mds drop cap bits */
+/* 7 */ CEPH_CAP_OP_FLUSH, /* client->mds cap writeback */
+/* 8 */ CEPH_CAP_OP_FLUSH_ACK, /* mds->client flushed */
+/* 9 */ CEPH_CAP_OP_FLUSHSNAP, /* client->mds flush snapped metadata */
+/* 10 */ CEPH_CAP_OP_FLUSHSNAP_ACK, /* mds->client flushed snapped metadata */
+/* 11 */ CEPH_CAP_OP_RELEASE, /* client->mds release (clean) cap */
+/* 12 */ CEPH_CAP_OP_RENEW, /* client->mds renewal request */
+/* 13 */ CEPH_CAP_OP_UNKNOWN_NAME
};
extern const char *ceph_cap_op_name(int op);
@@ -816,7 +870,15 @@ struct ceph_mds_cap_item {
#define CEPH_MDS_LEASE_RENEW 3 /* client <-> mds */
#define CEPH_MDS_LEASE_REVOKE_ACK 4 /* client -> mds */
-extern const char *ceph_lease_op_name(int o);
+enum {
+/* 0 */ CEPH_MDS_LEASE_REVOKE_STR_IDX,
+/* 1 */ CEPH_MDS_LEASE_RELEASE_STR_IDX,
+/* 2 */ CEPH_MDS_LEASE_RENEW_STR_IDX,
+/* 3 */ CEPH_MDS_LEASE_REVOKE_ACK_STR_IDX,
+/* 4 */ CEPH_MDS_LEASE_UNKNOWN_NAME_STR_IDX
+};
+
+extern const char *ceph_lease_op_name(int op);
/* lease msg header */
struct ceph_mds_lease {
@@ -860,10 +922,11 @@ struct ceph_mds_snaprealm_reconnect {
* snaps
*/
enum {
- CEPH_SNAP_OP_UPDATE, /* CREATE or DESTROY */
- CEPH_SNAP_OP_CREATE,
- CEPH_SNAP_OP_DESTROY,
- CEPH_SNAP_OP_SPLIT,
+/* 0 */ CEPH_SNAP_OP_UPDATE, /* CREATE or DESTROY */
+/* 1 */ CEPH_SNAP_OP_CREATE,
+/* 2 */ CEPH_SNAP_OP_DESTROY,
+/* 3 */ CEPH_SNAP_OP_SPLIT,
+/* 4 */ CEPH_SNAP_OP_UNKNOWN_NAME
};
extern const char *ceph_snap_op_name(int o);
--
2.51.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] ceph: introduce Kunit based unit-tests for string operations
2025-09-19 18:11 [PATCH] ceph: introduce Kunit based unit-tests for string operations Viacheslav Dubeyko
@ 2025-09-25 13:04 ` kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2025-09-25 13:04 UTC (permalink / raw)
To: Viacheslav Dubeyko, ceph-devel
Cc: oe-kbuild-all, idryomov, linux-fsdevel, pdonnell, amarkuze,
Slava.Dubeyko, slava, vdubeyko
Hi Viacheslav,
kernel test robot noticed the following build warnings:
[auto build test WARNING on ceph-client/testing]
[also build test WARNING on ceph-client/for-linus linus/master v6.17-rc7 next-20250924]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Viacheslav-Dubeyko/ceph-introduce-Kunit-based-unit-tests-for-string-operations/20250920-021357
base: https://github.com/ceph/ceph-client.git testing
patch link: https://lore.kernel.org/r/20250919181149.500408-2-slava%40dubeyko.com
patch subject: [PATCH] ceph: introduce Kunit based unit-tests for string operations
config: loongarch-randconfig-r133-20250925 (https://download.01.org/0day-ci/archive/20250925/202509252015.tfuSHe3S-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250925/202509252015.tfuSHe3S-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509252015.tfuSHe3S-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> fs/ceph/strings_test.c:102:11: sparse: sparse: symbol 'ceph_str_idx_2_mds_state' was not declared. Should it be static?
>> fs/ceph/strings_test.c:247:11: sparse: sparse: symbol 'ceph_str_idx_2_mds_op' was not declared. Should it be static?
>> fs/ceph/strings_test.c:459:11: sparse: sparse: symbol 'ceph_str_idx_2_lease_op' was not declared. Should it be static?
vim +/ceph_str_idx_2_mds_state +102 fs/ceph/strings_test.c
100
101 #define CEPH_MDS_STATE_STR_COUNT (CEPH_MDS_STATE_UNKNOWN_NAME_STR_IDX)
> 102 const int ceph_str_idx_2_mds_state[CEPH_MDS_STATE_STR_COUNT] = {
103 /* 0 */ CEPH_MDS_STATE_DNE,
104 /* 1 */ CEPH_MDS_STATE_STOPPED,
105 /* 2 */ CEPH_MDS_STATE_BOOT,
106 /* 3 */ CEPH_MDS_STATE_STANDBY,
107 /* 4 */ CEPH_MDS_STATE_STANDBY_REPLAY,
108 /* 5 */ CEPH_MDS_STATE_REPLAYONCE,
109 /* 6 */ CEPH_MDS_STATE_CREATING,
110 /* 7 */ CEPH_MDS_STATE_STARTING,
111 /* 8 */ CEPH_MDS_STATE_REPLAY,
112 /* 9 */ CEPH_MDS_STATE_RESOLVE,
113 /* 10 */ CEPH_MDS_STATE_RECONNECT,
114 /* 11 */ CEPH_MDS_STATE_REJOIN,
115 /* 12 */ CEPH_MDS_STATE_CLIENTREPLAY,
116 /* 13 */ CEPH_MDS_STATE_ACTIVE,
117 /* 14 */ CEPH_MDS_STATE_STOPPING
118 };
119
120 static int ceph_mds_state_next_op(int prev)
121 {
122 if (prev < CEPH_MDS_STATE_REPLAYONCE)
123 return CEPH_MDS_STATE_REPLAYONCE;
124
125 /* [-9..-4] */
126 if (prev >= CEPH_MDS_STATE_REPLAYONCE &&
127 prev < CEPH_MDS_STATE_BOOT)
128 return prev + 1;
129
130 /* [-4..-1] */
131 if (prev == CEPH_MDS_STATE_BOOT)
132 return CEPH_MDS_STATE_STOPPED;
133
134 /* [-1..0] */
135 if (prev >= CEPH_MDS_STATE_STOPPED &&
136 prev < CEPH_MDS_STATE_DNE)
137 return prev + 1;
138
139 /* [0..8] */
140 if (prev == CEPH_MDS_STATE_DNE)
141 return CEPH_MDS_STATE_REPLAY;
142
143 /* [8..14] */
144 if (prev >= CEPH_MDS_STATE_REPLAY &&
145 prev < CEPH_MDS_STATE_STOPPING)
146 return prev + 1;
147
148 return CEPH_MDS_STATE_STOPPING;
149 }
150
151 static void ceph_mds_state_name_test(struct kunit *test)
152 {
153 const char *unknown_name =
154 ceph_mds_state_name_strings[CEPH_MDS_STATE_UNKNOWN_NAME_STR_IDX];
155 struct ceph_op_iterator iter;
156 int start, end;
157 int i;
158
159 /* Test valid MDS states */
160 for (i = 0; i < CEPH_MDS_STATE_STR_COUNT; i++) {
161 KUNIT_EXPECT_STREQ(test,
162 ceph_mds_state_name(ceph_str_idx_2_mds_state[i]),
163 ceph_mds_state_name_strings[i]);
164 }
165
166 /* Test invalid/unknown states */
167 start = CEPH_MDS_STATE_REPLAYONCE - CEPH_KUNIT_STRINGS_TEST_RANGE;
168 end = CEPH_MDS_STATE_STOPPING + CEPH_KUNIT_STRINGS_TEST_RANGE;
169 ceph_op_iterator_init(&iter, start, end, ceph_mds_state_next_op);
170
171 while (ceph_op_iterator_valid(&iter)) {
172 switch (ceph_mds_state_2_str_idx(iter.cur)) {
173 case CEPH_MDS_STATE_UNKNOWN_NAME_STR_IDX:
174 KUNIT_EXPECT_STREQ(test,
175 ceph_mds_state_name(iter.cur),
176 unknown_name);
177 break;
178
179 default:
180 /* do nothing */
181 break;
182 }
183
184 ceph_op_iterator_next(&iter);
185 }
186
187 KUNIT_EXPECT_STREQ(test,
188 ceph_mds_state_name(CEPH_KUNIT_OP_INVALID_MIN),
189 unknown_name);
190 KUNIT_EXPECT_STREQ(test,
191 ceph_mds_state_name(CEPH_KUNIT_OP_INVALID_MAX),
192 unknown_name);
193 }
194
195 static int ceph_session_next_op(int prev)
196 {
197 return __ceph_next_op(prev,
198 CEPH_SESSION_REQUEST_OPEN,
199 CEPH_SESSION_REQUEST_FLUSH_MDLOG);
200 }
201
202 static void ceph_session_op_name_test(struct kunit *test)
203 {
204 const char *unknown_name =
205 ceph_session_op_name_strings[CEPH_SESSION_UNKNOWN_NAME];
206 struct ceph_op_iterator iter;
207 int start, end;
208 int i;
209
210 /* Test valid session operations */
211 for (i = CEPH_SESSION_REQUEST_OPEN; i < CEPH_SESSION_UNKNOWN_NAME; i++) {
212 KUNIT_EXPECT_STREQ(test,
213 ceph_session_op_name(i),
214 ceph_session_op_name_strings[i]);
215 }
216
217 /* Test invalid/unknown operations */
218 start = CEPH_SESSION_REQUEST_OPEN - CEPH_KUNIT_STRINGS_TEST_RANGE;
219 end = CEPH_SESSION_REQUEST_FLUSH_MDLOG + CEPH_KUNIT_STRINGS_TEST_RANGE;
220 ceph_op_iterator_init(&iter, start, end, ceph_session_next_op);
221
222 while (ceph_op_iterator_valid(&iter)) {
223 switch (ceph_session_op_2_str_idx(iter.cur)) {
224 case CEPH_SESSION_UNKNOWN_NAME:
225 KUNIT_EXPECT_STREQ(test,
226 ceph_session_op_name(iter.cur),
227 unknown_name);
228 break;
229
230 default:
231 /* do nothing */
232 break;
233 }
234
235 ceph_op_iterator_next(&iter);
236 }
237
238 KUNIT_EXPECT_STREQ(test,
239 ceph_session_op_name(CEPH_KUNIT_OP_INVALID_MIN),
240 unknown_name);
241 KUNIT_EXPECT_STREQ(test,
242 ceph_session_op_name(CEPH_KUNIT_OP_INVALID_MAX),
243 unknown_name);
244 }
245
246 #define CEPH_MDS_OP_STR_COUNT (CEPH_MDS_OP_UNKNOWN_NAME_STR_IDX)
> 247 const int ceph_str_idx_2_mds_op[CEPH_MDS_OP_STR_COUNT] = {
248 /* 0 */ CEPH_MDS_OP_LOOKUP,
249 /* 1 */ CEPH_MDS_OP_GETATTR,
250 /* 2 */ CEPH_MDS_OP_LOOKUPHASH,
251 /* 3 */ CEPH_MDS_OP_LOOKUPPARENT,
252 /* 4 */ CEPH_MDS_OP_LOOKUPINO,
253 /* 5 */ CEPH_MDS_OP_LOOKUPNAME,
254 /* 6 */ CEPH_MDS_OP_GETVXATTR,
255 /* 7 */ CEPH_MDS_OP_SETXATTR,
256 /* 8 */ CEPH_MDS_OP_RMXATTR,
257 /* 9 */ CEPH_MDS_OP_SETLAYOUT,
258 /* 10 */ CEPH_MDS_OP_SETATTR,
259 /* 11 */ CEPH_MDS_OP_SETFILELOCK,
260 /* 12 */ CEPH_MDS_OP_GETFILELOCK,
261 /* 13 */ CEPH_MDS_OP_SETDIRLAYOUT,
262 /* 14 */ CEPH_MDS_OP_MKNOD,
263 /* 15 */ CEPH_MDS_OP_LINK,
264 /* 16 */ CEPH_MDS_OP_UNLINK,
265 /* 17 */ CEPH_MDS_OP_RENAME,
266 /* 18 */ CEPH_MDS_OP_MKDIR,
267 /* 19 */ CEPH_MDS_OP_RMDIR,
268 /* 20 */ CEPH_MDS_OP_SYMLINK,
269 /* 21 */ CEPH_MDS_OP_CREATE,
270 /* 22 */ CEPH_MDS_OP_OPEN,
271 /* 23 */ CEPH_MDS_OP_READDIR,
272 /* 24 */ CEPH_MDS_OP_LOOKUPSNAP,
273 /* 25 */ CEPH_MDS_OP_MKSNAP,
274 /* 26 */ CEPH_MDS_OP_RMSNAP,
275 /* 27 */ CEPH_MDS_OP_LSSNAP,
276 /* 28 */ CEPH_MDS_OP_RENAMESNAP
277 };
278
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-09-25 13:05 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-19 18:11 [PATCH] ceph: introduce Kunit based unit-tests for string operations Viacheslav Dubeyko
2025-09-25 13:04 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).