[PATCH 2/2] nvmet: expose reservation state through debugfs
Guixin Liu
kanie at linux.alibaba.com
Mon Jun 22 03:44:18 PDT 2026
Add a 'reservation' debugfs file under each namespace directory that
shows the persistent reservation state, including enable status,
generation counter, notify mask, current holder info, and the full
registrant list with hostid and reservation key.
The output uses rcu_read_lock() for safe access to the holder and
registrant_list, consistent with other PR read paths.
Signed-off-by: Guixin Liu <kanie at linux.alibaba.com>
---
drivers/nvme/target/debugfs.c | 54 +++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c
index e6f51eb59010..96d81d446d13 100644
--- a/drivers/nvme/target/debugfs.c
+++ b/drivers/nvme/target/debugfs.c
@@ -153,6 +153,58 @@ static int nvmet_ctrl_tls_concat_show(struct seq_file *m, void *p)
NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_concat);
#endif
+static const char *const nvmet_pr_type_names[] = {
+ [NVME_PR_WRITE_EXCLUSIVE] = "write_exclusive",
+ [NVME_PR_EXCLUSIVE_ACCESS] = "exclusive_access",
+ [NVME_PR_WRITE_EXCLUSIVE_REG_ONLY] = "write_exclusive_reg_only",
+ [NVME_PR_EXCLUSIVE_ACCESS_REG_ONLY] = "exclusive_access_reg_only",
+ [NVME_PR_WRITE_EXCLUSIVE_ALL_REGS] = "write_exclusive_all_regs",
+ [NVME_PR_EXCLUSIVE_ACCESS_ALL_REGS] = "exclusive_access_all_regs",
+};
+
+static const char *nvmet_pr_type_to_str(enum nvme_pr_type type)
+{
+ if (type < ARRAY_SIZE(nvmet_pr_type_names) &&
+ nvmet_pr_type_names[type])
+ return nvmet_pr_type_names[type];
+ return "unknown";
+}
+
+static int nvmet_ns_pr_show(struct seq_file *m, void *p)
+{
+ struct nvmet_ns *ns = m->private;
+ struct nvmet_pr *pr = &ns->pr;
+ struct nvmet_pr_registrant *holder, *reg;
+
+ seq_printf(m, "enable : %d\n", pr->enable);
+ if (!pr->enable)
+ return 0;
+
+ seq_printf(m, "generation : %u\n", atomic_read(&pr->generation));
+ seq_printf(m, "notify_mask : 0x%lx\n", pr->notify_mask);
+
+ rcu_read_lock();
+ holder = rcu_dereference(pr->holder);
+ if (holder) {
+ seq_printf(m, "rtype : %s\n",
+ nvmet_pr_type_to_str(holder->rtype));
+ seq_printf(m, "holder : hostid=%pUb, rkey=0x%llx\n",
+ &holder->hostid, holder->rkey);
+ } else {
+ seq_puts(m, "holder : none\n");
+ }
+
+ seq_puts(m, "registrants:\n");
+ list_for_each_entry_rcu(reg, &pr->registrant_list, entry) {
+ seq_printf(m, " hostid=%pUb, rkey=0x%llx\n",
+ ®->hostid, reg->rkey);
+ }
+ rcu_read_unlock();
+
+ return 0;
+}
+NVMET_DEBUGFS_ATTR(nvmet_ns_pr);
+
void nvmet_debugfs_ns_setup(struct nvmet_ns *ns)
{
char name[16];
@@ -166,6 +218,8 @@ void nvmet_debugfs_ns_setup(struct nvmet_ns *ns)
ns->debugfs_dir = NULL;
return;
}
+ debugfs_create_file("reservation", 0400, ns->debugfs_dir, ns,
+ &nvmet_ns_pr_fops);
}
void nvmet_debugfs_ns_free(struct nvmet_ns *ns)
--
2.43.7
More information about the Linux-nvme
mailing list