From 3ddb4c765325586a62dfbadf8e5722148d9a0fcd Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Wed, 5 Mar 2008 18:22:01 +0000 Subject: [PATCH] - Fixed race on TM processing leading to BUG() - Fixed dev_cdrom and dev_modisk load failures if there are no media in the drives - Other minor fixes and cleanups git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@298 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/param.c | 47 +++++++++++++++-------------- iscsi-scst/usr/plain.c | 10 +++--- scst/include/scsi_tgt.h | 8 ++--- scst/src/dev_handlers/scst_cdrom.c | 11 +++---- scst/src/dev_handlers/scst_modisk.c | 13 ++++---- scst/src/scst_targ.c | 11 +++++-- 6 files changed, 52 insertions(+), 48 deletions(-) diff --git a/iscsi-scst/kernel/param.c b/iscsi-scst/kernel/param.c index 2150dbec6..b0d18225a 100644 --- a/iscsi-scst/kernel/param.c +++ b/iscsi-scst/kernel/param.c @@ -16,31 +16,34 @@ #include "iscsi.h" #include "digest.h" -#define CHECK_PARAM(info, iparam, word, min, max) \ -do { \ - if (!info->partial || (info->partial & 1 << key_##word)) \ - if (iparam[key_##word] < min || \ - iparam[key_##word] > max) { \ - PRINT_ERROR("%s: %u is out of range (%u %u)",\ - #word, iparam[key_##word], min, max); \ - iparam[key_##word] = min; \ - } \ +#define CHECK_PARAM(info, iparam, word, min, max) \ +do { \ + if (!(info)->partial || ((info)->partial & 1 << key_##word)) \ + if ((iparam)[key_##word] < (min) || \ + (iparam)[key_##word] > (max)) { \ + PRINT_ERROR("%s: %u is out of range (%u %u)", \ + #word, (iparam)[key_##word], (min), (max)); \ + if ((iparam)[key_##word] < (min)) \ + (iparam)[key_##word] = (min); \ + else \ + (iparam)[key_##word] = (max); \ + } \ } while (0) -#define SET_PARAM(param, info, iparam, word) \ -({ \ - int changed = 0; \ - if (!info->partial || (info->partial & 1 << key_##word)) { \ - if (param->word != iparam[key_##word]) \ - changed = 1; \ - param->word = iparam[key_##word]; \ - } \ - changed; \ +#define SET_PARAM(param, info, iparam, word) \ +({ \ + int changed = 0; \ + if (!(info)->partial || ((info)->partial & 1 << key_##word)) { \ + if ((param)->word != (iparam)[key_##word]) \ + changed = 1; \ + (param)->word = (iparam)[key_##word]; \ + } \ + changed; \ }) -#define GET_PARAM(param, info, iparam, word) \ -do { \ - iparam[key_##word] = param->word; \ +#define GET_PARAM(param, info, iparam, word) \ +do { \ + (iparam)[key_##word] = (param)->word; \ } while (0) static const char *get_bool_name(int val) @@ -191,7 +194,7 @@ static int trgt_param(struct iscsi_target *target, struct iscsi_param_info *info trgt_param_set(target, info); prm = &target->trgt_param; - PRINT_INFO("Target parameter changed: queued_cmnds %d", + PRINT_INFO("Target parameter changed: QueuedCommands %d", prm->queued_cmnds); } else trgt_param_get(&target->trgt_param, info); diff --git a/iscsi-scst/usr/plain.c b/iscsi-scst/usr/plain.c index c83b33cf0..ed83ce1e8 100644 --- a/iscsi-scst/usr/plain.c +++ b/iscsi-scst/usr/plain.c @@ -102,8 +102,9 @@ static int plain_account_init(char *filename) u32 tid; int idx, res = 0; - if (!(fp = fopen(filename, "r"))) - return -EIO; + if (!(fp = fopen(filename, "r"))) { + return errno == ENOENT ? 0 : -errno; + } tid = 0; while (fgets(buf, sizeof(buf), fp)) { @@ -520,8 +521,9 @@ static int plain_main_init(char *filename) u32 tid, val; int res = 0; - if (!(config = fopen(filename, "r"))) - return -errno; + if (!(config = fopen(filename, "r"))) { + return errno == ENOENT ? 0 : -errno; + } tid = 0; while (fgets(buf, BUFSIZE, config)) { diff --git a/scst/include/scsi_tgt.h b/scst/include/scsi_tgt.h index cd314f259..104a939de 100644 --- a/scst/include/scsi_tgt.h +++ b/scst/include/scsi_tgt.h @@ -1076,12 +1076,6 @@ struct scst_cmd */ unsigned int sg_buff_modified:1; - /* - * Set if the cmd's memory requirements are checked and found - * acceptable - */ - unsigned int mem_checked:1; - /* * Set if scst_cmd_init_stage1_done() called and the target * want that preprocessing_done() will be called @@ -1147,6 +1141,8 @@ struct scst_cmd lun_t lun; /* LUN for this cmd */ + unsigned long start_time; + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) struct scsi_request *scsi_req; /* SCSI request */ #endif diff --git a/scst/src/dev_handlers/scst_cdrom.c b/scst/src/dev_handlers/scst_cdrom.c index 89eae1bf8..39b99cba1 100644 --- a/scst/src/dev_handlers/scst_cdrom.c +++ b/scst/src/dev_handlers/scst_cdrom.c @@ -119,18 +119,17 @@ int cdrom_attach(struct scst_device *dev) TRACE_DBG("READ_CAPACITY done: %x", res); - if (!res || (sbuff[12] != 0x28 && sbuff[12] != 0x29)) - { + if ((res == 0) || (sbuff[2] != UNIT_ATTENTION)) break; - } + if (!--retries) { - PRINT_ERROR("UA not clear after %d retries", + PRINT_ERROR("UA not cleared after %d retries", SCST_DEV_UA_RETRIES); params->block_shift = CDROM_DEF_BLOCK_SHIFT; -// res = -ENODEV; goto out_free_buf; } } + if (res == 0) { int sector_size = ((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | (buffer[7] << 0)); @@ -143,8 +142,6 @@ int cdrom_attach(struct scst_device *dev) } else { TRACE_BUFFER("Sense set", sbuff, SCST_SENSE_BUFFERSIZE); params->block_shift = CDROM_DEF_BLOCK_SHIFT; -// res = -ENODEV; - goto out_free_buf; } res = scst_obtain_device_parameters(dev); diff --git a/scst/src/dev_handlers/scst_modisk.c b/scst/src/dev_handlers/scst_modisk.c index 2ba9f1955..8f16b1dfd 100644 --- a/scst/src/dev_handlers/scst_modisk.c +++ b/scst/src/dev_handlers/scst_modisk.c @@ -207,16 +207,16 @@ int modisk_attach(struct scst_device *dev) TRACE_DBG("READ_CAPACITY done: %x", res); - if (!res || (sbuff[2] != UNIT_ATTENTION)) - { + if (!res || (sbuff[2] != UNIT_ATTENTION)) break; - } + if (!--retries) { - PRINT_ERROR("UA not clear after %d retries", + PRINT_ERROR("UA not cleared after %d retries", SCST_DEV_UA_RETRIES); goto out_free_buf; } } + if (res == 0) { int sector_size = ((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | (buffer[7] << 0)); @@ -229,9 +229,10 @@ int modisk_attach(struct scst_device *dev) } else { TRACE_BUFFER("Sense set", sbuff, SCST_SENSE_BUFFERSIZE); - if (sbuff[2] != NOT_READY) + if (sbuff[2] != NOT_READY) { res = -ENODEV; - goto out_free_buf; + goto out_free_buf; + } } res = scst_obtain_device_parameters(dev); diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 608a99cd6..6ed0a7590 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -76,6 +76,8 @@ struct scst_cmd *scst_rx_cmd(struct scst_session *sess, cmd->tgt = sess->tgt; cmd->tgtt = sess->tgt->tgtt; + cmd->start_time = jiffies; + /* * For both wrong lun and CDB defer the error reporting for * scst_cmd_init_done() @@ -3566,9 +3568,10 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd, * we must wait here to be sure that we won't receive * double commands with the same tag. */ - TRACE_MGMT_DBG("cmd %p (tag %llu) being executed/" - "xmitted (state %d), deferring ABORT...", - cmd, cmd->tag, cmd->state); + TRACE_MGMT_DBG("cmd %p (tag %llu) being executed/xmitted " + "(state %d, proc time %ld sec.), deferring ABORT...", + cmd, cmd->tag, cmd->state, + (long)(jiffies - cmd->start_time)/HZ); mcmd->cmd_finish_wait_count++; @@ -4346,7 +4349,9 @@ static int scst_mgmt_cmd_check_nexus_loss(struct scst_mgmt_cmd *mcmd) sess->unreg_cmds_done_fn = NULL; } + spin_lock_irq(&scst_mcmd_lock); mcmd->nexus_loss_check_done = 1; + spin_unlock_irq(&scst_mcmd_lock); res = scst_set_mcmd_next_state(mcmd);