All of lore.kernel.org
 help / color / mirror / Atom feed
* [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",
+			   &reg->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.