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: Douglas Gilbert <dgilbert@interlog.com>
Signed-off-by: Wenchao Hao <haowenchao2@huawei.com>
Link: https://lore.kernel.org/r/20231010092051.608007-4-haowenchao2@huawei.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Wenchao Hao 2023-10-10 17:20:44 +08:00 committed by Martin K. Petersen
parent a9996d722b
commit 962d77cd4c

View file

@ -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;