From: <vl...@us...> - 2008-02-29 18:26:00
|
Revision: 297 http://scst.svn.sourceforge.net/scst/?rev=297&view=rev Author: vlnb Date: 2008-02-29 10:25:56 -0800 (Fri, 29 Feb 2008) Log Message: ----------- - TM fixes - Optimizations and send timeout introduced in r295 temporary disabled - Big connection shutdown times improvements. Great thanks to Alexey Kuznetsov for suggestions! - RESERVE/RELEASE serialization now made with TST field 0 (i.e. single task set) - Other minor fixes and improvements Modified Paths: -------------- trunk/iscsi-scst/README trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/iscsi_dbg.h trunk/iscsi-scst/kernel/nthread.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/iscsi-scst/README 2008-02-29 18:25:56 UTC (rev 297) @@ -115,15 +115,6 @@ like 8 (default is 32). See also SCST README file for more details about that issue. -Sometimes, when there are communication problems with initiator(s), -shutting down iSCSI-SCST can take very long time, up to about 10 -minutes. This can happen, because iSCSI-SCST can't be shutdown before -all already sent to TCP for initiator(s) data will be actually sent -and/or released by TCP. In case of communication failures this can take -up to TCP transmit timeout, which is about 10 minutes. In such cases -using netstat utility you can see that there is/are connection(s) to -initiator(s) with non-0 "Send-Q". - CAUTION: Working of target and initiator on the same host isn't ======== supported. See SCST README file for details. Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-02-29 18:25:56 UTC (rev 297) @@ -1742,7 +1742,7 @@ struct iscsi_session *sess = conn->session; struct iscsi_task_mgt_hdr *req_hdr = (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; - int err = 0, function = req_hdr->function & ISCSI_FUNCTION_MASK; + int rc, status, function = req_hdr->function & ISCSI_FUNCTION_MASK; struct scst_rx_mgmt_params params; TRACE((function == ISCSI_FUNCTION_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, @@ -1754,13 +1754,20 @@ iscsi_extracheck_is_rd_thread(conn); spin_lock(&sess->sn_lock); - sess->tm_active = 1; + sess->tm_active++; sess->tm_sn = req_hdr->cmd_sn; if (sess->tm_rsp != NULL) { struct iscsi_cmnd *tm_rsp = sess->tm_rsp; + TRACE(TRACE_MGMT_MINOR, "Dropping delayed TM rsp %p", tm_rsp); + sess->tm_rsp = NULL; + sess->tm_active--; + spin_unlock(&sess->sn_lock); + + sBUG_ON(sess->tm_active < 0); + rsp_cmnd_release(tm_rsp); } else spin_unlock(&sess->sn_lock); @@ -1773,7 +1780,8 @@ (req_hdr->rtt != ISCSI_RESERVED_TAG)) { PRINT_ERROR("Invalid RTT %x (TM fn %x)", req_hdr->rtt, function); - err = -1; + rc = -1; + status = ISCSI_RESPONSE_FUNCTION_REJECTED; goto reject; } @@ -1781,8 +1789,9 @@ switch (function) { case ISCSI_FUNCTION_ABORT_TASK: - err = cmnd_abort(req); - if (err == 0) { + rc = -1; + status = cmnd_abort(req); + if (status == 0) { params.fn = SCST_ABORT_TASK; params.tag = req_hdr->rtt; params.tag_set = 1; @@ -1791,8 +1800,9 @@ params.lun_set = 1; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; } break; case ISCSI_FUNCTION_ABORT_TASK_SET: @@ -1803,8 +1813,9 @@ params.lun_set = 1; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; case ISCSI_FUNCTION_CLEAR_TASK_SET: task_set_abort(req); @@ -1814,8 +1825,9 @@ params.lun_set = 1; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; case ISCSI_FUNCTION_CLEAR_ACA: params.fn = SCST_CLEAR_ACA; @@ -1824,8 +1836,9 @@ params.lun_set = 1; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; case ISCSI_FUNCTION_TARGET_COLD_RESET: case ISCSI_FUNCTION_TARGET_WARM_RESET: @@ -1833,8 +1846,9 @@ params.fn = SCST_TARGET_RESET; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; case ISCSI_FUNCTION_LOGICAL_UNIT_RESET: target_abort(req, 0); @@ -1844,25 +1858,26 @@ params.lun_set = 1; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; case ISCSI_FUNCTION_TASK_REASSIGN: - iscsi_send_task_mgmt_resp(req, - ISCSI_RESPONSE_FUNCTION_UNSUPPORTED); + rc = -1; + status = ISCSI_RESPONSE_FUNCTION_UNSUPPORTED; break; default: PRINT_ERROR("Unknown TM function %d", function); - iscsi_send_task_mgmt_resp(req, - ISCSI_RESPONSE_FUNCTION_REJECTED); + rc = -1; + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; } reject: - if (err != 0) { - iscsi_send_task_mgmt_resp(req, - ISCSI_RESPONSE_FUNCTION_REJECTED); - } + if (rc != 0) + iscsi_send_task_mgmt_resp(req, status); + + return; } static void noop_out_exec(struct iscsi_cmnd *req) @@ -2140,7 +2155,7 @@ while (1) { session->exp_cmd_sn = ++cmd_sn; - if (unlikely(session->tm_active)) { + if (unlikely(session->tm_active > 0)) { if (before(cmd_sn, session->tm_sn)) { struct iscsi_conn *conn = cmnd->conn; @@ -2476,7 +2491,11 @@ u8 *sense = scst_cmd_get_sense_buffer(scst_cmd); int sense_len = scst_cmd_get_sense_buffer_len(scst_cmd); int old_state = req->scst_state; +#if 0 /* temp. ToDo */ bool single_only = !scst_get_long_xmit(scst_cmd); +#else + bool single_only = 0; +#endif scst_cmd_set_tgt_priv(scst_cmd, NULL); @@ -2622,10 +2641,12 @@ TRACE(TRACE_MGMT_MINOR, "Sending delayed rsp %p", tm_rsp); sess->tm_rsp = NULL; - sess->tm_active = 0; + sess->tm_active--; spin_unlock(&sess->sn_lock); + sBUG_ON(sess->tm_active < 0); + iscsi_cmnd_init_write(tm_rsp, ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); @@ -2676,9 +2697,11 @@ spin_unlock(&sess->sn_lock); goto out_release; } - sess->tm_active = 0; + sess->tm_active--; spin_unlock(&sess->sn_lock); + sBUG_ON(sess->tm_active < 0); + iscsi_cmnd_init_write(rsp, ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-02-29 18:25:56 UTC (rev 297) @@ -99,8 +99,7 @@ u32 exp_cmd_sn; /* protected by sn_lock */ /* All 3 protected by sn_lock */ - unsigned int tm_active:1; - unsigned int shutting_down:1; /* Let's save some cache footprint by putting it here */ + int tm_active; u32 tm_sn; struct iscsi_cmnd *tm_rsp; @@ -118,6 +117,7 @@ /* Both don't need any protection */ char *initiator_name; + unsigned int shutting_down:1; u64 sid; }; Modified: trunk/iscsi-scst/kernel/iscsi_dbg.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi_dbg.h 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/iscsi-scst/kernel/iscsi_dbg.h 2008-02-29 18:25:56 UTC (rev 297) @@ -35,7 +35,7 @@ #ifdef DEBUG #define ISCSI_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_LINE | TRACE_PID | \ TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_MINOR | TRACE_MGMT_DEBUG | \ - TRACE_MINOR | TRACE_SPECIAL | TRACE_CONN_OC | TRACE_CONN_OC_DBG) + TRACE_MINOR | TRACE_SPECIAL | TRACE_CONN_OC) #else #define ISCSI_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | \ TRACE_MINOR | TRACE_SPECIAL) Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/iscsi-scst/kernel/nthread.c 2008-02-29 18:25:56 UTC (rev 297) @@ -61,16 +61,17 @@ TRACE_ENTRY(); - if ((conn->sock->sk->sk_state != TCP_CLOSE_WAIT) && - (conn->sock->sk->sk_state != TCP_CLOSE)) { - TRACE_CONN_CLOSE("sk_state %d, skipping", - conn->sock->sk->sk_state); + TRACE_CONN_CLOSE("conn %p, sk_state %d", conn, conn->sock->sk->sk_state); + + if (conn->sock->sk->sk_state != TCP_CLOSE) { + TRACE_CONN_CLOSE_DBG("conn %p, skipping", conn); goto out; } /* - * No data are going to be sent, so all being sent buffers can be freed - * now. Strange that TCP doesn't do that itself. + * No data are going to be sent, so all queued buffers can be freed + * now. In many cases TCP does that only in close(), but we can't rely + * on user space on calling it. */ again: @@ -235,7 +236,8 @@ TRACE(TRACE_MGMT_MINOR, "Dropping delayed TM rsp %p", tm_rsp); session->tm_rsp = NULL; - session->tm_active = 0; + session->tm_active--; + WARN_ON(session->tm_active < 0); spin_unlock(&session->sn_lock); mutex_unlock(&target->target_mutex); @@ -329,10 +331,18 @@ iscsi_make_conn_wr_active(conn); if (time_after(jiffies, start_waiting + 7*HZ)) { - TRACE_CONN_CLOSE("%s", "Wait time expired"); + TRACE_CONN_CLOSE("Wait time expired (conn %p, " + "sk_state %d)", conn, conn->sock->sk->sk_state); conn->sock->ops->shutdown(conn->sock, SEND_SHUTDOWN); } + if (time_after(jiffies, start_waiting + 15*HZ)) { + TRACE_CONN_CLOSE("Wait time after shutdown expired " + "(conn %p, sk_state %d)", conn, + conn->sock->sk->sk_state); + conn->sock->sk->sk_prot->disconnect(conn->sock->sk, 0); + } + msleep(200); TRACE_CONN_CLOSE("conn %p, conn_ref_cnt %d left, wr_state %d, " @@ -914,6 +924,7 @@ spin_unlock_bh(&conn->write_list_lock); } +#if 0 /* temp. ToDo */ if (!timer_pending(&conn->rsp_timer)) { sBUG_ON(!ref_cmd->on_written_list); spin_lock_bh(&conn->write_list_lock); @@ -925,6 +936,7 @@ } spin_unlock_bh(&conn->write_list_lock); } +#endif file = conn->file; saved_size = size = conn->write_size; Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2008-02-29 18:25:56 UTC (rev 297) @@ -2571,6 +2571,43 @@ return res; } +static void vdisk_report_registering(const char *type, + const struct scst_vdisk_dev *virt_dev) +{ + char buf[128]; + int i, j; + + i = snprintf(buf, sizeof(buf), "Registering virtual %s device %s", + type, virt_dev->name); + j = i; + + if (virt_dev->wt_flag) + i += snprintf(&buf[i], sizeof(buf) - i, " (WRITE_THROUGH"); + + if (virt_dev->nv_cache) + i += snprintf(&buf[i], sizeof(buf) - i, "%sNV_CACHE", + (j == i) ? "(" : ", "); + + if (virt_dev->rd_only_flag) + i += snprintf(&buf[i], sizeof(buf) - i, "%sREAD_ONLY", + (j == i) ? "(" : ", "); + + if (virt_dev->o_direct_flag) + i += snprintf(&buf[i], sizeof(buf) - i, "%sO_DIRECT", + (j == i) ? "(" : ", "); + + if (virt_dev->nullio) + i += snprintf(&buf[i], sizeof(buf) - i, "%sNULLIO", + (j == i) ? "(" : ", "); + + if (j == i) + PRINT_INFO("%s", buf); + else + PRINT_INFO("%s)", buf); + + return; +} + /* * Called when a file in the /proc/VDISK_NAME/VDISK_NAME is written */ @@ -2753,14 +2790,17 @@ list_add_tail(&virt_dev->vdisk_dev_list_entry, &vdisk_dev_list); - if (virt_dev->blockio) + if (virt_dev->blockio) { + vdisk_report_registering("BLOCKIO", virt_dev); virt_dev->virt_id = scst_register_virtual_device(&vdisk_blk_devtype, virt_dev->name); - else + } else { + vdisk_report_registering("FILEIO", virt_dev); virt_dev->virt_id = scst_register_virtual_device(&vdisk_devtype, virt_dev->name); + } if (virt_dev->virt_id < 0) { res = virt_dev->virt_id; goto out_free_vpath; @@ -2880,6 +2920,8 @@ list_add_tail(&virt_dev->vdisk_dev_list_entry, &vcdrom_dev_list); + PRINT_INFO("Registering virtual CDROM %s", name); + virt_dev->virt_id = scst_register_virtual_device(&vcdrom_devtype, virt_dev->name); Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/scst/src/scst_lib.c 2008-02-29 18:25:56 UTC (rev 297) @@ -719,13 +719,15 @@ out: if (res == 0) { if (dev->virt_name != NULL) { - PRINT_INFO("Added device %s to group %s", - dev->virt_name, acg->acg_name); + PRINT_INFO("Added device %s to group %s (LUN %Ld, " + "rd_only %d)", dev->virt_name, acg->acg_name, + lun, read_only); } else { - PRINT_INFO("Added device %d:%d:%d:%d to group %s", - dev->scsi_dev->host->host_no, + PRINT_INFO("Added device %d:%d:%d:%d to group %s (LUN " + "%Ld, rd_only %d)", dev->scsi_dev->host->host_no, dev->scsi_dev->channel, dev->scsi_dev->id, - dev->scsi_dev->lun, acg->acg_name); + dev->scsi_dev->lun, acg->acg_name, lun, + read_only); } } @@ -1568,9 +1570,9 @@ flags |= SCST_POOL_ALLOC_NO_CACHED; if (unlikely(cmd->bufflen == 0)) { - TRACE(TRACE_MGMT_MINOR, "Data direction %d or/and zero buffer " - "length. Opcode 0x%x, handler %s, target %s", - cmd->data_direction, cmd->cdb[0], + TRACE(TRACE_MGMT_MINOR, "Warning: data direction %d or/and " + "zero buffer length. Opcode 0x%x, handler %s, target " + "%s", cmd->data_direction, cmd->cdb[0], cmd->dev->handler->name, cmd->tgtt->name); /* * Be on the safe side and alloc stub buffer. Neither target Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/scst/src/scst_priv.h 2008-02-29 18:25:56 UTC (rev 297) @@ -240,7 +240,9 @@ spin_lock_irq(&c->cmd_lists->cmd_list_lock); list_add_tail(&c->cmd_list_entry, &c->cmd_lists->active_cmd_list); +#if 0 /* temp. ToDo */ if (!curr_cmd->context_processable || curr_cmd->long_xmit) +#endif wake_up(&c->cmd_lists->cmd_list_waitQ); spin_unlock_irq(&c->cmd_lists->cmd_list_lock); } Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/scst/src/scst_targ.c 2008-02-29 18:25:56 UTC (rev 297) @@ -476,6 +476,7 @@ PRINT_ERROR("Dev handler supplied data buffer (size %d), " "is less, than required (size %d)", cmd->bufflen, orig_bufflen); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); goto out_error; } @@ -487,6 +488,7 @@ PRINT_ERROR("Unknown data transfer length for opcode 0x%x " "(handler %s, target %s)", cmd->cdb[0], dev->handler->name, cmd->tgtt->name); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); goto out_error; } @@ -499,6 +501,7 @@ "or sg %p (opcode 0x%x)", dev->handler->name, cmd->data_direction, cmd->bufflen, state, cmd->sg, cmd->cdb[0]); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); goto out_error; } #endif @@ -513,20 +516,27 @@ "bufflen %d, expected_transfer_len %d", cmd->data_direction, cmd->expected_data_direction, cmd->bufflen, cmd->expected_transfer_len); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); } # endif cmd->data_direction = cmd->expected_data_direction; cmd->bufflen = cmd->expected_transfer_len; #else if (unlikely(cmd->data_direction != cmd->expected_data_direction)) { - PRINT_ERROR("Expected data direction %d for opcode " - "0x%02x (handler %s, target %s) doesn't match " - "decoded value %d", cmd->data_direction, - cmd->cdb[0], dev->handler->name, - cmd->tgtt->name, cmd->expected_data_direction); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_message)); - goto out_dev_done; + if (((cmd->expected_data_direction != SCST_DATA_NONE) || + (cmd->bufflen != 0)) && + /* Crazy VMware people sometimes do TUR with READ direction */ + !(cmd->cdb[0] == TEST_UNIT_READY)) { + PRINT_ERROR("Expected data direction %d for opcode " + "0x%02x (handler %s, target %s) doesn't match " + "decoded value %d", cmd->expected_data_direction, + cmd->cdb[0], dev->handler->name, + cmd->tgtt->name, cmd->data_direction); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_invalid_message)); + goto out_dev_done; + } } if (unlikely(cmd->bufflen != cmd->expected_transfer_len)) { TRACE(TRACE_MINOR, "Warning: expected transfer length " @@ -547,6 +557,7 @@ PRINT_ERROR("Unknown data direction. Opcode 0x%x, handler %s, " "target %s", cmd->cdb[0], dev->handler->name, cmd->tgtt->name); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); goto out_error; } @@ -1418,7 +1429,8 @@ dev = cmd->dev; - scst_block_dev_cmd(cmd, 1); + if (dev->tst == SCST_CONTR_MODE_ONE_TASK_SET) + scst_block_dev_cmd(cmd, 1); rc = scst_check_local_events(cmd); if (unlikely(rc != 0)) @@ -1473,7 +1485,8 @@ dev = cmd->dev; - scst_block_dev_cmd(cmd, 1); + if (dev->tst == SCST_CONTR_MODE_ONE_TASK_SET) + scst_block_dev_cmd(cmd, 1); rc = scst_check_local_events(cmd); if (unlikely(rc != 0)) @@ -3497,7 +3510,7 @@ TRACE_ENTRY(); TRACE(((mcmd != NULL) && (mcmd->fn == SCST_ABORT_TASK)) ? TRACE_MGMT_MINOR : TRACE_MGMT, - "Aborting cmd %p (tag %llu)", cmd, cmd->tag); + "Aborting cmd %p (tag %llu, op %x)", cmd, cmd->tag, cmd->cdb[0]); if (other_ini) { set_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags); @@ -3890,11 +3903,17 @@ } case SCST_TARGET_RESET: + case SCST_NEXUS_LOSS_SESS: + case SCST_ABORT_ALL_TASKS_SESS: + case SCST_NEXUS_LOSS: case SCST_ABORT_ALL_TASKS: - case SCST_NEXUS_LOSS: + case SCST_UNREG_SESS_TM: break; - default: + case SCST_ABORT_TASK_SET: + case SCST_CLEAR_ACA: + case SCST_CLEAR_TASK_SET: + case SCST_LUN_RESET: rc = scst_mgmt_translate_lun(mcmd); if (rc < 0) { PRINT_ERROR("Corresponding device for lun %Ld not " @@ -3904,6 +3923,9 @@ } else if (rc != 0) res = rc; break; + + default: + sBUG(); } out: @@ -4315,9 +4337,13 @@ if ((mcmd->fn == SCST_UNREG_SESS_TM) && (mcmd->sess->unreg_cmds_done_fn != NULL)) { struct scst_session *sess = mcmd->sess; + TRACE_MGMT_DBG("Calling unreg_cmds_done_fn(%p)", sess); sess->unreg_cmds_done_fn(sess); TRACE_MGMT_DBG("task_mgmt_all_cmds_done(%p) returned", sess); + + /* To prevent scst_mgmt_cmd_send_done() to call it again */ + sess->unreg_cmds_done_fn = NULL; } mcmd->nexus_loss_check_done = 1; @@ -4332,6 +4358,7 @@ { struct scst_device *dev; struct scst_tgt_dev *tgt_dev; + struct scst_session *sess = mcmd->sess; TRACE_ENTRY(); @@ -4342,13 +4369,20 @@ TRACE(TRACE_MGMT_MINOR, "TM command fn %d finished, status %x", mcmd->fn, mcmd->status); - if (mcmd->sess->tgt->tgtt->task_mgmt_fn_done && - (mcmd->fn != SCST_UNREG_SESS_TM)) { - TRACE_DBG("Calling target %s task_mgmt_fn_done()", - mcmd->sess->tgt->tgtt->name); - mcmd->sess->tgt->tgtt->task_mgmt_fn_done(mcmd); - TRACE_MGMT_DBG("Target's %s task_mgmt_fn_done() returned", - mcmd->sess->tgt->tgtt->name); + if (mcmd->fn == SCST_UNREG_SESS_TM) { + if (sess->unreg_cmds_done_fn != NULL) { + TRACE_MGMT_DBG("Calling unreg_cmds_done_fn(%p)", sess); + sess->unreg_cmds_done_fn(sess); + TRACE_MGMT_DBG("task_mgmt_all_cmds_done(%p) returned", sess); + } + } else { + if (sess->tgt->tgtt->task_mgmt_fn_done) { + TRACE_DBG("Calling target %s task_mgmt_fn_done(%p)", + sess->tgt->tgtt->name, sess); + sess->tgt->tgtt->task_mgmt_fn_done(mcmd); + TRACE_MGMT_DBG("Target's %s task_mgmt_fn_done() " + "returned", sess->tgt->tgtt->name); + } } if (mcmd->needs_unblocking) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |