Commit 7ae023c5 authored by Noam Gottlieb's avatar Noam Gottlieb Committed by Christoph Hellwig
Browse files

nvmet: make sn stable once connection was established



Once some host has connected to the target, make sure that the serial
number is stable and cannot be changed.

Reviewed-by: default avatarMax Gurtovoy <mgurtovoy@nvidia.com>
Signed-off-by: default avatarNoam Gottlieb <ngottlieb@nvidia.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent e13b0615
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -337,6 +337,12 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
	u32 cmd_capsule_size;
	u16 status = 0;

	if (!subsys->subsys_discovered) {
		mutex_lock(&subsys->lock);
		subsys->subsys_discovered = true;
		mutex_unlock(&subsys->lock);
	}

	/*
	 * If there is no model number yet, set it now.  It will then remain
	 * stable for the life time of the subsystem.
+22 −5
Original line number Diff line number Diff line
@@ -1044,12 +1044,18 @@ static ssize_t nvmet_subsys_attr_serial_show(struct config_item *item,
	return snprintf(page, PAGE_SIZE, "%s\n", subsys->serial);
}

static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item,
static ssize_t
nvmet_subsys_attr_serial_store_locked(struct nvmet_subsys *subsys,
		const char *page, size_t count)
{
	struct nvmet_subsys *subsys = to_subsys(item);
	int pos, len = strcspn(page, "\n");

	if (subsys->subsys_discovered) {
		pr_err("Can't set serial number. %s is already assigned\n",
		       subsys->serial);
		return -EINVAL;
	}

	if (!len || len > NVMET_SN_MAX_SIZE) {
		pr_err("Serial Number can not be empty or exceed %d Bytes\n",
		       NVMET_SN_MAX_SIZE);
@@ -1063,13 +1069,24 @@ static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item,
		}
	}

	memcpy_and_pad(subsys->serial, NVMET_SN_MAX_SIZE, page, len, ' ');

	return count;
}

static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item,
					      const char *page, size_t count)
{
	struct nvmet_subsys *subsys = to_subsys(item);
	ssize_t ret;

	down_write(&nvmet_config_sem);
	mutex_lock(&subsys->lock);
	memcpy_and_pad(subsys->serial, NVMET_SN_MAX_SIZE, page, len, ' ');
	ret = nvmet_subsys_attr_serial_store_locked(subsys, page, count);
	mutex_unlock(&subsys->lock);
	up_write(&nvmet_config_sem);

	return count;
	return ret;
}
CONFIGFS_ATTR(nvmet_subsys_, attr_serial);

+1 −0
Original line number Diff line number Diff line
@@ -231,6 +231,7 @@ struct nvmet_subsys {

	u64			ver;
	char			serial[NVMET_SN_MAX_SIZE];
	bool			subsys_discovered;
	char			*subsysnqn;
	bool			pi_support;