* [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state
@ 2026-06-22 10:44 Guixin Liu
2026-06-22 10:44 ` [PATCH 1/2] nvmet: add namespace-level debugfs directory Guixin Liu
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Guixin Liu @ 2026-06-22 10:44 UTC (permalink / raw)
To: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Hannes Reinecke
Cc: linux-nvme
This series adds debugfs support for inspecting NVMe target reservation
(PR) state at the namespace level.
Patch 1 introduces per-namespace debugfs directories under each subsystem,
providing the infrastructure for namespace-specific debug entries.
Patch 2 adds a 'reservation' file that exposes the persistent reservation
state including enable status, generation counter, holder information, and
the full registrant list.
Example output with two registered hosts and an active holder:
$ cat /sys/kernel/debug/nvmet/testnqn/ns1/reservation
enable : 1
generation : 2
notify_mask : 0x0
rtype : write_exclusive
holder : hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
registrants:
hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
hostid=22222222-2222-2222-2222-222222222222, rkey=0x2222
Guixin Liu (2):
nvmet: add namespace-level debugfs directory
nvmet: expose reservation state through debugfs
drivers/nvme/target/core.c | 2 +
drivers/nvme/target/debugfs.c | 75 +++++++++++++++++++++++++++++++++++
drivers/nvme/target/debugfs.h | 5 +++
drivers/nvme/target/nvmet.h | 3 ++
4 files changed, 85 insertions(+)
--
2.43.7
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/2] nvmet: add namespace-level debugfs directory
2026-06-22 10:44 [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state Guixin Liu
@ 2026-06-22 10:44 ` Guixin Liu
2026-06-22 10:44 ` [PATCH 2/2] nvmet: expose reservation state through debugfs Guixin Liu
2026-06-25 7:17 ` [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state Daniel Wagner
2 siblings, 0 replies; 10+ messages in thread
From: Guixin Liu @ 2026-06-22 10:44 UTC (permalink / raw)
To: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Hannes Reinecke
Cc: linux-nvme
Add per-namespace debugfs directory support under the subsystem debugfs
directory. Each enabled namespace gets a ns<nsid>/ directory created
during nvmet_ns_enable() and removed during nvmet_ns_disable().
This provides the infrastructure for exposing namespace-specific debug
information in subsequent patches.
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
---
drivers/nvme/target/core.c | 2 ++
drivers/nvme/target/debugfs.c | 21 +++++++++++++++++++++
drivers/nvme/target/debugfs.h | 5 +++++
drivers/nvme/target/nvmet.h | 3 +++
4 files changed, 31 insertions(+)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 62dd59b9aa4f..9752913e05c6 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -616,6 +616,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
nvmet_ns_changed(subsys, ns->nsid);
ns->enabled = true;
xa_set_mark(&subsys->namespaces, ns->nsid, NVMET_NS_ENABLED);
+ nvmet_debugfs_ns_setup(ns);
ret = 0;
out_unlock:
mutex_unlock(&subsys->lock);
@@ -642,6 +643,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
ns->enabled = false;
xa_clear_mark(&subsys->namespaces, ns->nsid, NVMET_NS_ENABLED);
+ nvmet_debugfs_ns_free(ns);
list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
pci_dev_put(radix_tree_delete(&ctrl->p2p_ns_map, ns->nsid));
diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c
index 5dcbd5aa86e1..e6f51eb59010 100644
--- a/drivers/nvme/target/debugfs.c
+++ b/drivers/nvme/target/debugfs.c
@@ -153,6 +153,27 @@ static int nvmet_ctrl_tls_concat_show(struct seq_file *m, void *p)
NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_concat);
#endif
+void nvmet_debugfs_ns_setup(struct nvmet_ns *ns)
+{
+ char name[16];
+ struct dentry *parent = ns->subsys->debugfs_dir;
+
+ if (!parent)
+ return;
+ snprintf(name, sizeof(name), "ns%u", ns->nsid);
+ ns->debugfs_dir = debugfs_create_dir(name, parent);
+ if (IS_ERR(ns->debugfs_dir)) {
+ ns->debugfs_dir = NULL;
+ return;
+ }
+}
+
+void nvmet_debugfs_ns_free(struct nvmet_ns *ns)
+{
+ debugfs_remove_recursive(ns->debugfs_dir);
+ ns->debugfs_dir = NULL;
+}
+
int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl)
{
char name[32];
diff --git a/drivers/nvme/target/debugfs.h b/drivers/nvme/target/debugfs.h
index cfb8bbf6a297..b559d254fc2a 100644
--- a/drivers/nvme/target/debugfs.h
+++ b/drivers/nvme/target/debugfs.h
@@ -14,6 +14,8 @@ int nvmet_debugfs_subsys_setup(struct nvmet_subsys *subsys);
void nvmet_debugfs_subsys_free(struct nvmet_subsys *subsys);
int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl);
void nvmet_debugfs_ctrl_free(struct nvmet_ctrl *ctrl);
+void nvmet_debugfs_ns_setup(struct nvmet_ns *ns);
+void nvmet_debugfs_ns_free(struct nvmet_ns *ns);
int __init nvmet_init_debugfs(void);
void nvmet_exit_debugfs(void);
@@ -30,6 +32,9 @@ static inline int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl)
}
static inline void nvmet_debugfs_ctrl_free(struct nvmet_ctrl *ctrl) {}
+static inline void nvmet_debugfs_ns_setup(struct nvmet_ns *ns) {}
+static inline void nvmet_debugfs_ns_free(struct nvmet_ns *ns) {}
+
static inline int __init nvmet_init_debugfs(void)
{
return 0;
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 3305a88684ec..142a78d9160f 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -128,6 +128,9 @@ struct nvmet_ns {
u8 csi;
struct nvmet_pr pr;
struct xarray pr_per_ctrl_refs;
+#ifdef CONFIG_NVME_TARGET_DEBUGFS
+ struct dentry *debugfs_dir;
+#endif
};
static inline struct nvmet_ns *to_nvmet_ns(struct config_item *item)
--
2.43.7
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/2] nvmet: expose reservation state through debugfs
2026-06-22 10:44 [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state Guixin Liu
2026-06-22 10:44 ` [PATCH 1/2] nvmet: add namespace-level debugfs directory Guixin Liu
@ 2026-06-22 10:44 ` Guixin Liu
2026-06-25 7:17 ` [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state Daniel Wagner
2 siblings, 0 replies; 10+ messages in thread
From: Guixin Liu @ 2026-06-22 10:44 UTC (permalink / raw)
To: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Hannes Reinecke
Cc: linux-nvme
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@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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state
2026-06-22 10:44 [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state Guixin Liu
2026-06-22 10:44 ` [PATCH 1/2] nvmet: add namespace-level debugfs directory Guixin Liu
2026-06-22 10:44 ` [PATCH 2/2] nvmet: expose reservation state through debugfs Guixin Liu
@ 2026-06-25 7:17 ` Daniel Wagner
2026-06-25 9:10 ` Guixin Liu
2 siblings, 1 reply; 10+ messages in thread
From: Daniel Wagner @ 2026-06-25 7:17 UTC (permalink / raw)
To: Guixin Liu
Cc: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Hannes Reinecke, linux-nvme
On Mon, Jun 22, 2026 at 06:44:16PM +0800, Guixin Liu wrote:
> This series adds debugfs support for inspecting NVMe target reservation
> (PR) state at the namespace level.
>
> Patch 1 introduces per-namespace debugfs directories under each subsystem,
> providing the infrastructure for namespace-specific debug entries.
>
> Patch 2 adds a 'reservation' file that exposes the persistent reservation
> state including enable status, generation counter, holder information, and
> the full registrant list.
>
> Example output with two registered hosts and an active holder:
>
> $ cat /sys/kernel/debug/nvmet/testnqn/ns1/reservation
> enable : 1
> generation : 2
> notify_mask : 0x0
> rtype : write_exclusive
> holder : hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
> registrants:
> hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
> hostid=22222222-2222-2222-2222-222222222222, rkey=0x2222
I expect blktests will make use of this interface eventually. The parser
for this wont be dead simple, sure doable but not simple. If you see a
way to make a bit simpler I wouldn't mind.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state
2026-06-25 7:17 ` [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state Daniel Wagner
@ 2026-06-25 9:10 ` Guixin Liu
2026-07-06 3:10 ` Guixin Liu
0 siblings, 1 reply; 10+ messages in thread
From: Guixin Liu @ 2026-06-25 9:10 UTC (permalink / raw)
To: Daniel Wagner
Cc: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Hannes Reinecke, linux-nvme
在 2026/6/25 15:17, Daniel Wagner 写道:
> On Mon, Jun 22, 2026 at 06:44:16PM +0800, Guixin Liu wrote:
>> This series adds debugfs support for inspecting NVMe target reservation
>> (PR) state at the namespace level.
>>
>> Patch 1 introduces per-namespace debugfs directories under each subsystem,
>> providing the infrastructure for namespace-specific debug entries.
>>
>> Patch 2 adds a 'reservation' file that exposes the persistent reservation
>> state including enable status, generation counter, holder information, and
>> the full registrant list.
>>
>> Example output with two registered hosts and an active holder:
>>
>> $ cat /sys/kernel/debug/nvmet/testnqn/ns1/reservation
>> enable : 1
>> generation : 2
>> notify_mask : 0x0
>> rtype : write_exclusive
>> holder : hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
>> registrants:
>> hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
>> hostid=22222222-2222-2222-2222-222222222222, rkey=0x2222
> I expect blktests will make use of this interface eventually. The parser
> for this wont be dead simple, sure doable but not simple. If you see a
> way to make a bit simpler I wouldn't mind.
How about this:
1. One holer, multi registrants:
enable=1
generation=2
notify_mask=0x0
rtype=write_exclusive
holder=11111111-1111-1111-1111-111111111111,0x1111
reg=11111111-1111-1111-1111-111111111111,0x1111
reg=22222222-2222-2222-2222-222222222222,0x2222
2. No holder, multi registrants:
enable=1
generation=1
notify_mask=0x0
rtype=none
holder=none
reg=11111111-1111-1111-1111-111111111111,0x1111
reg=22222222-2222-2222-2222-222222222222,0x2222
3. No registrant:
enable=1
generation=0
notify_mask=0x0
rtype=none
holder=none
4. Reservation not enabled:
enable=0
Otherwise, the notify_mask can be stringization:
notify_mask=reg_preempted,resv_released,resv_preempted
Best Regards,
Guixin Liu
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state
2026-06-25 9:10 ` Guixin Liu
@ 2026-07-06 3:10 ` Guixin Liu
2026-07-06 7:59 ` Daniel Wagner
0 siblings, 1 reply; 10+ messages in thread
From: Guixin Liu @ 2026-07-06 3:10 UTC (permalink / raw)
To: Daniel Wagner
Cc: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Hannes Reinecke, linux-nvme
在 2026/6/25 17:10, Guixin Liu 写道:
>
>
> 在 2026/6/25 15:17, Daniel Wagner 写道:
>> On Mon, Jun 22, 2026 at 06:44:16PM +0800, Guixin Liu wrote:
>>> This series adds debugfs support for inspecting NVMe target reservation
>>> (PR) state at the namespace level.
>>>
>>> Patch 1 introduces per-namespace debugfs directories under each
>>> subsystem,
>>> providing the infrastructure for namespace-specific debug entries.
>>>
>>> Patch 2 adds a 'reservation' file that exposes the persistent
>>> reservation
>>> state including enable status, generation counter, holder
>>> information, and
>>> the full registrant list.
>>>
>>> Example output with two registered hosts and an active holder:
>>>
>>> $ cat /sys/kernel/debug/nvmet/testnqn/ns1/reservation
>>> enable : 1
>>> generation : 2
>>> notify_mask : 0x0
>>> rtype : write_exclusive
>>> holder : hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
>>> registrants:
>>> hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
>>> hostid=22222222-2222-2222-2222-222222222222, rkey=0x2222
>> I expect blktests will make use of this interface eventually. The parser
>> for this wont be dead simple, sure doable but not simple. If you see a
>> way to make a bit simpler I wouldn't mind.
> How about this:
>
> 1. One holer, multi registrants:
> enable=1
> generation=2
> notify_mask=0x0
> rtype=write_exclusive
> holder=11111111-1111-1111-1111-111111111111,0x1111
> reg=11111111-1111-1111-1111-111111111111,0x1111
> reg=22222222-2222-2222-2222-222222222222,0x2222
>
> 2. No holder, multi registrants:
> enable=1
> generation=1
> notify_mask=0x0
> rtype=none
> holder=none
> reg=11111111-1111-1111-1111-111111111111,0x1111
> reg=22222222-2222-2222-2222-222222222222,0x2222
>
> 3. No registrant:
> enable=1
> generation=0
> notify_mask=0x0
> rtype=none
> holder=none
>
> 4. Reservation not enabled:
> enable=0
>
> Otherwise, the notify_mask can be stringization:
>
> notify_mask=reg_preempted,resv_released,resv_preempted
>
> Best Regards,
> Guixin Liu
>
Hi Daniel,
What do you think?
Best Regards,
Guixin Liu
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state
2026-07-06 3:10 ` Guixin Liu
@ 2026-07-06 7:59 ` Daniel Wagner
2026-07-06 10:28 ` Guixin Liu
0 siblings, 1 reply; 10+ messages in thread
From: Daniel Wagner @ 2026-07-06 7:59 UTC (permalink / raw)
To: Guixin Liu
Cc: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Hannes Reinecke, linux-nvme
On Mon, Jul 06, 2026 at 11:10:41AM +0800, Guixin Liu wrote:
> > > > Example output with two registered hosts and an active holder:
> > > >
> > > > $ cat /sys/kernel/debug/nvmet/testnqn/ns1/reservation
> > > > enable : 1
> > > > generation : 2
> > > > notify_mask : 0x0
> > > > rtype : write_exclusive
> > > > holder : hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
> > > > registrants:
> > > > hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
> > > > hostid=22222222-2222-2222-2222-222222222222, rkey=0x2222
> > > I expect blktests will make use of this interface eventually. The parser
> > > for this wont be dead simple, sure doable but not simple. If you see a
> > > way to make a bit simpler I wouldn't mind.
> > How about this:
> >
> > 1. One holer, multi registrants:
> > enable=1
> > generation=2
> > notify_mask=0x0
> > rtype=write_exclusive
> > holder=11111111-1111-1111-1111-111111111111,0x1111
> > reg=11111111-1111-1111-1111-111111111111,0x1111
> > reg=22222222-2222-2222-2222-222222222222,0x2222
> >
> > 2. No holder, multi registrants:
> > enable=1
> > generation=1
> > notify_mask=0x0
> > rtype=none
> > holder=none
> > reg=11111111-1111-1111-1111-111111111111,0x1111
> > reg=22222222-2222-2222-2222-222222222222,0x2222
> >
> > 3. No registrant:
> > enable=1
> > generation=0
> > notify_mask=0x0
> > rtype=none
> > holder=none
> >
> > 4. Reservation not enabled:
> > enable=0
> >
> > Otherwise, the notify_mask can be stringization:
> >
> > notify_mask=reg_preempted,resv_released,resv_preempted
Sorry, missed your previous post. This looks easier to parser (*), but I
think it's up to Shiinchiro to make the call.
Thanks,
Daniel
(*) I asked a LLM to generate one and it looks straight forward.
#!/bin/bash
# Clean plaintext data with email/quote formatting completely removed
DATA=$(cat << 'EOF'
19 enable=1
20 generation=2
21 notify_mask=0x0
22 rtype=write_exclusive
23 holder=11111111-1111-1111-1111-111111111111,0x1111
24 reg=11111111-1111-1111-1111-111111111111,0x1111
25 reg=22222222-2222-2222-2222-222222222222,0x2222
26
27 2. No holder, multi registrants:
28 enable=1
29 generation=1
30 notify_mask=0x0
31 rtype=none
32 holder=none
33 reg=11111111-1111-1111-1111-111111111111,0x1111
34 reg=22222222-2222-2222-2222-222222222222,0x2222
35
36 3. No registrant:
37 enable=1
38 generation=0
39 notify_mask=0x0
40 rtype=none
41 holder=none
42
43 4. Reservation not enabled:
44 enable=0
EOF
)
# Declare an associative array to store parsed data
declare -A INI_DATA
# Tracks the active section namespace
current_section="1. Default"
# Read line-by-line
while IFS= read -r raw_line; do
# Strip leading line numbers (e.g., " 19 ") and trim surrounding spaces
line=$(echo "$raw_line" | sed -E 's/^[[:space:]]*[0-9]+[[:space:]]+//; s/^[[:space:]]+//; s/[[:space:]]+$//')
# Skip empty lines
[[ -z "$line" ]] && continue
# Check if the line is a section header (e.g., "2. No holder, multi registrants:")
if [[ "$line" =~ ^[0-9]+\. ]]; then
current_section="$line"
continue
fi
# Parse Key=Value configurations
if [[ "$line" == *"="* ]]; then
key="${line%%=*}"
val="${line#*=}"
# Build a compound key: "SectionName|||KeyName"
map_key="${current_section}|||${key}"
# If key already exists in this section, append value using a pipe '|' delimiter
if [[ -n "${INI_DATA[$map_key]}" ]]; then
INI_DATA[$map_key]+="|$val"
else
INI_DATA[$map_key]="$val"
fi
fi
done <<< "$DATA"
# --- Demonstrate Accessing the Generated Arrays ---
echo "=== PARSED DATA STRUCTURE ==="
for compound_key in "${!INI_DATA[@]}"; do
section="${compound_key%%|||*}"
key="${compound_key##*|||}"
raw_value="${INI_DATA[$compound_key]}"
echo "[$section]"
# If the value contains our delimiter '|', turn it into a real Bash array
if [[ "$raw_value" == *"|"* ]]; then
IFS='|' read -r -a val_array <<< "$raw_value"
echo " Key '$key' is an ARRAY (${#val_array[@]} elements):"
for i in "${!val_array[@]}"; do
echo " -> index [$i]: ${val_array[$i]}"
done
else
echo " Key '$key' is a STRING:"
echo " -> value: $raw_value"
fi
echo "----------------------------------------"
done
=== PARSED DATA STRUCTURE ===
[3. No registrant:]
Key 'rtype' is a STRING:
-> value: none
----------------------------------------
[3. No registrant:]
Key 'generation' is a STRING:
-> value: 0
----------------------------------------
[1. Default]
Key 'generation' is a STRING:
-> value: 2
----------------------------------------
[2. No holder, multi registrants:]
Key 'holder' is a STRING:
-> value: none
----------------------------------------
[2. No holder, multi registrants:]
Key 'reg' is an ARRAY (2 elements):
-> index [0]: 11111111-1111-1111-1111-111111111111,0x1111
-> index [1]: 22222222-2222-2222-2222-222222222222,0x2222
----------------------------------------
[2. No holder, multi registrants:]
Key 'enable' is a STRING:
-> value: 1
----------------------------------------
[1. Default]
Key 'enable' is a STRING:
-> value: 1
----------------------------------------
[1. Default]
Key 'notify_mask' is a STRING:
-> value: 0x0
----------------------------------------
[2. No holder, multi registrants:]
Key 'generation' is a STRING:
-> value: 1
----------------------------------------
[3. No registrant:]
Key 'notify_mask' is a STRING:
-> value: 0x0
----------------------------------------
[1. Default]
Key 'holder' is a STRING:
-> value: 11111111-1111-1111-1111-111111111111,0x1111
----------------------------------------
[3. No registrant:]
Key 'holder' is a STRING:
-> value: none
----------------------------------------
[2. No holder, multi registrants:]
Key 'rtype' is a STRING:
-> value: none
----------------------------------------
[3. No registrant:]
Key 'enable' is a STRING:
-> value: 1
----------------------------------------
[4. Reservation not enabled:]
Key 'enable' is a STRING:
-> value: 0
----------------------------------------
[1. Default]
Key 'rtype' is a STRING:
-> value: write_exclusive
----------------------------------------
[2. No holder, multi registrants:]
Key 'notify_mask' is a STRING:
-> value: 0x0
----------------------------------------
[1. Default]
Key 'reg' is an ARRAY (2 elements):
-> index [0]: 11111111-1111-1111-1111-111111111111,0x1111
-> index [1]: 22222222-2222-2222-2222-222222222222,0x2222
----------------------------------------
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state
2026-07-06 7:59 ` Daniel Wagner
@ 2026-07-06 10:28 ` Guixin Liu
2026-07-06 12:57 ` Shin'ichiro Kawasaki
0 siblings, 1 reply; 10+ messages in thread
From: Guixin Liu @ 2026-07-06 10:28 UTC (permalink / raw)
To: Daniel Wagner, Shin'ichiro Kawasaki
Cc: Christoph Hellwig, Sagi Grimberg, Chaitanya Kulkarni,
Hannes Reinecke, linux-nvme
在 2026/7/6 15:59, Daniel Wagner 写道:
> On Mon, Jul 06, 2026 at 11:10:41AM +0800, Guixin Liu wrote:
>>>>> Example output with two registered hosts and an active holder:
>>>>>
>>>>> $ cat /sys/kernel/debug/nvmet/testnqn/ns1/reservation
>>>>> enable : 1
>>>>> generation : 2
>>>>> notify_mask : 0x0
>>>>> rtype : write_exclusive
>>>>> holder : hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
>>>>> registrants:
>>>>> hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
>>>>> hostid=22222222-2222-2222-2222-222222222222, rkey=0x2222
>>>> I expect blktests will make use of this interface eventually. The parser
>>>> for this wont be dead simple, sure doable but not simple. If you see a
>>>> way to make a bit simpler I wouldn't mind.
>>> How about this:
>>>
>>> 1. One holer, multi registrants:
>>> enable=1
>>> generation=2
>>> notify_mask=0x0
>>> rtype=write_exclusive
>>> holder=11111111-1111-1111-1111-111111111111,0x1111
>>> reg=11111111-1111-1111-1111-111111111111,0x1111
>>> reg=22222222-2222-2222-2222-222222222222,0x2222
>>>
>>> 2. No holder, multi registrants:
>>> enable=1
>>> generation=1
>>> notify_mask=0x0
>>> rtype=none
>>> holder=none
>>> reg=11111111-1111-1111-1111-111111111111,0x1111
>>> reg=22222222-2222-2222-2222-222222222222,0x2222
>>>
>>> 3. No registrant:
>>> enable=1
>>> generation=0
>>> notify_mask=0x0
>>> rtype=none
>>> holder=none
>>>
>>> 4. Reservation not enabled:
>>> enable=0
>>>
>>> Otherwise, the notify_mask can be stringization:
>>>
>>> notify_mask=reg_preempted,resv_released,resv_preempted
> Sorry, missed your previous post. This looks easier to parser (*), but I
> think it's up to Shiinchiro to make the call.
>
> Thanks,
> Daniel
>
> (*) I asked a LLM to generate one and it looks straight forward.
>
> #!/bin/bash
>
> # Clean plaintext data with email/quote formatting completely removed
> DATA=$(cat << 'EOF'
> 19 enable=1
> 20 generation=2
> 21 notify_mask=0x0
> 22 rtype=write_exclusive
> 23 holder=11111111-1111-1111-1111-111111111111,0x1111
> 24 reg=11111111-1111-1111-1111-111111111111,0x1111
> 25 reg=22222222-2222-2222-2222-222222222222,0x2222
> 26
> 27 2. No holder, multi registrants:
> 28 enable=1
> 29 generation=1
> 30 notify_mask=0x0
> 31 rtype=none
> 32 holder=none
> 33 reg=11111111-1111-1111-1111-111111111111,0x1111
> 34 reg=22222222-2222-2222-2222-222222222222,0x2222
> 35
> 36 3. No registrant:
> 37 enable=1
> 38 generation=0
> 39 notify_mask=0x0
> 40 rtype=none
> 41 holder=none
> 42
> 43 4. Reservation not enabled:
> 44 enable=0
> EOF
> )
>
> # Declare an associative array to store parsed data
> declare -A INI_DATA
>
> # Tracks the active section namespace
> current_section="1. Default"
>
> # Read line-by-line
> while IFS= read -r raw_line; do
> # Strip leading line numbers (e.g., " 19 ") and trim surrounding spaces
> line=$(echo "$raw_line" | sed -E 's/^[[:space:]]*[0-9]+[[:space:]]+//; s/^[[:space:]]+//; s/[[:space:]]+$//')
>
> # Skip empty lines
> [[ -z "$line" ]] && continue
>
> # Check if the line is a section header (e.g., "2. No holder, multi registrants:")
> if [[ "$line" =~ ^[0-9]+\. ]]; then
> current_section="$line"
> continue
> fi
>
> # Parse Key=Value configurations
> if [[ "$line" == *"="* ]]; then
> key="${line%%=*}"
> val="${line#*=}"
>
> # Build a compound key: "SectionName|||KeyName"
> map_key="${current_section}|||${key}"
>
> # If key already exists in this section, append value using a pipe '|' delimiter
> if [[ -n "${INI_DATA[$map_key]}" ]]; then
> INI_DATA[$map_key]+="|$val"
> else
> INI_DATA[$map_key]="$val"
> fi
> fi
> done <<< "$DATA"
>
> # --- Demonstrate Accessing the Generated Arrays ---
> echo "=== PARSED DATA STRUCTURE ==="
>
> for compound_key in "${!INI_DATA[@]}"; do
> section="${compound_key%%|||*}"
> key="${compound_key##*|||}"
> raw_value="${INI_DATA[$compound_key]}"
>
> echo "[$section]"
>
> # If the value contains our delimiter '|', turn it into a real Bash array
> if [[ "$raw_value" == *"|"* ]]; then
> IFS='|' read -r -a val_array <<< "$raw_value"
> echo " Key '$key' is an ARRAY (${#val_array[@]} elements):"
> for i in "${!val_array[@]}"; do
> echo " -> index [$i]: ${val_array[$i]}"
> done
> else
> echo " Key '$key' is a STRING:"
> echo " -> value: $raw_value"
> fi
> echo "----------------------------------------"
> done
>
>
> === PARSED DATA STRUCTURE ===
> [3. No registrant:]
> Key 'rtype' is a STRING:
> -> value: none
> ----------------------------------------
> [3. No registrant:]
> Key 'generation' is a STRING:
> -> value: 0
> ----------------------------------------
> [1. Default]
> Key 'generation' is a STRING:
> -> value: 2
> ----------------------------------------
> [2. No holder, multi registrants:]
> Key 'holder' is a STRING:
> -> value: none
> ----------------------------------------
> [2. No holder, multi registrants:]
> Key 'reg' is an ARRAY (2 elements):
> -> index [0]: 11111111-1111-1111-1111-111111111111,0x1111
> -> index [1]: 22222222-2222-2222-2222-222222222222,0x2222
> ----------------------------------------
> [2. No holder, multi registrants:]
> Key 'enable' is a STRING:
> -> value: 1
> ----------------------------------------
> [1. Default]
> Key 'enable' is a STRING:
> -> value: 1
> ----------------------------------------
> [1. Default]
> Key 'notify_mask' is a STRING:
> -> value: 0x0
> ----------------------------------------
> [2. No holder, multi registrants:]
> Key 'generation' is a STRING:
> -> value: 1
> ----------------------------------------
> [3. No registrant:]
> Key 'notify_mask' is a STRING:
> -> value: 0x0
> ----------------------------------------
> [1. Default]
> Key 'holder' is a STRING:
> -> value: 11111111-1111-1111-1111-111111111111,0x1111
> ----------------------------------------
> [3. No registrant:]
> Key 'holder' is a STRING:
> -> value: none
> ----------------------------------------
> [2. No holder, multi registrants:]
> Key 'rtype' is a STRING:
> -> value: none
> ----------------------------------------
> [3. No registrant:]
> Key 'enable' is a STRING:
> -> value: 1
> ----------------------------------------
> [4. Reservation not enabled:]
> Key 'enable' is a STRING:
> -> value: 0
> ----------------------------------------
> [1. Default]
> Key 'rtype' is a STRING:
> -> value: write_exclusive
> ----------------------------------------
> [2. No holder, multi registrants:]
> Key 'notify_mask' is a STRING:
> -> value: 0x0
> ----------------------------------------
> [1. Default]
> Key 'reg' is an ARRAY (2 elements):
> -> index [0]: 11111111-1111-1111-1111-111111111111,0x1111
> -> index [1]: 22222222-2222-2222-2222-222222222222,0x2222
> ----------------------------------------
OK, this seems feasible.
Hi Shin'ichiro:
Does this work for you?
Best Regards,
Guixin Liu
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state
2026-07-06 10:28 ` Guixin Liu
@ 2026-07-06 12:57 ` Shin'ichiro Kawasaki
2026-07-07 1:42 ` Guixin Liu
0 siblings, 1 reply; 10+ messages in thread
From: Shin'ichiro Kawasaki @ 2026-07-06 12:57 UTC (permalink / raw)
To: Guixin Liu
Cc: Daniel Wagner, Christoph Hellwig, Sagi Grimberg,
Chaitanya Kulkarni, Hannes Reinecke, linux-nvme
On Jul 06, 2026 / 18:28, Guixin Liu wrote:
>
>
> 在 2026/7/6 15:59, Daniel Wagner 写道:
> > On Mon, Jul 06, 2026 at 11:10:41AM +0800, Guixin Liu wrote:
> > > > > > Example output with two registered hosts and an active holder:
> > > > > >
> > > > > > $ cat /sys/kernel/debug/nvmet/testnqn/ns1/reservation
> > > > > > enable : 1
> > > > > > generation : 2
> > > > > > notify_mask : 0x0
> > > > > > rtype : write_exclusive
> > > > > > holder : hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
> > > > > > registrants:
> > > > > > hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
> > > > > > hostid=22222222-2222-2222-2222-222222222222, rkey=0x2222
> > > > > I expect blktests will make use of this interface eventually. The parser
> > > > > for this wont be dead simple, sure doable but not simple. If you see a
> > > > > way to make a bit simpler I wouldn't mind.
> > > > How about this:
> > > >
> > > > 1. One holer, multi registrants:
> > > > enable=1
> > > > generation=2
> > > > notify_mask=0x0
> > > > rtype=write_exclusive
> > > > holder=11111111-1111-1111-1111-111111111111,0x1111
> > > > reg=11111111-1111-1111-1111-111111111111,0x1111
> > > > reg=22222222-2222-2222-2222-222222222222,0x2222
> > > >
> > > > 2. No holder, multi registrants:
> > > > enable=1
> > > > generation=1
> > > > notify_mask=0x0
> > > > rtype=none
> > > > holder=none
> > > > reg=11111111-1111-1111-1111-111111111111,0x1111
> > > > reg=22222222-2222-2222-2222-222222222222,0x2222
> > > >
> > > > 3. No registrant:
> > > > enable=1
> > > > generation=0
> > > > notify_mask=0x0
> > > > rtype=none
> > > > holder=none
> > > >
> > > > 4. Reservation not enabled:
> > > > enable=0
...
> Hi Shin'ichiro:
> Does this work for you?
Hi Guixin, yes, I think it is good enough. If this is sysfs, "one value
per file" and "array by files in a directory" would be guided, but this is
debugfs readonly data. So, it sounds reasonable to put some data structure into
a single debufs attribute file. Uevent like key=value format sounds good. It is
a bit wacky to use comma to hold both host id and key for a holder and a
registrant, but I cannot think of better solution.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state
2026-07-06 12:57 ` Shin'ichiro Kawasaki
@ 2026-07-07 1:42 ` Guixin Liu
0 siblings, 0 replies; 10+ messages in thread
From: Guixin Liu @ 2026-07-07 1:42 UTC (permalink / raw)
To: Shin'ichiro Kawasaki
Cc: Daniel Wagner, Christoph Hellwig, Sagi Grimberg,
Chaitanya Kulkarni, Hannes Reinecke, linux-nvme
在 2026/7/6 20:57, Shin'ichiro Kawasaki 写道:
> On Jul 06, 2026 / 18:28, Guixin Liu wrote:
>>
>> 在 2026/7/6 15:59, Daniel Wagner 写道:
>>> On Mon, Jul 06, 2026 at 11:10:41AM +0800, Guixin Liu wrote:
>>>>>>> Example output with two registered hosts and an active holder:
>>>>>>>
>>>>>>> $ cat /sys/kernel/debug/nvmet/testnqn/ns1/reservation
>>>>>>> enable : 1
>>>>>>> generation : 2
>>>>>>> notify_mask : 0x0
>>>>>>> rtype : write_exclusive
>>>>>>> holder : hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
>>>>>>> registrants:
>>>>>>> hostid=11111111-1111-1111-1111-111111111111, rkey=0x1111
>>>>>>> hostid=22222222-2222-2222-2222-222222222222, rkey=0x2222
>>>>>> I expect blktests will make use of this interface eventually. The parser
>>>>>> for this wont be dead simple, sure doable but not simple. If you see a
>>>>>> way to make a bit simpler I wouldn't mind.
>>>>> How about this:
>>>>>
>>>>> 1. One holer, multi registrants:
>>>>> enable=1
>>>>> generation=2
>>>>> notify_mask=0x0
>>>>> rtype=write_exclusive
>>>>> holder=11111111-1111-1111-1111-111111111111,0x1111
>>>>> reg=11111111-1111-1111-1111-111111111111,0x1111
>>>>> reg=22222222-2222-2222-2222-222222222222,0x2222
>>>>>
>>>>> 2. No holder, multi registrants:
>>>>> enable=1
>>>>> generation=1
>>>>> notify_mask=0x0
>>>>> rtype=none
>>>>> holder=none
>>>>> reg=11111111-1111-1111-1111-111111111111,0x1111
>>>>> reg=22222222-2222-2222-2222-222222222222,0x2222
>>>>>
>>>>> 3. No registrant:
>>>>> enable=1
>>>>> generation=0
>>>>> notify_mask=0x0
>>>>> rtype=none
>>>>> holder=none
>>>>>
>>>>> 4. Reservation not enabled:
>>>>> enable=0
> ...
>> Hi Shin'ichiro:
>> Does this work for you?
> Hi Guixin, yes, I think it is good enough. If this is sysfs, "one value
> per file" and "array by files in a directory" would be guided, but this is
> debugfs readonly data. So, it sounds reasonable to put some data structure into
> a single debufs attribute file. Uevent like key=value format sounds good. It is
> a bit wacky to use comma to hold both host id and key for a holder and a
> registrant, but I cannot think of better solution.
OK, I will change this in v2, thanks.
Best Regards,
Guixin Liu
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-07-07 1:42 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-22 10:44 [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state Guixin Liu
2026-06-22 10:44 ` [PATCH 1/2] nvmet: add namespace-level debugfs directory Guixin Liu
2026-06-22 10:44 ` [PATCH 2/2] nvmet: expose reservation state through debugfs Guixin Liu
2026-06-25 7:17 ` [PATCH 0/2] nvmet: add namespace-level debugfs for reservation state Daniel Wagner
2026-06-25 9:10 ` Guixin Liu
2026-07-06 3:10 ` Guixin Liu
2026-07-06 7:59 ` Daniel Wagner
2026-07-06 10:28 ` Guixin Liu
2026-07-06 12:57 ` Shin'ichiro Kawasaki
2026-07-07 1:42 ` Guixin Liu
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.