diff mbox series

[RFC,2/2] scsi: scsi_debug: Allow dev_size_mb changes through sysfs

Message ID 20240311065427.3006023-3-shinichiro.kawasaki@wdc.com
State New
Headers show
Series scsi: scsi_debug: Allow parameter changes through sysfs | expand

Commit Message

Shinichiro Kawasaki March 11, 2024, 6:54 a.m. UTC
The parameter dev_size_mb is read-only and can be modified only when
scsi_debug is reloaded. Therefore, loadable scsi_debug is required to
specify the desired dev_size_mb. With the built-in scsi_debug, only the
default dev_size_mb value can be used.

To allow testing with built-in scsi_debug and any dev_size_mb value,
make the parameter writable. To take the required actions at the
parameter writing and change, allow such writing not through the sysfs
module attribute, but through the sysfs driver attribute. The parameter
is stored as a global variable and referred to in many places, then
changes of the value would causes troubles for existing live hosts. To
avoid the troubles, allow the value changes only when there is no host.
Users must remove all hosts to write new dev_size_mb values.

At the parameter write, call scsi_debug_init_size_parameters() to
propagate the dev_size_mb value changes to dependent parameters. Also
erase all stores at dev_size_mb change and recreate the store with the
new dev_size_mb value.

Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
---
 drivers/scsi/scsi_debug.c | 39 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index c6b32f07a82c..c93cac831d8e 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -558,6 +558,8 @@  static void sdebug_erase_all_stores(bool apart_from_first);
 
 static void sdebug_free_queued_cmd(struct sdebug_queued_cmd *sqcp);
 
+static void scsi_debug_init_size_parameters(void);
+
 /*
  * The following are overflow arrays for cdbs that "hit" the same index in
  * the opcode_info_arr array. The most time sensitive (or commonly used) cdb
@@ -6660,7 +6662,42 @@  static ssize_t dev_size_mb_show(struct device_driver *ddp, char *buf)
 {
 	return scnprintf(buf, PAGE_SIZE, "%d\n", sdebug_dev_size_mb);
 }
-static DRIVER_ATTR_RO(dev_size_mb);
+
+static ssize_t dev_size_mb_store(struct device_driver *ddp, const char *buf,
+				 size_t count)
+{
+	bool want_store = sdebug_fake_rw == 0;
+	int n, ret;
+
+	if (sdebug_num_hosts) {
+		pr_err("scsi_debug: Can not change dev_size_mb due to existing hosts\n");
+		return -EINVAL;
+	}
+
+	if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 1)) {
+		sdebug_dev_size_mb = n;
+
+		/* Propagate dev_size_mb change to other parameters */
+		scsi_debug_init_size_parameters();
+
+		/*
+		 * Erase all stores which may have different size. Initialize
+		 * global variables for the stores and recreate the store.
+		 */
+		sdebug_erase_all_stores(false);
+		sdeb_first_idx = -1;
+		sdeb_most_recent_idx = -1;
+		if (want_store) {
+			ret = sdebug_add_store();
+			if (ret < 0)
+				return ret;
+		}
+		return count;
+	}
+
+	return -EINVAL;
+}
+static DRIVER_ATTR_RW(dev_size_mb);
 
 static ssize_t per_host_store_show(struct device_driver *ddp, char *buf)
 {