Skip to content

Commit 33bccf5

Browse files
wenchao-haomartinkpetersen
authored andcommitted
scsi: scsi_debug: Return failed value if error is injected
If a fail queuecommand error is injected, return the failed value defined in the rule from queuecommand. Make queuecommand return format: +--------+------+-------------------------------------------------------+ | Column | Type | Description | +--------+------+-------------------------------------------------------+ | 1 | u8 | Error type, fixed to 0x1 | +--------+------+-------------------------------------------------------+ | 2 | s32 | Error count | | | | 0: this rule will be ignored | | | | positive: the rule will always take effect | | | | negative: the rule takes effect n times where -n is | | | | the value given. Ignored after n times | +--------+------+-------------------------------------------------------+ | 3 | x8 | SCSI command opcode, 0xff for all commands | +--------+------+-------------------------------------------------------+ | 4 | x32 | The queuecommand() return value we want | +--------+------+-------------------------------------------------------+ Examples: error=/sys/kernel/debug/scsi_debug/0:0:0:1/error echo "1 1 0x12 0x1055" > ${error} will make each INQUIRY command sent to that device return 0x1055 (SCSI_MLQUEUE_HOST_BUSY). Acked-by: Douglas Gilbert <[email protected]> Signed-off-by: Wenchao Hao <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 32be8b6 commit 33bccf5

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

drivers/scsi/scsi_debug.c

+36
Original file line numberDiff line numberDiff line change
@@ -7769,6 +7769,34 @@ static int sdebug_timeout_cmd(struct scsi_cmnd *cmnd)
77697769
return 0;
77707770
}
77717771

7772+
static int sdebug_fail_queue_cmd(struct scsi_cmnd *cmnd)
7773+
{
7774+
struct scsi_device *sdp = cmnd->device;
7775+
struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata;
7776+
struct sdebug_err_inject *err;
7777+
unsigned char *cmd = cmnd->cmnd;
7778+
int ret = 0;
7779+
7780+
if (devip == NULL)
7781+
return 0;
7782+
7783+
rcu_read_lock();
7784+
list_for_each_entry_rcu(err, &devip->inject_err_list, list) {
7785+
if (err->type == ERR_FAIL_QUEUE_CMD &&
7786+
(err->cmd == cmd[0] || err->cmd == 0xff)) {
7787+
ret = err->cnt ? err->queuecmd_ret : 0;
7788+
if (err->cnt < 0)
7789+
err->cnt++;
7790+
7791+
rcu_read_unlock();
7792+
return ret;
7793+
}
7794+
}
7795+
rcu_read_unlock();
7796+
7797+
return 0;
7798+
}
7799+
77727800
static int scsi_debug_queuecommand(struct Scsi_Host *shost,
77737801
struct scsi_cmnd *scp)
77747802
{
@@ -7788,6 +7816,7 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost,
77887816
u8 opcode = cmd[0];
77897817
bool has_wlun_rl;
77907818
bool inject_now;
7819+
int ret = 0;
77917820

77927821
scsi_set_resid(scp, 0);
77937822
if (sdebug_statistics) {
@@ -7833,6 +7862,13 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost,
78337862
return 0;
78347863
}
78357864

7865+
ret = sdebug_fail_queue_cmd(scp);
7866+
if (ret) {
7867+
scmd_printk(KERN_INFO, scp, "fail queue command 0x%x with 0x%x\n",
7868+
opcode, ret);
7869+
return ret;
7870+
}
7871+
78367872
if (unlikely(inject_now && !atomic_read(&sdeb_inject_pending)))
78377873
atomic_set(&sdeb_inject_pending, 1);
78387874

0 commit comments

Comments
 (0)