summaryrefslogtreecommitdiff
path: root/drivers/scsi/scsi_debug.c
diff options
context:
space:
mode:
authorWenchao Hao <haowenchao2@huawei.com>2023-10-10 12:20:44 +0300
committerMartin K. Petersen <martin.petersen@oracle.com>2023-10-17 03:50:11 +0300
commit962d77cd4c852e6a34ffd44fc5f32ba678e02633 (patch)
treebc85ddff5817735d4d5134cc7b70ab06faaf1f41 /drivers/scsi/scsi_debug.c
parenta9996d722b1197b625acfa350dd2849e35ad6092 (diff)
downloadlinux-962d77cd4c852e6a34ffd44fc5f32ba678e02633.tar.xz
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>
Diffstat (limited to 'drivers/scsi/scsi_debug.c')
-rw-r--r--drivers/scsi/scsi_debug.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 46f1ee647b15..0d5a179dbd97 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -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;