Commit 962d77cd authored by Wenchao Hao's avatar Wenchao Hao Committed by Martin K. Petersen
Browse files

scsi: scsi_debug: Define grammar to remove added error injection



The grammar to remove error injection is a line with fixed 3 columns
separated by spaces.

First column is fixed to "-". It tells this is a removal operation.  Second
column is the error code to match.  Third column is the scsi command to
match.

For example the following command would remove timeout injection of inquiry
command:

    echo "- 0 0x12" > /sys/kernel/debug/scsi_debug/0:0:0:1/error

Acked-by: default avatarDouglas Gilbert <dgilbert@interlog.com>
Signed-off-by: default avatarWenchao Hao <haowenchao2@huawei.com>
Link: https://lore.kernel.org/r/20231010092051.608007-4-haowenchao2@huawei.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent a9996d72
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -930,6 +930,34 @@ static void sdebug_err_add(struct scsi_device *sdev, struct sdebug_err_inject *n
	spin_unlock(&devip->list_lock);
}

static int sdebug_err_remove(struct scsi_device *sdev, const char *buf, size_t count)
{
	struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdev->hostdata;
	struct sdebug_err_inject *err;
	int type;
	unsigned char cmd;

	if (sscanf(buf, "- %d %hhx", &type, &cmd) != 2) {
		kfree(buf);
		return -EINVAL;
	}

	spin_lock(&devip->list_lock);
	list_for_each_entry_rcu(err, &devip->inject_err_list, list) {
		if (err->type == type && err->cmd == cmd) {
			list_del_rcu(&err->list);
			call_rcu(&err->rcu, sdebug_err_free);
			spin_unlock(&devip->list_lock);
			kfree(buf);
			return count;
		}
	}
	spin_unlock(&devip->list_lock);

	kfree(buf);
	return -EINVAL;
}

static int sdebug_error_show(struct seq_file *m, void *p)
{
	struct scsi_device *sdev = (struct scsi_device *)m->private;
@@ -987,6 +1015,9 @@ static ssize_t sdebug_error_write(struct file *file, const char __user *ubuf,
		return -EFAULT;
	}

	if (buf[0] == '-')
		return sdebug_err_remove(sdev, buf, count);

	if (sscanf(buf, "%d", &inject_type) != 1) {
		kfree(buf);
		return -EINVAL;