From 566827010dfc26edf058889909620cfbacc862db Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 7 Nov 2015 00:01:57 +0000 Subject: [PATCH] scst: Insert a blank line after declarations git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6618 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/dev_handlers/scst_cdrom.c | 1 + scst/src/dev_handlers/scst_disk.c | 2 ++ scst/src/dev_handlers/scst_modisk.c | 1 + scst/src/dev_handlers/scst_tape.c | 3 ++ scst/src/dev_handlers/scst_user.c | 12 +++++++ scst/src/dev_handlers/scst_vdisk.c | 19 ++++++++++ scst/src/scst_lib.c | 55 ++++++++++++++++++++++++++++- scst/src/scst_main.c | 6 ++++ scst/src/scst_mem.c | 5 +++ scst/src/scst_pres.c | 6 ++++ scst/src/scst_priv.h | 1 + scst/src/scst_sysfs.c | 18 ++++++++-- scst/src/scst_targ.c | 38 ++++++++++++++++++++ scst/src/scst_tg.c | 2 ++ 14 files changed, 166 insertions(+), 3 deletions(-) diff --git a/scst/src/dev_handlers/scst_cdrom.c b/scst/src/dev_handlers/scst_cdrom.c index a08999b4f..f1860f8d7 100644 --- a/scst/src/dev_handlers/scst_cdrom.c +++ b/scst/src/dev_handlers/scst_cdrom.c @@ -123,6 +123,7 @@ static int cdrom_attach(struct scst_device *dev) if (rc == 0) { uint32_t sector_size = get_unaligned_be32(&buffer[4]); + if (sector_size == 0) dev->block_shift = CDROM_DEF_BLOCK_SHIFT; else diff --git a/scst/src/dev_handlers/scst_disk.c b/scst/src/dev_handlers/scst_disk.c index a56cc204c..d694633fd 100644 --- a/scst/src/dev_handlers/scst_disk.c +++ b/scst/src/dev_handlers/scst_disk.c @@ -217,6 +217,7 @@ static int disk_attach(struct scst_device *dev) } if (rc == 0) { uint32_t sector_size = get_unaligned_be32(&buffer[4]); + if (sector_size == 0) dev->block_shift = DISK_DEF_BLOCK_SHIFT; else @@ -474,6 +475,7 @@ split: if (unlikely(sg_is_chain(&sg[j]))) { bool reset_start_sg = (start_sg == &sg[j]); + sg = sg_chain_ptr(&sg[j]); j = 0; if (reset_start_sg) diff --git a/scst/src/dev_handlers/scst_modisk.c b/scst/src/dev_handlers/scst_modisk.c index 850f8efe2..80913010c 100644 --- a/scst/src/dev_handlers/scst_modisk.c +++ b/scst/src/dev_handlers/scst_modisk.c @@ -222,6 +222,7 @@ static int modisk_attach(struct scst_device *dev) if (rc == 0) { uint32_t sector_size = get_unaligned_be32(&buffer[4]); + if (sector_size == 0) dev->block_shift = MODISK_DEF_BLOCK_SHIFT; else diff --git a/scst/src/dev_handlers/scst_tape.c b/scst/src/dev_handlers/scst_tape.c index 4daa84d84..1b56b01ed 100644 --- a/scst/src/dev_handlers/scst_tape.c +++ b/scst/src/dev_handlers/scst_tape.c @@ -206,6 +206,7 @@ static int tape_attach(struct scst_device *dev) if (rc == 0) { int medium_type, mode, speed, density; + if (buffer[3] == 8) dev->block_size = get_unaligned_be24(&buffer[9]); else @@ -299,6 +300,7 @@ static int tape_done(struct scst_cmd *cmd) (cmd->sense[2] & 0xe0)) { /* EOF, EOM, or ILI */ unsigned int TransferLength, Residue = 0; + if ((cmd->sense[2] & 0x0f) == BLANK_CHECK) /* No need for EOM in this case */ cmd->sense[2] &= 0xcf; @@ -312,6 +314,7 @@ static int tape_done(struct scst_cmd *cmd) cmd->cdb[1], TransferLength, Residue); if (TransferLength > Residue) { int resp_data_len = TransferLength - Residue; + if (cmd->cdb[1] & 1) { /* * No need for locks here, since diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index 45288befd..3b90d38d1 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -261,6 +261,7 @@ static inline bool ucmd_get_check(struct scst_user_cmd *ucmd) { int r = atomic_inc_return(&ucmd->ucmd_ref); int res; + if (unlikely(r == 1)) { TRACE_DBG("ucmd %p is being destroyed", ucmd); atomic_dec(&ucmd->ucmd_ref); @@ -551,6 +552,7 @@ static int dev_user_alloc_sg(struct scst_user_cmd *ucmd, int cached_buff) } else { /* Make out_sg->offset 0 */ int len = cmd->bufflen + ucmd->first_page_offset; + out_sg_pages = (len >> PAGE_SHIFT) + ((len & ~PAGE_MASK) != 0); orig_bufflen = (out_sg_pages << PAGE_SHIFT) + cmd->out_bufflen; pool = dev->pool; @@ -612,6 +614,7 @@ static int dev_user_alloc_sg(struct scst_user_cmd *ucmd, int cached_buff) if (unlikely(cmd->sg_cnt > cmd->tgt_dev->max_sg_cnt)) { static int ll; + if ((ll < 10) || TRACING_MINOR()) { PRINT_INFO("Unable to complete command due to " "SG IO count limitation (requested %d, " @@ -1090,6 +1093,7 @@ static void dev_user_set_block_size(struct scst_cmd *cmd, int block_size) dev->block_size = block_size; else { struct scst_user_dev *udev = cmd->dev->dh_priv; + dev->block_size = udev->def_block_size; } dev->block_shift = -1; /* not used */ @@ -1311,6 +1315,7 @@ static int dev_user_process_reply_alloc(struct scst_user_cmd *ucmd, if (likely(reply->alloc_reply.pbuf != 0)) { int pages; + if (ucmd->buff_cached) { if (unlikely((reply->alloc_reply.pbuf & ~PAGE_MASK) != 0)) { PRINT_ERROR("Supplied pbuf %llx isn't " @@ -1775,6 +1780,7 @@ static int dev_user_process_reply_exec(struct scst_user_cmd *ucmd, if (ereply->resp_data_len != 0) { if (ucmd->ubuff == 0) { int pages, rc; + if (unlikely(ereply->pbuf == 0)) goto out_busy; if (ucmd->buff_cached) { @@ -2324,6 +2330,7 @@ static int dev_user_reply_get_cmd(struct file *file, void __user *arg) if (ureply != 0) { unsigned long u = (unsigned long)ureply; + rc = copy_from_user(&reply, (void __user *)u, sizeof(reply)); if (unlikely(rc != 0)) { PRINT_ERROR("Failed to copy %d user's bytes", rc); @@ -2476,6 +2483,7 @@ static long dev_user_ioctl(struct file *file, unsigned int cmd, case SCST_USER_REGISTER_DEVICE: { struct scst_user_dev_desc *dev_desc; + TRACE_DBG("%s", "REGISTER_DEVICE"); dev_desc = kmalloc(sizeof(*dev_desc), GFP_KERNEL); if (dev_desc == NULL) { @@ -2511,6 +2519,7 @@ static long dev_user_ioctl(struct file *file, unsigned int cmd, case SCST_USER_SET_OPTIONS: { struct scst_user_opt opt; + TRACE_DBG("%s", "SET_OPTIONS"); rc = copy_from_user(&opt, (void __user *)arg, sizeof(opt)); if (rc != 0) { @@ -3868,6 +3877,7 @@ static int dev_user_exit_dev(struct scst_user_dev *dev) static int __dev_user_release(void *arg) { struct scst_user_dev *dev = arg; + dev_user_exit_dev(dev); kmem_cache_free(user_dev_cachep, dev); return 0; @@ -3938,6 +3948,7 @@ static int dev_user_process_cleanup(struct scst_user_dev *dev) #ifdef CONFIG_SCST_EXTRACHECKS { int i; + for (i = 0; i < (int)ARRAY_SIZE(dev->ucmd_hash); i++) { struct list_head *head = &dev->ucmd_hash[i]; struct scst_user_cmd *ucmd2, *tmp; @@ -3979,6 +3990,7 @@ static ssize_t dev_user_sysfs_commands_show(struct kobject *kobj, for (i = 0; i < (int)ARRAY_SIZE(udev->ucmd_hash); i++) { struct list_head *head = &udev->ucmd_hash[i]; struct scst_user_cmd *ucmd; + list_for_each_entry(ucmd, head, hash_list_entry) { ppos = pos; pos += scnprintf(&buf[pos], diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 79ef50208..e8437ff55 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -1034,6 +1034,7 @@ check: if (virt_dev->thin_provisioned) { int block_shift = virt_dev->dev->block_shift; + if (virt_dev->blockio) { struct request_queue *q; @@ -1856,6 +1857,7 @@ static enum compl_status_e vdisk_synchronize_cache(struct vdisk_cmd_params *p) if (data_len == 0) { struct scst_vdisk_dev *virt_dev = dev->dh_priv; + data_len = virt_dev->file_size - ((loff_t)scst_cmd_get_lba(cmd) << dev->block_shift); } @@ -2000,6 +2002,7 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, i = -1; while (1) { int len = min_t(size_t, (size_t)left, PAGE_SIZE); + full_len += len; i++; iv_count++; @@ -2209,6 +2212,7 @@ static enum compl_status_e vdisk_exec_format_unit(struct vdisk_cmd_params *p) if (virt_dev->thin_provisioned) { int rc = vdisk_unmap_range(cmd, virt_dev, 0, virt_dev->nblocks); + if (rc != 0) goto finished; } @@ -3003,6 +3007,7 @@ out: static int vcdrom_parse(struct scst_cmd *cmd) { int res, rc; + rc = scst_cdrom_generic_parse(cmd); if (rc != 0) { res = scst_get_cmd_abnormal_done_state(cmd); @@ -4310,6 +4315,7 @@ static int vdisk_inq(uint8_t *buf, struct scst_cmd *cmd, /* Physical transport */ if (cmd->tgtt->get_phys_transport_version != NULL) { uint16_t v = cmd->tgtt->get_phys_transport_version(cmd->tgt); + if (v != 0) { put_unaligned_be16(v, &buf[58 + num]); num += 2; @@ -5230,6 +5236,7 @@ static enum compl_status_e vdisk_exec_read_capacity(struct vdisk_cmd_params *p) if ((cmd->cdb[8] & 1) == 0) { uint32_t lba = get_unaligned_be32(&cmd->cdb[2]); + if (lba != 0) { TRACE_DBG("PMI zero and LBA not zero (cmd %p)", cmd); scst_set_invalid_field_in_cdb(cmd, 2, 0); @@ -5305,6 +5312,7 @@ static enum compl_status_e vdisk_exec_read_capacity16(struct vdisk_cmd_params *p if ((cmd->cdb[14] & 1) == 0) { uint32_t lba = get_unaligned_be32(&cmd->cdb[2]); + if (lba != 0) { TRACE_DBG("PMI zero and LBA not zero (cmd %p)", cmd); scst_set_invalid_field_in_cdb(cmd, 2, 0); @@ -5788,6 +5796,7 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) iv = vdisk_alloc_iv(cmd, p); if (iv == NULL) { unsigned long flags; + /* To protect sense setting against blockio data reads */ spin_lock_irqsave(&vdev_err_lock, flags); scst_set_busy(cmd); @@ -5836,6 +5845,7 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) &loff); if ((err < 0) || (err < full_len)) { unsigned long flags; + PRINT_ERROR("DIF readv() returned %lld from %zd " "(offs %lld, dev %s)", (long long)err, full_len, (long long)loff, cmd->dev->virt_name); @@ -5919,6 +5929,7 @@ static int vdev_write_dif_tags(struct vdisk_cmd_params *p) iv = vdisk_alloc_iv(cmd, p); if (iv == NULL) { unsigned long flags; + /* To protect sense setting against blockio data writes */ spin_lock_irqsave(&vdev_err_lock, flags); scst_set_busy(cmd); @@ -5969,6 +5980,7 @@ restart: &loff); if (err < 0) { unsigned long flags; + PRINT_ERROR("DIF write() returned %lld from %zd", (long long)err, full_len); /* To protect sense setting with blockio */ @@ -5988,6 +6000,7 @@ restart: * value less, than requested. Let's restart. */ int e = eiv_count; + TRACE_MGMT_DBG("DIF write() returned %d from %zd " "(iv_count=%d)", (int)err, full_len, eiv_count); @@ -6322,6 +6335,7 @@ restart: * value less, than requested. Let's restart. */ int e = eiv_count; + TRACE_MGMT_DBG("write() returned %d from %zd " "(iv_count=%d)", (int)err, full_len, eiv_count); @@ -6688,6 +6702,7 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) #if 0 { static int err_inj_cntr; + if (++err_inj_cntr % 256 == 0) { PRINT_INFO("blockio_exec_rw() error injection"); scst_set_busy(cmd); @@ -6913,6 +6928,7 @@ static int vdisk_blockio_flush(struct block_device *bdev, gfp_t gfp_mask, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) if (async) { struct bio *bio = bio_alloc(gfp_mask, 0); + if (bio == NULL) { res = -ENOMEM; goto out_rep; @@ -7371,6 +7387,7 @@ static void vdisk_task_mgmt_fn_done(struct scst_mgmt_cmd *mcmd, } else if (mcmd->fn == SCST_PR_ABORT_ALL) { struct scst_device *dev = tgt_dev->dev; struct scst_vdisk_dev *virt_dev = dev->dh_priv; + spin_lock(&virt_dev->flags_lock); virt_dev->prevent_allow_medium_removal = 0; spin_unlock(&virt_dev->flags_lock); @@ -8406,6 +8423,7 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev, if (!virt_dev->cdrom_empty) { char *fn = kstrdup(filename, GFP_KERNEL); + if (fn == NULL) { PRINT_ERROR("%s", "Allocation of filename failed"); res = -ENOMEM; @@ -10625,6 +10643,7 @@ static void exit_scst_vdisk(struct scst_dev_type *devtype) static void init_ops(vdisk_op_fn *ops, int count) { int i; + for (i = 0; i < count; i++) if (ops[i] == NULL) ops[i] = vdisk_invalid_opcode; diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index e85c9e688..aa5aa0d1b 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -2028,6 +2028,7 @@ int scst_set_cmd_error_and_inf(struct scst_cmd *cmd, int key, int asc, { /* Fixed format */ uint32_t i = information; + cmd->sense[0] |= 0x80; /* Information field is valid */ put_unaligned_be32(i, &cmd->sense[3]); break; @@ -2931,6 +2932,7 @@ next: something_freed = false; for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct scst_tgt_dev *t; + head = &sess->sess_tgt_dev_list[i]; list_for_each_entry_safe(tgt_dev, t, head, @@ -3001,8 +3003,10 @@ void scst_check_reassign_sessions(void) list_for_each_entry(tgtt, &scst_template_list, scst_template_list_entry) { struct scst_tgt *tgt; + list_for_each_entry(tgt, &tgtt->tgt_list, tgt_list_entry) { struct scst_session *sess; + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { scst_check_reassign_sess(sess); @@ -3737,6 +3741,7 @@ bool __scst_get_resid(struct scst_cmd *cmd, int *resid, int *bidi_out_resid) if (cmd->expected_data_direction & SCST_DATA_READ) { int resp = cmd->resp_data_len; + if (cmd->tgt_dif_data_expected) resp += (resp >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; *resid = cmd->expected_transfer_len_full - resp; @@ -3749,6 +3754,7 @@ bool __scst_get_resid(struct scst_cmd *cmd, int *resid, int *bidi_out_resid) } } else if (cmd->expected_data_direction & SCST_DATA_WRITE) { int wl = cmd->write_len; + if (cmd->tgt_dif_data_expected) wl += (wl >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; if (wl < cmd->expected_transfer_len_full) @@ -3757,6 +3763,7 @@ bool __scst_get_resid(struct scst_cmd *cmd, int *resid, int *bidi_out_resid) *resid = cmd->write_len - cmd->bufflen; if (cmd->tgt_dif_data_expected) { int r = *resid; + if (r < 0) r = -r; r += (r >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; @@ -3953,6 +3960,7 @@ static bool __scst_is_relative_target_port_id_unique(uint16_t id, list_for_each_entry(tgtt, &scst_template_list, scst_template_list_entry) { struct scst_tgt *tgt; + list_for_each_entry(tgt, &tgtt->tgt_list, tgt_list_entry) { if (tgt == t) continue; @@ -4098,6 +4106,7 @@ void scst_free_tgt(struct scst_tgt *tgt) static void scst_init_order_data(struct scst_order_data *order_data) { int i; + spin_lock_init(&order_data->sn_lock); INIT_LIST_HEAD(&order_data->deferred_cmd_list); INIT_LIST_HEAD(&order_data->skipped_sn_list); @@ -4589,6 +4598,7 @@ static void scst_free_acg(struct scst_acg *acg) list_for_each_entry_safe(acg_dev, acg_dev_tmp, &acg->acg_dev_list, acg_dev_list_entry) { struct scst_tgt_dev *tgt_dev, *tt; + list_for_each_entry_safe(tgt_dev, tt, &acg_dev->dev->dev_tgt_dev_list, dev_tgt_dev_list_entry) { @@ -4893,6 +4903,7 @@ int scst_tgt_dev_setup_threads(struct scst_tgt_dev *tgt_dev) if (dev->threads_num == 0) { struct scst_tgt_dev *shared_io_tgt_dev; + tgt_dev->active_cmd_threads = &scst_main_cmd_threads; shared_io_tgt_dev = scst_find_shared_io_tgt_dev(tgt_dev); @@ -5337,6 +5348,7 @@ void scst_sess_free_tgt_devs(struct scst_session *sess) /* The session is going down, no users, so no locks */ for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; + list_for_each_entry_safe(tgt_dev, t, head, sess_tgt_dev_list_entry) { scst_free_tgt_dev(tgt_dev); @@ -5780,6 +5792,7 @@ static int scst_ws_push_single_write(struct scst_write_same_priv *wsp, write_cdb[1] = ws_cmd->cdb[1]; if (needs_dif) { uint8_t wrprotect = ws_cmd->cdb[1] & 0xE0; + if (wrprotect == 0) wrprotect = 0x20; write_cdb[1] |= wrprotect; @@ -5789,6 +5802,7 @@ static int scst_ws_push_single_write(struct scst_write_same_priv *wsp, } else { /* There might be WRITE SAME(16) with WRPROTECT 0 here */ uint8_t wrprotect; + if (ws_cmd->cdb_len != 32) wrprotect = ws_cmd->cdb[1] & 0xE0; else @@ -5851,6 +5865,7 @@ static int scst_ws_push_single_write(struct scst_write_same_priv *wsp, for_each_sg(dif_sg, s, dif_sg_cnt, i) { int left = (s->length - s->offset) >> SCST_DIF_TAG_SHIFT; struct t10_pi_tuple *t = sg_virt(s); + TRACE_DBG("sg %p, offset %d, length %d, left %d", s, s->offset, s->length, left); while (left > 0) { @@ -5951,6 +5966,7 @@ static void scst_ws_write_cmd_finished(struct scst_cmd *cmd) if (cmd->status != 0) { int rc; + TRACE_DBG("Write cmd %p (ws cmd %p) finished not successfully", cmd, ws_cmd); sBUG_ON(cmd->resp_data_len != 0); @@ -6082,6 +6098,7 @@ static int scst_ws_sg_init(struct scatterlist **ws_sg, int ws_sg_cnt, sg_init_table(*ws_sg, ws_sg_cnt); for_each_sg(*ws_sg, sg, ws_sg_cnt, i) { u32 len = min(total_bytes, length); + sg_set_page(sg, pg, len, offset); total_bytes -= len; } @@ -6337,6 +6354,7 @@ static void scst_cwr_write_cmd_finished(struct scst_cmd *cmd) if (cmd->status != 0) { int rc; + TRACE_DBG("WRITE cmd %p (cwr cmd %p) finished not successfully", cmd, cwr_cmd); sBUG_ON(cmd->resp_data_len != 0); @@ -6375,6 +6393,7 @@ static void scst_cwr_read_cmd_finished(struct scst_cmd *cmd) if (cmd->status != 0) { int rc; + TRACE_DBG("Read cmd %p (cwr cmd %p) finished not successfully", cmd, cwr_cmd); sBUG_ON(cmd->resp_data_len != 0); @@ -6583,6 +6602,7 @@ int scst_finish_internal_cmd(struct scst_cmd *cmd) scst_complete_request_sense(cmd); else { scst_i_finish_fn_t f = (void *) *((unsigned long long **)cmd->tgt_i_priv); + f(cmd); } @@ -6685,6 +6705,7 @@ struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask, atomic_set(&sess->refcnt, 0); for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; + INIT_LIST_HEAD(head); } spin_lock_init(&sess->sess_list_lock); @@ -6900,6 +6921,7 @@ int scst_pre_init_cmd(struct scst_cmd *cmd, const uint8_t *cdb, { int i; uint8_t *b = (uint8_t *)cmd; + for (i = 0; i < sizeof(*cmd); i++) EXTRACHECKS_BUG_ON(b[i] != 0); } @@ -7090,7 +7112,7 @@ void scst_free_cmd(struct scst_cmd *cmd) TRACE_MGMT_DBG("Freeing aborted cmd %p", cmd); EXTRACHECKS_BUG_ON(cmd->unblock_dev || cmd->dec_on_dev_needed || - cmd->on_dev_exec_list); + cmd->on_dev_exec_list); /* * Target driver can already free sg buffer before calling @@ -7101,6 +7123,7 @@ void scst_free_cmd(struct scst_cmd *cmd) if (likely(cmd->dev != NULL)) { struct scst_dev_type *devt = cmd->devt; + if (devt->on_free_cmd != NULL) { TRACE_DBG("Calling dev handler %s on_free_cmd(%p)", devt->name, cmd); @@ -8205,6 +8228,7 @@ static int sg_cmp_elem(struct scatterlist **pdst_sg, size_t *pdst_len, /* Fast path: both buffers and len aligned */ unsigned long long *s = saddr; unsigned long long *d = daddr; + EXTRACHECKS_BUG_ON(len % align_size != 0); len /= align_size; for (i = 0; i < len; i++) { @@ -8212,6 +8236,7 @@ static int sg_cmp_elem(struct scatterlist **pdst_sg, size_t *pdst_len, uint8_t *s8 = (uint8_t *)&s[i]; uint8_t *d8 = (uint8_t *)&d[i]; int j; + for (j = 0; j < align_size; j++) { if (s8[j] != d8[j]) { *miscompare_offs = i * align_size + j; @@ -8224,6 +8249,7 @@ static int sg_cmp_elem(struct scatterlist **pdst_sg, size_t *pdst_len, } else { uint8_t *s = saddr; uint8_t *d = daddr; + for (i = 0; i < len; i++) { if (s[i] != d[i]) { *miscompare_offs = i; @@ -8693,6 +8719,7 @@ static int scst_verify_dif_type1(struct scst_cmd *cmd) if ((checks & SCST_DIF_CHECK_GUARD_TAG) && !cmd->internal) { __be16 crc = crc_fn(cur_buf, block_size); + if (t->guard_tag != crc) { PRINT_WARNING("GUARD TAG check failed, " "expected 0x%x, seeing 0x%x " @@ -9015,6 +9042,7 @@ static int scst_do_dif(struct scst_cmd *cmd, case SCST_DIF_ACTION_PASS_CHECK: { enum scst_dif_actions checks = scst_get_dif_checks(cmd->cmd_dif_actions); + if (likely(checks != SCST_DIF_ACTION_NONE)) res = verify_fn(cmd); else @@ -9141,6 +9169,7 @@ static int scst_verify_dif_type2(struct scst_cmd *cmd) if ((checks & SCST_DIF_CHECK_GUARD_TAG) && !cmd->internal) { __be16 crc = crc_fn(cur_buf, block_size); + if (t->guard_tag != crc) { PRINT_WARNING("GUARD TAG check failed, " "expected 0x%x, seeing 0x%x " @@ -9358,6 +9387,7 @@ static int scst_verify_dif_type3(struct scst_cmd *cmd) if ((checks & SCST_DIF_CHECK_GUARD_TAG) && !cmd->internal) { __be16 crc = crc_fn(cur_buf, block_size); + if (t->guard_tag != crc) { PRINT_WARNING("GUARD TAG check failed, " "expected 0x%x, seeing 0x%x " @@ -10813,10 +10843,12 @@ static int get_cdb_info_lba_3_len_1_256_read(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_3_len_1_256(cmd, sdbops); + if (res != 0) goto out; else { struct scst_device *dev = cmd->dev; + if ((dev->dev_dif_mode != SCST_DIF_MODE_NONE) && !dev->dpicz) cmd->cmd_dif_actions = dev->dev_dif_rd_prot0_actions | SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | @@ -10830,10 +10862,12 @@ static int get_cdb_info_lba_3_len_1_256_write(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_3_len_1_256(cmd, sdbops); + if (res != 0) goto out; else { struct scst_device *dev = cmd->dev; + if (dev->dev_dif_mode != SCST_DIF_MODE_NONE) cmd->cmd_dif_actions = dev->dev_dif_wr_prot0_actions | SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | @@ -10941,6 +10975,7 @@ static int get_cdb_info_read_10(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_4_len_2(cmd, sdbops); + if (res != 0) return res; else { @@ -10956,6 +10991,7 @@ static int get_cdb_info_lba_4_len_2_wrprotect(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_4_len_2(cmd, sdbops); + if (res != 0) return res; else @@ -10981,6 +11017,7 @@ static int get_cdb_info_lba_4_len_4_rdprotect(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_4_len_4(cmd, sdbops); + if (res != 0) return res; else @@ -10991,6 +11028,7 @@ static int get_cdb_info_lba_4_len_4_wrprotect(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_4_len_4(cmd, sdbops); + if (res != 0) return res; else @@ -11016,6 +11054,7 @@ static int get_cdb_info_read_16(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_8_len_4(cmd, sdbops); + if (res != 0) return res; else { @@ -11031,6 +11070,7 @@ static int get_cdb_info_lba_8_len_4_wrprotect(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_8_len_4(cmd, sdbops); + if (res != 0) return res; else @@ -11041,6 +11081,7 @@ static int get_cdb_info_lba_8_len_4_wrprotect32(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_8_len_4(cmd, sdbops); + if (res != 0) return res; else @@ -11051,6 +11092,7 @@ static int get_cdb_info_lba_8_len_4_rdprotect32(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { int res = get_cdb_info_lba_8_len_4(cmd, sdbops); + if (res != 0) return res; else @@ -11384,6 +11426,7 @@ static int get_cdb_info_mo(struct scst_cmd *cmd, case MO_SET_TARGET_PGS: { unsigned long flags; + cmd->op_name = "SET TARGET PORT GROUPS"; cmd->op_flags |= SCST_STRICTLY_SERIALIZED; spin_lock_irqsave(&scst_global_stpg_list_lock, flags); @@ -11749,6 +11792,7 @@ int scst_tape_generic_parse(struct scst_cmd *cmd) if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED && cmd->cdb[1] & 1) { int block_size = cmd->dev->block_size; + cmd->bufflen = cmd->bufflen * block_size; cmd->data_len = cmd->data_len * block_size; cmd->out_bufflen = cmd->out_bufflen * block_size; @@ -12194,6 +12238,7 @@ static void scst_check_internal_sense(struct scst_device *dev, int result, if (host_byte(result) == DID_RESET) { int sl; + TRACE(TRACE_MGMT, "DID_RESET received for device %s, " "triggering reset UA", dev->virt_name); sl = scst_set_sense(sense, sense_len, dev->d_sense, @@ -12383,6 +12428,7 @@ again: for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { /* Lockdep triggers here a false positive.. */ @@ -12425,6 +12471,7 @@ again: list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { struct scst_tgt_dev_UA *ua; + list_for_each_entry(ua, &tgt_dev->UA_list, UA_list_entry) { if (ua->global_UA && @@ -12456,6 +12503,7 @@ out_unlock: for (i = SESS_TGT_DEV_LIST_HASH_SIZE-1; i >= 0; i--) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry_reverse(tgt_dev, head, sess_tgt_dev_list_entry) { spin_unlock(&tgt_dev->tgt_dev_lock); @@ -13601,6 +13649,7 @@ static int scst_parse_unmap_descriptors(struct scst_cmd *cmd) i = 0; while ((offset - 8) < descriptor_len) { struct scst_data_descriptor *d = &pd[i]; + d->sdd_lba = get_unaligned_be64(&address[offset]); offset += 8; d->sdd_blocks = get_unaligned_be32(&address[offset]); @@ -14823,6 +14872,7 @@ static void tm_dbg_deinit_tgt_dev(struct scst_tgt_dev *tgt_dev) { if (tm_dbg_tgt_dev == tgt_dev) { unsigned long flags; + TRACE_MGMT_DBG("Deinit TM debugging tgt_dev %p", tgt_dev); del_timer_sync(&tm_dbg_timer); spin_lock_irqsave(&scst_tm_dbg_lock, flags); @@ -14847,6 +14897,7 @@ static void tm_dbg_delay_cmd(struct scst_cmd *cmd) case TM_DBG_STATE_ABORT: if (tm_dbg_delayed_cmds_count == 0) { unsigned long d = 58*HZ + (scst_random() % (4*HZ)); + TRACE_MGMT_DBG("STATE ABORT: delaying cmd %p (tag %llu)" " for %ld.%ld seconds (%ld HZ), " "tm_dbg_on_state_passes=%d", cmd, cmd->tag, @@ -14892,6 +14943,7 @@ void tm_dbg_check_released_cmds(void) { if (tm_dbg_flags.tm_dbg_release) { struct scst_cmd *cmd, *tc; + spin_lock_irq(&scst_tm_dbg_lock); list_for_each_entry_safe_reverse(cmd, tc, &tm_dbg_delayed_cmd_list, cmd_list_entry) { @@ -15073,6 +15125,7 @@ void scst_check_debug_sn(struct scst_cmd *cmd) /* To simulate from time to time queue flushing */ if (!in_interrupt() && (scst_random() % 120) == 8) { int t = scst_random() % 1200; + TRACE_SN("Delaying IO on %d ms", t); msleep(t); } diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index 709cc1a20..63d2e8e37 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -596,6 +596,7 @@ EXPORT_SYMBOL(scst_register_target); static inline int test_sess_list(struct scst_tgt *tgt) { int res; + mutex_lock(&scst_mutex); res = list_empty(&tgt->sysfs_sess_list); mutex_unlock(&scst_mutex); @@ -637,6 +638,7 @@ void scst_unregister_target(struct scst_tgt *tgt) again: { struct scst_session *sess; + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { if (sess->shut_phase == SCST_SESS_SPH_READY) { /* @@ -870,6 +872,7 @@ static void __printf(2, 3) scst_to_syslog(void *arg, const char *fmt, ...) int scst_get_cmd_counter(void) { int i, res = 0; + for (i = 0; i < (int)ARRAY_SIZE(scst_percpu_infos); i++) res += atomic_read(&scst_percpu_infos[i].cpu_cmd_count); return res; @@ -1877,6 +1880,7 @@ int scst_add_threads(struct scst_cmd_threads *cmd_threads, if (tgt_dev != NULL) { struct scst_tgt_dev *t; + list_for_each_entry(t, &tgt_dev->dev->dev_tgt_dev_list, dev_tgt_dev_list_entry) { if (t == tgt_dev) @@ -2447,6 +2451,7 @@ static int __init init_scst(void) struct scsi_sense_hdr *shdr; struct scst_order_data *o; struct scst_cmd *c; + BUILD_BUG_ON(sizeof(*shdr) > SCST_SENSE_BUFFERSIZE); BUILD_BUG_ON(sizeof(o->curr_sn) != sizeof(o->expected_sn)); BUILD_BUG_ON(sizeof(c->sn) != sizeof(o->expected_sn)); @@ -2606,6 +2611,7 @@ static int __init init_scst(void) if (scst_max_cmd_mem == 0) { struct sysinfo si; + si_meminfo(&si); #if BITS_PER_LONG == 32 scst_max_cmd_mem = min( diff --git a/scst/src/scst_mem.c b/scst/src/scst_mem.c index 1706acb78..488132c07 100644 --- a/scst/src/scst_mem.c +++ b/scst/src/scst_mem.c @@ -675,6 +675,7 @@ static int sgv_alloc_sg_entries(struct scatterlist *sg, int pages, pg = 0; for (i = 0; i < pages; i++) { int n = PAGE_ALIGN(sg[i].length) >> PAGE_SHIFT; + trans_tbl[i].pg_count = pg; for (j = 0; j < n; j++) trans_tbl[pg++].sg_num = i+1; @@ -972,6 +973,7 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size, pages = PAGE_ALIGN(size) >> PAGE_SHIFT; if (pool->single_alloc_pages == 0) { int pages_order = get_order(size); + cache_num = pages_order; pages_to_alloc = (1 << pages_order); } else { @@ -1128,6 +1130,7 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size, success: if (cache_num >= 0) { int sg; + atomic_inc(&pool->cache_acc[cache_num].total_alloc); if (sgv_pool_clustered(pool)) cnt = obj->trans_tbl[pages-1].sg_num; @@ -1255,10 +1258,12 @@ void sgv_pool_free(struct sgv_pool_obj *obj, struct scst_mem_lim *mem_lim) { struct scatterlist *sg = obj->sg_entries; int i; + for (i = 0; i < obj->sg_count; i++) { struct page *p = sg_page(&sg[i]); int len = sg[i].length; int pages = PAGE_ALIGN(len) >> PAGE_SHIFT; + while (pages > 0) { if (page_count(p) != 1) { PRINT_WARNING("Freeing page %p with " diff --git a/scst/src/scst_pres.c b/scst/src/scst_pres.c index 037c0d462..8d48ab86f 100644 --- a/scst/src/scst_pres.c +++ b/scst/src/scst_pres.c @@ -103,6 +103,7 @@ static inline void tid_secure(uint8_t *tid) { if ((tid[0] & 0x0f) == SCSI_TRANSPORTID_PROTOCOLID_ISCSI) { int size = scst_tid_size(tid); + tid[size - 1] = '\0'; } @@ -137,6 +138,7 @@ bool tid_equal(const uint8_t *tid_a, const uint8_t *tid_b) else if (tid_a_fmt == 0x40) { if (tid_a_fmt != tid_b_fmt) { uint8_t *p = strnchr(tid_a, tid_a_max, ','); + if (p == NULL) goto out_error; tid_a_len = p - tid_a; @@ -153,6 +155,7 @@ bool tid_equal(const uint8_t *tid_a, const uint8_t *tid_b) else if (tid_b_fmt == 0x40) { if (tid_a_fmt != tid_b_fmt) { uint8_t *p = strnchr(tid_b, tid_b_max, ','); + if (p == NULL) goto out_error; tid_b_len = p - tid_b; @@ -243,6 +246,7 @@ void scst_pr_dump_prs(struct scst_device *dev, bool force) else { struct scst_dev_registrant *reg; int i = 0; + list_for_each_entry(reg, &dev->dev_registrants_list, dev_registrants_list_entry) { PRINT_INFO(" [%d] registrant %s/%d, key %016llx " @@ -256,6 +260,7 @@ void scst_pr_dump_prs(struct scst_device *dev, bool force) if (dev->pr_is_set) { struct scst_dev_registrant *holder = dev->pr_holder; + if (holder != NULL) PRINT_INFO("Reservation holder is %s/%d (key %016llx, " "scope %x, type %x, reg %p, tgt_dev %p)", @@ -629,6 +634,7 @@ static void scst_pr_abort_reg(struct scst_device *dev, if ((reg->tgt_dev != pr_cmd->tgt_dev) && !dev->tas) { uint8_t sense_buffer[SCST_STANDARD_SENSE_LEN]; int sl; + sl = scst_set_sense(sense_buffer, sizeof(sense_buffer), dev->d_sense, SCST_LOAD_SENSE(scst_sense_cleared_by_another_ini_UA)); diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index f0606d677..0fe533b40 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -753,6 +753,7 @@ static inline atomic_t *scst_get(void) static inline void scst_put(atomic_t *a) { int f; + f = atomic_dec_and_test(a); /* See comment about smp_mb() in scst_suspend_activity() */ if (unlikely(test_bit(SCST_FLAG_SUSPENDED, &scst_flags)) && f) { diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index c67891ee3..1538066c4 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -668,9 +668,11 @@ static int scst_check_tgt_acg_ptrs(struct scst_tgt *tgt, struct scst_acg *acg) list_for_each_entry(tgtt, &scst_template_list, scst_template_list_entry) { struct scst_tgt *t; + list_for_each_entry(t, &tgtt->tgt_list, tgt_list_entry) { if (t == tgt) { struct scst_acg *a; + if (acg == NULL) goto out; if (acg == tgt->default_acg) @@ -783,8 +785,8 @@ static ssize_t scst_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct kobj_attribute *kobj_attr; - kobj_attr = container_of(attr, struct kobj_attribute, attr); + kobj_attr = container_of(attr, struct kobj_attribute, attr); return kobj_attr->show(kobj, kobj_attr, buf); } @@ -792,8 +794,8 @@ static ssize_t scst_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { struct kobj_attribute *kobj_attr; - kobj_attr = container_of(attr, struct kobj_attribute, attr); + kobj_attr = container_of(attr, struct kobj_attribute, attr); if (kobj_attr->store) return kobj_attr->store(kobj, kobj_attr, buf, count); else @@ -1073,6 +1075,7 @@ static ssize_t scst_tgtt_dif_capable_show(struct kobject *kobj, if (tgtt->supported_dif_block_sizes) { const int *p = tgtt->supported_dif_block_sizes; int j; + pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, "Supported blocks: "); j = pos; @@ -1893,9 +1896,11 @@ static ssize_t __scst_acg_black_hole_store(struct scst_acg *acg, list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) { int i; + for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { if (t != SCST_ACG_BLACK_HOLE_NONE) set_bit(SCST_TGT_DEV_BLACK_HOLE, &tgt_dev->tgt_dev_flags); @@ -1991,9 +1996,11 @@ static int __scst_acg_process_cpu_mask_store(struct scst_tgt *tgt, list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) { int i; + for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct scst_tgt_dev *tgt_dev; struct list_head *head = &sess->sess_tgt_dev_list[i]; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { int rc; @@ -2562,9 +2569,11 @@ static ssize_t scst_tgt_forwarding_store(struct kobject *kobj, list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { int i; + for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { if (tgt->tgt_forwarding) set_bit(SCST_TGT_DEV_FORWARDING, &tgt_dev->tgt_dev_flags); @@ -2727,6 +2736,7 @@ static ssize_t scst_tgt_dif_capable_show(struct kobject *kobj, if (tgt->tgt_supported_dif_block_sizes) { const int *p = tgt->tgt_supported_dif_block_sizes; int j; + pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, "Supported blocks: "); j = pos; @@ -4463,6 +4473,7 @@ static int scst_sess_zero_latency(struct scst_sysfs_work_item *work) for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) { struct list_head *head = &sess->sess_tgt_dev_list[t]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { tgt_dev->scst_time = 0; tgt_dev->tgt_time = 0; @@ -4546,6 +4557,7 @@ static int scst_sysfs_sess_get_active_commands(struct scst_session *sess) for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) { struct list_head *head = &sess->sess_tgt_dev_list[t]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { active_cmds += atomic_read(&tgt_dev->tgt_dev_cmd_count); } @@ -4615,6 +4627,7 @@ static int scst_sysfs_sess_get_dif_checks_failed_work_fn(struct scst_sysfs_work_ for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) { struct list_head *head = &sess->sess_tgt_dev_list[t]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { app_failed_tgt += atomic_read(&tgt_dev->tgt_dev_dif_app_failed_tgt); ref_failed_tgt += atomic_read(&tgt_dev->tgt_dev_dif_ref_failed_tgt); @@ -4695,6 +4708,7 @@ static int scst_sess_zero_dif_checks_failed(struct scst_sysfs_work_item *work) for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) { struct list_head *head = &sess->sess_tgt_dev_list[t]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { atomic_set(&tgt_dev->tgt_dev_dif_app_failed_tgt, 0); atomic_set(&tgt_dev->tgt_dev_dif_ref_failed_tgt, 0); diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 41713a72c..b9453278d 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -117,6 +117,7 @@ static bool scst_unmap_overlap(struct scst_cmd *cmd, int64_t lba2, for (i = 0; pd[i].sdd_blocks != 0; i++) { struct scst_data_descriptor *d = &pd[i]; + TRACE_DBG("i %d, lba %lld, blocks %lld", i, (long long)d->sdd_lba, (long long)d->sdd_blocks); res = scst_lba1_inside_lba2(d->sdd_lba, lba2, lba2_blocks); @@ -292,6 +293,7 @@ static bool scst_check_scsi_atomicity(struct scst_cmd *chk_cmd) continue; if (scst_cmd_overlap(chk_cmd, cmd)) { struct scst_cmd **p = cmd->scsi_atomic_blocked_cmds; + /* * kmalloc() allocates by at least 32 bytes increments, * hence krealloc() on 8 bytes increments, if not all @@ -328,6 +330,7 @@ out: out_busy_undo: list_for_each_entry(cmd, &dev->dev_exec_cmd_list, dev_exec_cmd_list_entry) { struct scst_cmd **p = cmd->scsi_atomic_blocked_cmds; + if ((p != NULL) && (p[cmd->scsi_atomic_blocked_cmds_count-1] == chk_cmd)) { cmd->scsi_atomic_blocked_cmds_count--; chk_cmd->scsi_atomic_blockers--; @@ -472,6 +475,7 @@ static void scst_check_unblock_scsi_atomic_cmds(struct scst_cmd *cmd) for (i = 0; i < cmd->scsi_atomic_blocked_cmds_count; i++) { struct scst_cmd *acmd = cmd->scsi_atomic_blocked_cmds[i]; + acmd->scsi_atomic_blockers--; if (acmd->scsi_atomic_blockers == 0) { TRACE_BLOCK("Unblocking blocked acmd %p (blocker " @@ -766,6 +770,7 @@ out_redirect: msleep(50); } else { unsigned long flags; + spin_lock_irqsave(&scst_init_lock, flags); TRACE_DBG("Adding cmd %p to init cmd list", cmd); list_add_tail(&cmd->cmd_list_entry, &scst_init_cmd_list); @@ -1401,6 +1406,7 @@ out_check_compl: if (unlikely(test_bit(SCST_TGT_DEV_BLACK_HOLE, &cmd->tgt_dev->tgt_dev_flags))) { struct scst_session *sess = cmd->sess; bool abort = false; + switch (sess->acg->acg_black_hole_type) { case SCST_ACG_BLACK_HOLE_CMD: case SCST_ACG_BLACK_HOLE_ALL: @@ -1803,6 +1809,7 @@ static int scst_rdy_to_xfer(struct scst_cmd *cmd) if (tgtt->on_hw_pending_cmd_timeout != NULL) { struct scst_session *sess = cmd->sess; + cmd->hw_pending_start = jiffies; cmd->cmd_hw_pending = 1; if (!test_bit(SCST_SESS_HW_PENDING_WORK_SCHEDULED, &sess->sess_aflags)) { @@ -2062,6 +2069,7 @@ static int scst_tgt_pre_exec(struct scst_cmd *cmd) if (unlikely(cmd->resid_possible)) { if (cmd->data_direction & SCST_DATA_WRITE) { bool remainder = false; + if (cmd->data_direction & SCST_DATA_READ) { if (cmd->write_len != cmd->out_bufflen) remainder = true; @@ -2141,6 +2149,7 @@ static int scst_tgt_pre_exec(struct scst_cmd *cmd) out_descr: if (unlikely(cmd->op_flags & SCST_DESCRIPTORS_BASED)) { int r = scst_parse_descriptors(cmd); + if (unlikely(r != 0)) goto out; } @@ -2314,6 +2323,7 @@ static int scst_report_luns_local(struct scst_cmd *cmd) */ for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &cmd->sess->sess_tgt_dev_list[i]; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { if (!overflow) { if ((buffer_size - offs) < 8) { @@ -3388,6 +3398,7 @@ static struct scst_cmd *scst_post_exec_sn(struct scst_cmd *cmd, if (inc_expected_sn) { bool rc = scst_inc_expected_sn(cmd); + if (!rc) goto out; if (make_active) @@ -3653,6 +3664,7 @@ static inline bool scst_check_alua(struct scst_cmd *cmd, int *out_res) alua_filter = ACCESS_ONCE(cmd->tgt_dev->alua_filter); if (unlikely(alua_filter)) { int ac = alua_filter(cmd); + if (ac != SCST_ALUA_CHECK_OK) { if (ac != SCST_ALUA_CHECK_DELAYED) { EXTRACHECKS_BUG_ON(cmd->status == 0); @@ -3692,6 +3704,7 @@ static int scst_exec_check_blocking(struct scst_cmd **active_cmd) #ifdef CONFIG_SCST_DEBUG_SN if ((scst_random() % 120) == 7) { int t = scst_random() % 200; + TRACE_SN("Delaying IO on %d ms", t); msleep(t); } @@ -3865,6 +3878,7 @@ static int scst_check_sense(struct scst_cmd *cmd) } else { int sl; uint8_t sense[SCST_STANDARD_SENSE_LEN]; + TRACE(TRACE_MGMT, "DID_RESET received for device %s, " "triggering reset UA", dev->virt_name); sl = scst_set_sense(sense, sizeof(sense), dev->d_sense, @@ -4041,6 +4055,7 @@ next: if (likely(scst_cmd_completed_good(cmd))) { if (cmd->deferred_dif_read_check) { int rc = scst_dif_process_read(cmd); + if (unlikely(rc != 0)) { cmd->deferred_dif_read_check = 0; goto again; @@ -4153,6 +4168,7 @@ static int scst_mode_select_checks(struct scst_cmd *cmd) if (likely(scsi_status_is_good(cmd->status))) { int atomic = scst_cmd_atomic(cmd); + if (unlikely((cmd->cdb[0] == MODE_SELECT) || (cmd->cdb[0] == MODE_SELECT_10) || (cmd->cdb[0] == LOG_SELECT))) { @@ -4206,6 +4222,7 @@ static int scst_mode_select_checks(struct scst_cmd *cmd) SCST_SENSE_ASC_VALID, 0, 0x2F, 0))) { int atomic = scst_cmd_atomic(cmd); + if (atomic) { TRACE_DBG("Possible parameters changed UA %x: " "thread context required", cmd->sense[12]); @@ -4315,6 +4332,7 @@ static int scst_dev_done(struct scst_cmd *cmd) if (cmd->inc_expected_sn_on_done && cmd->sent_for_exec && cmd->sn_set) { bool rc = scst_inc_expected_sn(cmd); + if (rc) scst_make_deferred_commands_active(cmd->cur_order_data); } @@ -4478,6 +4496,7 @@ static int scst_xmit_response(struct scst_cmd *cmd) (cmd->data_direction & SCST_DATA_READ)) { int i, sg_cnt; struct scatterlist *sg, *sgi; + if (cmd->tgt_i_sg != NULL) { sg = cmd->tgt_i_sg; sg_cnt = cmd->tgt_i_sg_cnt; @@ -4502,6 +4521,7 @@ static int scst_xmit_response(struct scst_cmd *cmd) if (tgtt->on_hw_pending_cmd_timeout != NULL) { struct scst_session *sess = cmd->sess; + cmd->hw_pending_start = jiffies; cmd->cmd_hw_pending = 1; if (!test_bit(SCST_SESS_HW_PENDING_WORK_SCHEDULED, &sess->sess_aflags)) { @@ -4762,6 +4782,7 @@ again: order_data->cur_sn_slot = order_data->sn_slots; if (unlikely(atomic_read(order_data->cur_sn_slot) != 0)) { static int q; + if (q++ < 10) PRINT_WARNING("Not enough SN slots " "(dev %s)", cmd->dev->virt_name); @@ -5002,6 +5023,7 @@ static int __scst_init_cmd(struct scst_cmd *cmd) else { struct scst_order_data *order_data = cmd->cur_order_data; unsigned long flags; + spin_lock_irqsave(&order_data->init_done_lock, flags); scst_cmd_set_sn(cmd); spin_unlock_irqrestore(&order_data->init_done_lock, flags); @@ -5046,6 +5068,7 @@ restart: list_for_each_entry(cmd, &scst_init_cmd_list, cmd_list_entry) { int rc; + if (susp && !test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) continue; if (!test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) { @@ -5922,6 +5945,7 @@ void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd, if (mstb->done_counted || mstb->finish_counted) { unsigned long t; char state_name[32]; + if (mcmd->fn != SCST_PR_ABORT_ALL) t = TRACE_MGMT; else @@ -6009,6 +6033,7 @@ static int scst_set_mcmd_next_state(struct scst_mgmt_cmd *mcmd) default: { char fn_name[16], state_name[32]; + PRINT_CRIT_ERROR("Wrong mcmd %p state %s (fn %s, " "cmd_finish_wait_count %d, cmd_done_wait_count %d)", mcmd, scst_get_mcmd_state_name(state_name, @@ -6033,6 +6058,7 @@ static bool __scst_check_unblock_aborted_cmd(struct scst_cmd *cmd, struct list_head *list_entry, bool blocked) { bool res; + if (test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) { list_del(list_entry); if (blocked) @@ -6090,6 +6116,7 @@ void scst_unblock_aborted_cmds(const struct scst_tgt *tgt, list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, dev_tgt_dev_list_entry) { struct scst_order_data *order_data = tgt_dev->curr_order_data; + spin_lock(&order_data->sn_lock); list_for_each_entry_safe(cmd, tcmd, &order_data->deferred_cmd_list, @@ -6590,6 +6617,7 @@ static void scst_do_nexus_loss_sess(struct scst_mgmt_cmd *mcmd) for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { scst_nexus_loss(tgt_dev, (mcmd->fn != SCST_UNREG_SESS_TM)); @@ -6623,6 +6651,7 @@ static int scst_abort_all_nexus_loss_sess(struct scst_mgmt_cmd *mcmd, for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { __scst_abort_task_set(mcmd, tgt_dev); @@ -6657,6 +6686,7 @@ static void scst_do_nexus_loss_tgt(struct scst_mgmt_cmd *mcmd) for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { scst_nexus_loss(tgt_dev, true); @@ -6692,6 +6722,7 @@ static int scst_abort_all_nexus_loss_tgt(struct scst_mgmt_cmd *mcmd, for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { __scst_abort_task_set(mcmd, tgt_dev); @@ -6884,6 +6915,7 @@ static int scst_mgmt_affected_cmds_done(struct scst_mgmt_cmd *mcmd) { struct scst_acg *acg = sess->acg; struct scst_acg_dev *acg_dev; + mutex_lock(&scst_mutex); list_for_each_entry(acg_dev, &acg->acg_dev_list, acg_dev_list_entry) { dev = acg_dev->dev; @@ -6905,6 +6937,7 @@ static int scst_mgmt_affected_cmds_done(struct scst_mgmt_cmd *mcmd) mutex_lock(&scst_mutex); for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &sess->sess_tgt_dev_list[i]; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { scst_call_dev_task_mgmt_fn_done(mcmd, tgt_dev); } @@ -6917,11 +6950,13 @@ static int scst_mgmt_affected_cmds_done(struct scst_mgmt_cmd *mcmd) { struct scst_session *s; struct scst_tgt *tgt = sess->tgt; + mutex_lock(&scst_mutex); list_for_each_entry(s, &tgt->sess_list, sess_list_entry) { for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) { struct list_head *head = &s->sess_tgt_dev_list[i]; struct scst_tgt_dev *tgt_dev; + list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { if (mcmd->sess == tgt_dev->sess) @@ -7073,6 +7108,7 @@ static int scst_process_mgmt_cmd(struct scst_mgmt_cmd *mcmd) default: { char fn_name[16], state_name[32]; + PRINT_CRIT_ERROR("Wrong mcmd %p state %s (fn %s, " "cmd_finish_wait_count %d, cmd_done_wait_count " "%d)", mcmd, scst_get_mcmd_state_name(state_name, @@ -7116,6 +7152,7 @@ int scst_tm_thread(void *arg) while (!list_empty(&scst_active_mgmt_cmd_list)) { int rc; struct scst_mgmt_cmd *mcmd; + mcmd = list_first_entry(&scst_active_mgmt_cmd_list, typeof(*mcmd), mgmt_cmd_list_entry); TRACE_MGMT_DBG("Deleting mgmt cmd %p from active cmd " @@ -8114,6 +8151,7 @@ struct scst_cmd *scst_find_cmd_by_tag(struct scst_session *sess, { unsigned long flags; struct scst_cmd *cmd; + spin_lock_irqsave(&sess->sess_list_lock, flags); cmd = __scst_find_cmd_by_tag(sess, tag, false); spin_unlock_irqrestore(&sess->sess_list_lock, flags); diff --git a/scst/src/scst_tg.c b/scst/src/scst_tg.c index 86e61883f..e9f818095 100644 --- a/scst/src/scst_tg.c +++ b/scst/src/scst_tg.c @@ -906,6 +906,7 @@ static void scst_event_stpg_notify_fn(struct scst_event *event, for (i = 0, d = &p->stpg_descriptors[0]; i < p->stpg_descriptors_cnt; i++, d++) { struct scst_target_group *tg = __lookup_tg_by_group_id(dg, d->group_id); + if (!tg) { PRINT_ERROR("STPG: unable to find TG %d", d->group_id); goto out_fail; @@ -967,6 +968,7 @@ static void __scst_tg_set_state(struct scst_target_group *tg, list_for_each_entry(tg_tgt, &tg->tgt_list, entry) { if (tg_tgt->tgt == tgt) { bool gen_ua = (state != SCST_TG_STATE_TRANSITIONING); + if ((tg->dg->stpg_rel_tgt_id == tgt_dev->sess->tgt->rel_tgt_id) && tid_equal(tg->dg->stpg_transport_id, tgt_dev->sess->transport_id)) gen_ua = false;