[PATCH 4/4] nvmet: prevent vid/ssvid changes for discovered subsystems

Max Gurtovoy mgurtovoy at nvidia.com
Wed Sep 24 13:26:04 PDT 2025


Disallow updates to the vendor_id and subsys_vendor_id attributes via
configfs after a subsystem has been discovered. This prevents invalid
configuration.
These attributes can now only be set on non-discovered subsystems,
ensuring consistent configuration state.

Signed-off-by: Max Gurtovoy <mgurtovoy at nvidia.com>
---
 drivers/nvme/target/configfs.c | 50 +++++++++++++++++++++++++++++++---
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index ac12326e036c..dab10825ca0b 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -1439,18 +1439,38 @@ static ssize_t nvmet_subsys_attr_vendor_id_show(struct config_item *item,
 	return snprintf(page, PAGE_SIZE, "0x%x\n", to_subsys(item)->vendor_id);
 }
 
+static ssize_t
+nvmet_subsys_attr_vendor_id_store_locked(struct nvmet_subsys *subsys,
+		u16 vid, size_t count)
+{
+	if (subsys->subsys_discovered) {
+		pr_err("Can't set vendor id. %u is already assigned\n",
+		       subsys->vendor_id);
+		return -EINVAL;
+	}
+
+	subsys->vendor_id = vid;
+
+	return count;
+}
+
 static ssize_t nvmet_subsys_attr_vendor_id_store(struct config_item *item,
 		const char *page, size_t count)
 {
+	struct nvmet_subsys *subsys = to_subsys(item);
 	u16 vid;
+	ssize_t ret;
 
 	if (kstrtou16(page, 0, &vid))
 		return -EINVAL;
 
 	down_write(&nvmet_config_sem);
-	to_subsys(item)->vendor_id = vid;
+	mutex_lock(&subsys->lock);
+	ret = nvmet_subsys_attr_vendor_id_store_locked(subsys, vid, count);
+	mutex_unlock(&subsys->lock);
 	up_write(&nvmet_config_sem);
-	return count;
+
+	return ret;
 }
 CONFIGFS_ATTR(nvmet_subsys_, attr_vendor_id);
 
@@ -1461,18 +1481,40 @@ static ssize_t nvmet_subsys_attr_subsys_vendor_id_show(struct config_item *item,
 			to_subsys(item)->subsys_vendor_id);
 }
 
+static ssize_t
+nvmet_subsys_attr_subsys_vendor_id_store_locked(struct nvmet_subsys *subsys,
+		u16 ssvid, size_t count)
+{
+	if (subsys->subsys_discovered) {
+		pr_err("Can't set subsystem vendor id. %u is already assigned\n",
+		       subsys->subsys_vendor_id);
+		return -EINVAL;
+	}
+
+	subsys->subsys_vendor_id = ssvid;
+
+	return count;
+}
+
 static ssize_t nvmet_subsys_attr_subsys_vendor_id_store(struct config_item *item,
 		const char *page, size_t count)
 {
+	struct nvmet_subsys *subsys = to_subsys(item);
 	u16 ssvid;
+	ssize_t ret;
 
 	if (kstrtou16(page, 0, &ssvid))
 		return -EINVAL;
 
 	down_write(&nvmet_config_sem);
-	to_subsys(item)->subsys_vendor_id = ssvid;
+	mutex_lock(&subsys->lock);
+	ret = nvmet_subsys_attr_subsys_vendor_id_store_locked(subsys,
+							      ssvid,
+							      count);
+	mutex_unlock(&subsys->lock);
 	up_write(&nvmet_config_sem);
-	return count;
+
+	return ret;
 }
 CONFIGFS_ATTR(nvmet_subsys_, attr_subsys_vendor_id);
 
-- 
2.18.1




More information about the Linux-nvme mailing list