提交 817fd66b 编写于 作者: D Douglas Gilbert 提交者: Christoph Hellwig

scsi_debug: append inject error flags onto scsi_cmnd object

The way the existing scsi_debug command parser associated various
inject error flags to a command was difficult to replicate in the
table driven parser. This patch adds infrastructure to append those
flags to the end of a scsi_cmnd object with the cmd_size host
template option.
Signed-off-by: NDouglas Gilbert <dgilbert@interlog.com>
Signed-off-by: NChristoph Hellwig <hch@lst.de>
上级 22017ed2
...@@ -209,6 +209,14 @@ static const char *scsi_debug_version_date = "20141022"; ...@@ -209,6 +209,14 @@ static const char *scsi_debug_version_date = "20141022";
#warning "Expect DEF_CMD_PER_LUN <= SCSI_DEBUG_CANQUEUE" #warning "Expect DEF_CMD_PER_LUN <= SCSI_DEBUG_CANQUEUE"
#endif #endif
struct sdebug_scmd_extra_t {
bool inj_recovered;
bool inj_transport;
bool inj_dif;
bool inj_dix;
bool inj_short;
};
static int scsi_debug_add_host = DEF_NUM_HOST; static int scsi_debug_add_host = DEF_NUM_HOST;
static int scsi_debug_ato = DEF_ATO; static int scsi_debug_ato = DEF_ATO;
static int scsi_debug_delay = DEF_DELAY; static int scsi_debug_delay = DEF_DELAY;
...@@ -248,6 +256,7 @@ static unsigned int scsi_debug_write_same_length = DEF_WRITESAME_LENGTH; ...@@ -248,6 +256,7 @@ static unsigned int scsi_debug_write_same_length = DEF_WRITESAME_LENGTH;
static bool scsi_debug_removable = DEF_REMOVABLE; static bool scsi_debug_removable = DEF_REMOVABLE;
static bool scsi_debug_clustering; static bool scsi_debug_clustering;
static bool scsi_debug_host_lock = DEF_HOST_LOCK; static bool scsi_debug_host_lock = DEF_HOST_LOCK;
static bool sdebug_any_injecting_opt;
static atomic_t sdebug_cmnd_count; static atomic_t sdebug_cmnd_count;
static atomic_t sdebug_completions; static atomic_t sdebug_completions;
...@@ -3416,6 +3425,16 @@ static ssize_t opts_store(struct device_driver *ddp, const char *buf, ...@@ -3416,6 +3425,16 @@ static ssize_t opts_store(struct device_driver *ddp, const char *buf,
return -EINVAL; return -EINVAL;
opts_done: opts_done:
scsi_debug_opts = opts; scsi_debug_opts = opts;
if (SCSI_DEBUG_OPT_RECOVERED_ERR & opts)
sdebug_any_injecting_opt = true;
else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & opts)
sdebug_any_injecting_opt = true;
else if (SCSI_DEBUG_OPT_DIF_ERR & opts)
sdebug_any_injecting_opt = true;
else if (SCSI_DEBUG_OPT_DIX_ERR & opts)
sdebug_any_injecting_opt = true;
else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & opts)
sdebug_any_injecting_opt = true;
atomic_set(&sdebug_cmnd_count, 0); atomic_set(&sdebug_cmnd_count, 0);
atomic_set(&sdebug_a_tsf, 0); atomic_set(&sdebug_a_tsf, 0);
return count; return count;
...@@ -4563,6 +4582,41 @@ sdebug_change_qtype(struct scsi_device *sdev, int qtype) ...@@ -4563,6 +4582,41 @@ sdebug_change_qtype(struct scsi_device *sdev, int qtype)
return qtype; return qtype;
} }
static int
check_inject(struct scsi_cmnd *scp)
{
struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp);
memset(ep, 0, sizeof(struct sdebug_scmd_extra_t));
if (atomic_inc_return(&sdebug_cmnd_count) >=
abs(scsi_debug_every_nth)) {
atomic_set(&sdebug_cmnd_count, 0);
if (scsi_debug_every_nth < -1)
scsi_debug_every_nth = -1;
if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
return 1; /* ignore command causing timeout */
else if (SCSI_DEBUG_OPT_MAC_TIMEOUT & scsi_debug_opts &&
scsi_medium_access_command(scp))
return 1; /* time out reads and writes */
if (sdebug_any_injecting_opt) {
int opts = scsi_debug_opts;
if (SCSI_DEBUG_OPT_RECOVERED_ERR & opts)
ep->inj_recovered = true;
else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & opts)
ep->inj_transport = true;
else if (SCSI_DEBUG_OPT_DIF_ERR & opts)
ep->inj_dif = true;
else if (SCSI_DEBUG_OPT_DIX_ERR & opts)
ep->inj_dix = true;
else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & opts)
ep->inj_short = true;
}
}
return 0;
}
static struct scsi_host_template sdebug_driver_template = { static struct scsi_host_template sdebug_driver_template = {
.show_info = scsi_debug_show_info, .show_info = scsi_debug_show_info,
.write_info = scsi_debug_write_info, .write_info = scsi_debug_write_info,
...@@ -4589,11 +4643,13 @@ static struct scsi_host_template sdebug_driver_template = { ...@@ -4589,11 +4643,13 @@ static struct scsi_host_template sdebug_driver_template = {
.use_clustering = DISABLE_CLUSTERING, .use_clustering = DISABLE_CLUSTERING,
.module = THIS_MODULE, .module = THIS_MODULE,
.track_queue_depth = 1, .track_queue_depth = 1,
.cmd_size = sizeof(struct sdebug_scmd_extra_t),
}; };
static int sdebug_driver_probe(struct device * dev) static int sdebug_driver_probe(struct device * dev)
{ {
int error = 0; int error = 0;
int opts;
struct sdebug_host_info *sdbg_host; struct sdebug_host_info *sdbg_host;
struct Scsi_Host *hpnt; struct Scsi_Host *hpnt;
int host_prot; int host_prot;
...@@ -4662,6 +4718,18 @@ static int sdebug_driver_probe(struct device * dev) ...@@ -4662,6 +4718,18 @@ static int sdebug_driver_probe(struct device * dev)
else else
scsi_host_set_guard(hpnt, SHOST_DIX_GUARD_CRC); scsi_host_set_guard(hpnt, SHOST_DIX_GUARD_CRC);
opts = scsi_debug_opts;
if (SCSI_DEBUG_OPT_RECOVERED_ERR & opts)
sdebug_any_injecting_opt = true;
else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & opts)
sdebug_any_injecting_opt = true;
else if (SCSI_DEBUG_OPT_DIF_ERR & opts)
sdebug_any_injecting_opt = true;
else if (SCSI_DEBUG_OPT_DIX_ERR & opts)
sdebug_any_injecting_opt = true;
else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & opts)
sdebug_any_injecting_opt = true;
error = scsi_add_host(hpnt, &sdbg_host->dev); error = scsi_add_host(hpnt, &sdbg_host->dev);
if (error) { if (error) {
printk(KERN_ERR "%s: scsi_add_host failed\n", __func__); printk(KERN_ERR "%s: scsi_add_host failed\n", __func__);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册