From: <vl...@us...> - 2007-12-21 19:10:45
|
Revision: 237 http://scst.svn.sourceforge.net/scst/?rev=237&view=rev Author: vlnb Date: 2007-12-21 11:10:40 -0800 (Fri, 21 Dec 2007) Log Message: ----------- - Update to the latest IET r145 - TM fixes and improvements, particularly, TARGET RESET now resets only visible to the initiator devices - Logs improvements Modified Paths: -------------- trunk/doc/scst_user_spec.txt trunk/iscsi-scst/include/iscsi_u.h trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/nthread.c trunk/iscsi-scst/usr/iscsid.c trunk/scst/include/scst_user.h trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/doc/scst_user_spec.txt =================================================================== --- trunk/doc/scst_user_spec.txt 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/doc/scst_user_spec.txt 2007-12-21 19:10:40 UTC (rev 237) @@ -2,7 +2,7 @@ USER SPACE INTERFACE DESCRIPTION. - Version 0.9.6/2 + Version 0.9.6/3 I. Description. @@ -335,6 +335,8 @@ uint8_t expected_values_set; uint8_t expected_data_direction; int32_t expected_transfer_len; + + uint32_t sn; }, where: @@ -362,6 +364,8 @@ - expected_transfer_len - remote initiator supplied transfer length + - sn - command's SN, which might be used for task management + In the PARSE state of SCSI commands processing the user space device handler shall check and provide SCST values for command data buffer length, data flow direction and timeout, which it shall reply using the @@ -401,6 +405,8 @@ uint8_t queue_type; uint8_t data_direction; + + uint32_t sn; }, where: @@ -418,6 +424,8 @@ - data_direction - command's data flow direction, one of SCST_DATA_* constants + - sn - command's SN, which might be used for task management + Memory allocation, preparation and freeing are ones of the most complicated and expensive operations during SCSI commands processing. Module scst_user provides a way to almost completely eliminate those @@ -507,6 +515,8 @@ uint8_t partial; uint32_t timeout; + uint32_t sn; + uint32_t parent_cmd_h; int32_t parent_cmd_data_len; uint32_t partial_offset; @@ -546,6 +556,8 @@ - timeout - CDB execution timeout + - sn - command's SN, which might be used for task management + - parent_cmd_h - has the same unique value for all partial data transfers subcommands of one original (parent) command @@ -641,6 +653,8 @@ uint64_t sess_h; uint32_t fn; uint32_t cmd_h_to_abort; + uint32_t cmd_sn; + uint8_t cmd_sn_set; }, where: @@ -651,6 +665,12 @@ - cmd_h_to_abort - handle of command to abort. Valid only if fn is SCST_ABORT_TASK + + - cmd_sn - if cmd_sn_set is set, contains maximum commands SN, which + this task management function affects. See iSCSI RFC 3720 10.5.1 for + more details. + + - cmd_sn_set - specifies if cmd_sn is valid After TM function is completed, the user space device handler shall reply using "result" field of the corresponding reply command. It isn't Modified: trunk/iscsi-scst/include/iscsi_u.h =================================================================== --- trunk/iscsi-scst/include/iscsi_u.h 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/iscsi-scst/include/iscsi_u.h 2007-12-21 19:10:40 UTC (rev 237) @@ -20,7 +20,7 @@ #include <sys/uio.h> #endif -#define ISCSI_VERSION_STRING "0.9.6/0.4.15r137" +#define ISCSI_VERSION_STRING "0.9.6/0.4.15r145" /* The maximum length of 223 bytes in the RFC. */ #define ISCSI_NAME_LEN 256 Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/iscsi-scst/kernel/iscsi.c 2007-12-21 19:10:40 UTC (rev 237) @@ -62,7 +62,7 @@ static void cmnd_remove_hash(struct iscsi_cmnd *cmnd); static void iscsi_send_task_mgmt_resp(struct iscsi_cmnd *req, int status); static void cmnd_prepare_skip_pdu(struct iscsi_cmnd *cmnd); -static void iscsi_cond_send_tm_resp(struct iscsi_cmnd *rsp, int force); +static void iscsi_check_send_delayed_tm_resp(struct iscsi_session *sess); static inline u32 cmnd_write_size(struct iscsi_cmnd *cmnd) { @@ -780,8 +780,10 @@ if (!tmp) { list_add_tail(&cmnd->hash_list_entry, head); cmnd->hashed = 1; - } else + } else { + PRINT_ERROR("Task %x in progress, cmnd %p", itt, cmnd); err = -ISCSI_REASON_TASK_IN_PROGRESS; + } spin_unlock(&session->cmnd_hash_lock); @@ -965,6 +967,13 @@ u32 length, offset, burst; LIST_HEAD(send); + if (unlikely(req->tmfabort)) { + TRACE_MGMT_DBG("req %p (scst_cmd %p) aborted on R2T", req, + req->scst_cmd); + req_cmnd_release_force(req, ISCSI_FORCE_RELEASE_WRITE); + goto out; + } + /* * There is no race with data_out_start() and __cmnd_abort(), since * all functions called from single read thread @@ -1009,6 +1018,9 @@ iscsi_cmnds_init_write(&send, ISCSI_INIT_WRITE_WAKE); req->data_waiting = 1; + +out: + return; } static int iscsi_pre_exec(struct scst_cmd *scst_cmd) @@ -1333,7 +1345,8 @@ cmnd->cmd_req = req = cmnd_find_hash(conn->session, req_hdr->itt, req_hdr->ttt); if (!req) { - PRINT_ERROR("Unable to find scsi task %x %x", + /* It might happen if req was aborted and then freed */ + TRACE(TRACE_MGMT_MINOR, "Unable to find scsi task %x %x", cmnd_itt(cmnd), cmnd_ttt(cmnd)); goto skip_pdu; } @@ -1447,12 +1460,12 @@ goto out; TRACE_MGMT_DBG("Aborting cmd %p, scst_cmd %p (scst state %x, " - "ref_cnt %d, itt %x, op %x, r2t_len %x, CDB op %x, " + "ref_cnt %d, itt %x, sn %d, op %x, r2t_len %x, CDB op %x, " "size to write %u, is_unsolicited_data %u, " "outstanding_r2t %u)", cmnd, cmnd->scst_cmd, cmnd->scst_state, atomic_read(&cmnd->ref_cnt), - cmnd_itt(cmnd), cmnd_opcode(cmnd), cmnd->r2t_length, - cmnd_scsicode(cmnd), cmnd_write_size(cmnd), + cmnd_itt(cmnd), cmnd->pdu.bhs.sn, cmnd_opcode(cmnd), + cmnd->r2t_length, cmnd_scsicode(cmnd), cmnd_write_size(cmnd), cmnd->is_unsolicited_data, cmnd->outstanding_r2t); #ifdef NET_PAGE_CALLBACKS_DEFINED @@ -1615,26 +1628,32 @@ static void execute_task_management(struct iscsi_cmnd *req) { struct iscsi_conn *conn = req->conn; + 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; struct scst_rx_mgmt_params params; TRACE((function == ISCSI_FUNCTION_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, - "TM cmd: req %p, itt %x, fn %d, rtt %x", req, cmnd_itt(req), - function, req_hdr->rtt); + "TM cmd: req %p, itt %x, fn %d, rtt %x, sn %d", req, cmnd_itt(req), + function, req_hdr->rtt, req_hdr->cmd_sn); + spin_lock(&sess->sn_lock); + sess->tm_active = 1; + 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; + spin_unlock(&sess->sn_lock); + rsp_cmnd_release(tm_rsp); + } else + spin_unlock(&sess->sn_lock); + memset(¶ms, 0, sizeof(params)); params.atomic = SCST_NON_ATOMIC; params.tgt_priv = req; - if (conn->session->tm_rsp != NULL) { - struct iscsi_task_rsp_hdr *rsp_hdr = - (struct iscsi_task_rsp_hdr *)&conn->session->tm_rsp->pdu.bhs; - rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_REJECTED; - iscsi_cond_send_tm_resp(conn->session->tm_rsp, 1); - } - if ((function != ISCSI_FUNCTION_ABORT_TASK) && (req_hdr->rtt != ISCSI_RESERVED_TAG)) { PRINT_ERROR("Invalid RTT %x (TM fn %x)", req_hdr->rtt, @@ -1697,6 +1716,8 @@ case ISCSI_FUNCTION_TARGET_WARM_RESET: target_abort(req, 1); 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, ¶ms); break; @@ -1706,6 +1727,8 @@ params.lun = (uint8_t *)&req_hdr->lun; params.lun_len = sizeof(req_hdr->lun); 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, ¶ms); break; @@ -1985,16 +2008,23 @@ while (1) { session->exp_cmd_sn = ++cmd_sn; - spin_unlock(&session->sn_lock); + if (unlikely(session->tm_active)) { + if (before(cmd_sn, session->tm_sn)) { + struct iscsi_conn *conn = cmnd->conn; - if (unlikely(session->tm_rsp != NULL)) { - struct iscsi_conn *conn = cmnd->conn; - spin_lock_bh(&conn->cmd_list_lock); - __cmnd_abort(cmnd); - spin_unlock_bh(&conn->cmd_list_lock); - iscsi_cond_send_tm_resp(session->tm_rsp, 0); + spin_unlock(&session->sn_lock); + + spin_lock_bh(&conn->cmd_list_lock); + __cmnd_abort(cmnd); + spin_unlock_bh(&conn->cmd_list_lock); + + spin_lock(&session->sn_lock); + } + iscsi_check_send_delayed_tm_resp(session); } + spin_unlock(&session->sn_lock); + iscsi_cmnd_exec(cmnd); if (list_empty(&session->pending_list)) @@ -2010,13 +2040,13 @@ } } else { cmnd->pending = 1; - if (before(cmd_sn, session->exp_cmd_sn)) { /* close the conn */ + if (before(cmd_sn, session->exp_cmd_sn)) { PRINT_ERROR("unexpected cmd_sn (%u,%u)", cmd_sn, session->exp_cmd_sn); } if (after(cmd_sn, session->exp_cmd_sn + iscsi_get_allowed_cmds(session))) { - PRINT_ERROR("too large cmd_sn %u (exp_cmd_sn %u, " + PRINT_INFO("Suspicious: too large cmd_sn %u (exp_cmd_sn %u, " "max_sn %u)", cmd_sn, session->exp_cmd_sn, iscsi_get_allowed_cmds(session)); } @@ -2360,45 +2390,53 @@ return SCST_TGT_RES_SUCCESS; } -static void iscsi_cond_send_tm_resp(struct iscsi_cmnd *rsp, int force) +/* Called under sn_lock */ +static bool iscsi_is_delay_tm_resp(struct iscsi_cmnd *rsp) { + bool res = 0; struct iscsi_task_mgt_hdr *req_hdr = - (struct iscsi_task_mgt_hdr *)&rsp->parent_req->pdu.bhs; + (struct iscsi_task_mgt_hdr *)&rsp->parent_req->pdu.bhs; int function = req_hdr->function & ISCSI_FUNCTION_MASK; struct iscsi_session *sess = rsp->conn->session; TRACE_ENTRY(); - if (!force) { - spin_lock(&sess->sn_lock); - switch(function) { - case ISCSI_FUNCTION_ABORT_TASK_SET: - case ISCSI_FUNCTION_CLEAR_TASK_SET: - case ISCSI_FUNCTION_CLEAR_ACA: - if (before(sess->exp_cmd_sn, req_hdr->cmd_sn)) { - TRACE_MGMT_DBG("Delaying TM fn %x response, " - "because not all affected commands " - "received (rsp %p, cmd sn %x, exp sn " - "%x)", function, rsp, req_hdr->cmd_sn, - sess->exp_cmd_sn); - sess->tm_rsp = rsp; - spin_unlock(&sess->sn_lock); - goto out; - } - break; - default: - break; - } - spin_unlock(&sess->sn_lock); + switch(function) { + default: + if (before(sess->exp_cmd_sn, req_hdr->cmd_sn)) + res = 1; + break; } - if (rsp == sess->tm_rsp) { - TRACE_MGMT_DBG("Sending delayed rsp %p (fn %x)", rsp, function); - sess->tm_rsp = NULL; - } - iscsi_cmnd_init_write(rsp, + TRACE_EXIT_RES(res); + return res; +} + +/* Called under sn_lock, but might drop it inside, then reaquire */ +static void iscsi_check_send_delayed_tm_resp(struct iscsi_session *sess) +{ + struct iscsi_cmnd *tm_rsp = sess->tm_rsp; + + TRACE_ENTRY(); + + if (tm_rsp == NULL) + goto out; + + if (iscsi_is_delay_tm_resp(tm_rsp)) + goto out; + + TRACE(TRACE_MGMT_MINOR, "Sending delayed rsp %p", tm_rsp); + + sess->tm_rsp = NULL; + sess->tm_active = 0; + + spin_unlock(&sess->sn_lock); + + iscsi_cmnd_init_write(tm_rsp, ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); + spin_lock(&sess->sn_lock); + out: TRACE_EXIT(); return; @@ -2410,6 +2448,7 @@ struct iscsi_task_mgt_hdr *req_hdr = (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; struct iscsi_task_rsp_hdr *rsp_hdr; + struct iscsi_session *sess = req->conn->session; TRACE_ENTRY(); @@ -2429,8 +2468,26 @@ ISCSI_FUNCTION_TARGET_COLD_RESET) rsp->should_close_conn = 1; - iscsi_cond_send_tm_resp(rsp, 0); + sBUG_ON(sess->tm_rsp != NULL); + spin_lock(&sess->sn_lock); + if (iscsi_is_delay_tm_resp(rsp)) { + TRACE(TRACE_MGMT_MINOR, "Delaying TM fn %x response %p " + "(req %p), because not all affected commands received " + "(cmd sn %d, exp sn %d)", + req_hdr->function & ISCSI_FUNCTION_MASK, rsp, req, + req_hdr->cmd_sn, sess->exp_cmd_sn); + sess->tm_rsp = rsp; + spin_unlock(&sess->sn_lock); + goto out_release; + } + sess->tm_active = 0; + spin_unlock(&sess->sn_lock); + + iscsi_cmnd_init_write(rsp, + ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); + +out_release: req_cmnd_release(req); TRACE_EXIT(); Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/iscsi-scst/kernel/iscsi.h 2007-12-21 19:10:40 UTC (rev 237) @@ -88,7 +88,7 @@ struct iscsi_target *target; struct scst_session *scst_sess; - /* All 2 unprotected, since accessed only from a single read thread */ + /* Both unprotected, since accessed only from a single read thread */ struct list_head pending_list; u32 next_ttt; @@ -98,6 +98,9 @@ spinlock_t sn_lock; u32 exp_cmd_sn; /* protected by sn_lock */ + /* All 3 protected by sn_lock */ + unsigned int tm_active:1; + u32 tm_sn; struct iscsi_cmnd *tm_rsp; /* read only, if there are connection(s) */ Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/iscsi-scst/kernel/nthread.c 2007-12-21 19:10:40 UTC (rev 237) @@ -136,6 +136,22 @@ conn_abort(conn); + mutex_lock(&target->target_mutex); + spin_lock(&session->sn_lock); + if ((session->tm_rsp != NULL) && (session->tm_rsp->conn == conn)) { + struct iscsi_cmnd *tm_rsp = session->tm_rsp; + TRACE(TRACE_MGMT_MINOR, "Dropping delayed TM rsp %p", tm_rsp); + session->tm_rsp = NULL; + session->tm_active = 0; + spin_unlock(&session->sn_lock); + mutex_unlock(&target->target_mutex); + + rsp_cmnd_release(tm_rsp); + } else { + spin_unlock(&session->sn_lock); + mutex_unlock(&target->target_mutex); + } + if (conn->read_state != RX_INIT_BHS) { req_cmnd_release_force(conn->read_cmnd, 0); conn->read_cmnd = NULL; @@ -181,10 +197,12 @@ spin_lock_bh(&conn->cmd_list_lock); list_for_each_entry(cmnd, &conn->cmd_list, cmd_list_entry) { - TRACE_CONN_CLOSE_DBG("cmd %p, scst_state %x, data_waiting " - "%d, ref_cnt %d, parent_req %p", cmnd, - cmnd->scst_state, cmnd->data_waiting, - atomic_read(&cmnd->ref_cnt), cmnd->parent_req); + TRACE_CONN_CLOSE_DBG("cmd %p, scst_state %x, scst_cmd " + "state %d, data_waiting %d, ref_cnt %d, " + "parent_req %p", cmnd, cmnd->scst_state, + (cmnd->scst_cmd != NULL) ? cmnd->scst_cmd->state : -1, + cmnd->data_waiting, atomic_read(&cmnd->ref_cnt), + cmnd->parent_req); #ifdef NET_PAGE_CALLBACKS_DEFINED TRACE_CONN_CLOSE_DBG("net_ref_cnt %d, sg %p", atomic_read(&cmnd->net_ref_cnt), cmnd->sg); @@ -568,6 +586,8 @@ { TRACE_ENTRY(); + PRINT_INFO("Read thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; spin_lock_bh(&iscsi_rd_lock); @@ -598,6 +618,8 @@ */ sBUG_ON(!list_empty(&iscsi_rd_list)); + PRINT_INFO("Read thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } @@ -1072,6 +1094,8 @@ { TRACE_ENTRY(); + PRINT_INFO("Write thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; spin_lock_bh(&iscsi_wr_lock); @@ -1102,6 +1126,8 @@ */ sBUG_ON(!list_empty(&iscsi_wr_list)); + PRINT_INFO("Write thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } Modified: trunk/iscsi-scst/usr/iscsid.c =================================================================== --- trunk/iscsi-scst/usr/iscsid.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/iscsi-scst/usr/iscsid.c 2007-12-21 19:10:40 UTC (rev 237) @@ -108,7 +108,7 @@ } conn->rsp.data = conn->rsp_buffer; } - if (conn->rwsize + len > INCOMING_BUFSIZE) { + if (conn->rsp.datasize + len > INCOMING_BUFSIZE) { log_warning("Dropping key (%s=%s)", key, value); return; } Modified: trunk/scst/include/scst_user.h =================================================================== --- trunk/scst/include/scst_user.h 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/scst/include/scst_user.h 2007-12-21 19:10:40 UTC (rev 237) @@ -23,9 +23,9 @@ #include <scst_const.h> -#define DEV_USER_NAME "scst_user" +#define DEV_USER_NAME "scst_user" #define DEV_USER_PATH "/dev/" -#define DEV_USER_VERSION 962 +#define DEV_USER_VERSION 963 /* * Chosen so sizeof(scst_user_sess) <= sizeof(scst_user_scsi_cmd_exec) @@ -137,6 +137,8 @@ uint8_t expected_values_set; uint8_t expected_data_direction; int32_t expected_transfer_len; + + uint32_t sn; }; struct scst_user_scsi_cmd_alloc_mem @@ -150,6 +152,8 @@ uint8_t queue_type; uint8_t data_direction; + + uint32_t sn; }; struct scst_user_scsi_cmd_exec @@ -168,6 +172,8 @@ uint8_t partial; uint32_t timeout; + uint32_t sn; + uint32_t parent_cmd_h; int32_t parent_cmd_data_len; uint32_t partial_offset; @@ -193,6 +199,8 @@ aligned_u64 sess_h; uint32_t fn; uint32_t cmd_h_to_abort; + uint32_t cmd_sn; + uint8_t cmd_sn_set; }; struct scst_user_get_cmd Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/scst/src/dev_handlers/scst_user.c 2007-12-21 19:10:40 UTC (rev 237) @@ -596,6 +596,7 @@ (cmd->sg_cnt << PAGE_SHIFT) : cmd->bufflen; ucmd->user_cmd.alloc_cmd.queue_type = cmd->queue_type; ucmd->user_cmd.alloc_cmd.data_direction = cmd->data_direction; + ucmd->user_cmd.alloc_cmd.sn = cmd->tgt_sn; dev_user_add_to_ready(ucmd); @@ -722,6 +723,7 @@ cmd->expected_data_direction; ucmd->user_cmd.parse_cmd.expected_transfer_len = cmd->expected_transfer_len; + ucmd->user_cmd.parse_cmd.sn = cmd->tgt_sn; ucmd->state = UCMD_STATE_PARSING; dev_user_add_to_ready(ucmd); res = SCST_CMD_STATE_STOP; @@ -809,6 +811,7 @@ ucmd->user_cmd.exec_cmd.data_direction = cmd->data_direction; ucmd->user_cmd.exec_cmd.partial = 0; ucmd->user_cmd.exec_cmd.timeout = cmd->timeout; + ucmd->user_cmd.exec_cmd.sn = cmd->tgt_sn; ucmd->state = UCMD_STATE_EXECING; @@ -2126,6 +2129,8 @@ ucmd->user_cmd.subcode = SCST_USER_TASK_MGMT; ucmd->user_cmd.tm_cmd.sess_h = (unsigned long)tgt_dev; ucmd->user_cmd.tm_cmd.fn = mcmd->fn; + ucmd->user_cmd.tm_cmd.cmd_sn = mcmd->cmd_sn; + ucmd->user_cmd.tm_cmd.cmd_sn_set = mcmd->cmd_sn_set; if (mcmd->cmd_to_abort != NULL) { ucmd_to_abort = (struct scst_user_cmd*)mcmd->cmd_to_abort->dh_priv; @@ -2990,6 +2995,8 @@ TRACE_ENTRY(); + PRINT_INFO("Cleanup thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; spin_lock(&cleanup_lock); @@ -3027,6 +3034,8 @@ */ sBUG_ON(!list_empty(&cleanup_list)); + PRINT_INFO("Cleanup thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/scst/src/scst_lib.c 2007-12-21 19:10:40 UTC (rev 237) @@ -3322,13 +3322,17 @@ } /* No locks */ -void tm_dbg_task_mgmt(const char *fn, int force) +void tm_dbg_task_mgmt(struct scst_tgt_dev *tgt_dev, const char *fn, int force) { unsigned long flags; if (!tm_dbg_flags.tm_dbg_active) goto out; + if ((tgt_dev != NULL) && !test_bit(SCST_TGT_DEV_UNDER_TM_DBG, + &tgt_dev->tgt_dev_flags)) + goto out; + spin_lock_irqsave(&scst_tm_dbg_lock, flags); if ((tm_dbg_state != TM_DBG_STATE_OFFLINE) || force) { TRACE_MGMT_DBG("%s: freeing %d delayed cmds", fn, Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/scst/src/scst_priv.h 2007-12-21 19:10:40 UTC (rev 237) @@ -512,7 +512,8 @@ extern void tm_dbg_check_released_cmds(void); extern int tm_dbg_check_cmd(struct scst_cmd *cmd); extern void tm_dbg_release_cmd(struct scst_cmd *cmd); -extern void tm_dbg_task_mgmt(const char *fn, int force); +extern void tm_dbg_task_mgmt(struct scst_tgt_dev *tgt_dev, const char *fn, + int force); extern int tm_dbg_is_release(void); #else static inline void tm_dbg_init_tgt_dev(struct scst_tgt_dev *tgt_dev, @@ -524,7 +525,8 @@ return 0; } static inline void tm_dbg_release_cmd(struct scst_cmd *cmd) {} -static inline void tm_dbg_task_mgmt(const char *fn, int force) {} +static inline void tm_dbg_task_mgmt(struct scst_tgt_dev *tgt_dev, const char *fn, + int force) {} static inline int tm_dbg_is_release(void) { return 0; Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/scst/src/scst_targ.c 2007-12-21 19:10:40 UTC (rev 237) @@ -448,6 +448,14 @@ if (unlikely(state == SCST_CMD_STATE_PRE_XMIT_RESP)) goto set_res; + if (unlikely((cmd->bufflen == 0) && + (cmd->op_flags & SCST_UNKNOWN_LENGTH))) { + PRINT_ERROR("Unknown data transfer length for opcode 0x%x " + "(handler %s, target %s)", cmd->cdb[0], + dev->handler->name, cmd->tgtt->name); + goto out_error; + } + #ifdef EXTRACHECKS if ((cmd->bufflen != 0) && ((cmd->data_direction == SCST_DATA_NONE) || @@ -2854,6 +2862,8 @@ { TRACE_ENTRY(); + PRINT_INFO("Init thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; set_user_nice(current, -20); @@ -2887,6 +2897,8 @@ */ sBUG_ON(!list_empty(&scst_init_cmd_list)); + PRINT_INFO("Init thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } @@ -3053,6 +3065,8 @@ TRACE_ENTRY(); + PRINT_INFO("Processing thread started, PID %d", current->pid); + #if 0 set_user_nice(current, 10); #endif @@ -3101,6 +3115,8 @@ } #endif + PRINT_INFO("Processing thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } @@ -3659,8 +3675,9 @@ static int scst_target_reset(struct scst_mgmt_cmd *mcmd) { int res, rc; - struct scst_device *dev, *d; - struct scst_tgt_dev *tgt_dev; + struct scst_device *dev; + struct scst_acg *acg = mcmd->sess->acg; + struct scst_acg_dev *acg_dev; int cont, c; LIST_HEAD(host_devs); @@ -3673,20 +3690,12 @@ mutex_lock(&scst_mutex); - list_for_each_entry(dev, &scst_dev_list, dev_list_entry) { + list_for_each_entry(acg_dev, &acg->acg_dev_list, acg_dev_list_entry) { + struct scst_device *d; + struct scst_tgt_dev *tgt_dev; int found = 0; - /* Skip local SCSI devices */ - if (dev->handler == &scst_null_devtype) { - /* - * Generally we shouldn't reset not exported devices, - * but what if a backstorage SCSI disk hung? Let's - * reset it too. - */ - if ((dev->scsi_dev != NULL) && - (dev->scsi_dev->type != TYPE_DISK)) - continue; - } + dev = acg_dev->dev; spin_lock_bh(&dev->dev_lock); __scst_block_dev(dev); @@ -3744,14 +3753,15 @@ #endif } - list_for_each_entry(dev, &scst_dev_list, dev_list_entry) { + list_for_each_entry(acg_dev, &acg->acg_dev_list, acg_dev_list_entry) { + dev = acg_dev->dev; if (dev->scsi_dev != NULL) dev->scsi_dev->was_reset = 0; } mutex_unlock(&scst_mutex); - tm_dbg_task_mgmt("TARGET RESET", 0); + tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev, "TARGET RESET", 0); res = scst_set_mcmd_next_state(mcmd); TRACE_EXIT_RES(res); @@ -3792,7 +3802,7 @@ } out_tm_dbg: - tm_dbg_task_mgmt("LUN RESET", 0); + tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev, "LUN RESET", 0); res = scst_set_mcmd_next_state(mcmd); TRACE_EXIT_RES(res); @@ -3857,9 +3867,9 @@ int res; int i; struct scst_tgt *tgt = mcmd->sess->tgt; + struct scst_acg *acg = mcmd->sess->acg; struct scst_session *sess; - struct scst_device *dev; - struct scst_tgt_dev *tgt_dev; + struct scst_acg_dev *acg_dev; TRACE_ENTRY(); @@ -3875,7 +3885,9 @@ mutex_lock(&scst_mutex); - list_for_each_entry(dev, &scst_dev_list, dev_list_entry) { + list_for_each_entry(acg_dev, &acg->acg_dev_list, acg_dev_list_entry) { + struct scst_device *dev = acg_dev->dev; + spin_lock_bh(&dev->dev_lock); __scst_block_dev(dev); spin_unlock_bh(&dev->dev_lock); @@ -3885,6 +3897,7 @@ for(i = 0; i < TGT_DEV_HASH_SIZE; i++) { struct list_head *sess_tgt_dev_list_head = &sess->sess_tgt_dev_list_hash[i]; + struct scst_tgt_dev *tgt_dev; list_for_each_entry(tgt_dev, sess_tgt_dev_list_head, sess_tgt_dev_list_entry) { int rc; @@ -4020,12 +4033,19 @@ case SCST_TARGET_RESET: case SCST_ABORT_ALL_TASKS: case SCST_NEXUS_LOSS: + { + struct scst_acg *acg = mcmd->sess->acg; + struct scst_acg_dev *acg_dev; + mutex_lock(&scst_mutex); - list_for_each_entry(dev, &scst_dev_list, dev_list_entry) { + list_for_each_entry(acg_dev, &acg->acg_dev_list, + acg_dev_list_entry) { + dev = acg_dev->dev; scst_unblock_dev(dev); } mutex_unlock(&scst_mutex); break; + } case SCST_NEXUS_LOSS_SESS: case SCST_ABORT_ALL_TASKS_SESS: @@ -4115,6 +4135,8 @@ { TRACE_ENTRY(); + PRINT_INFO("Task management thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; set_user_nice(current, -20); @@ -4174,6 +4196,8 @@ */ sBUG_ON(!list_empty(&scst_active_mgmt_cmd_list)); + PRINT_INFO("Task management thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } @@ -4311,7 +4335,7 @@ TRACE((params->fn == SCST_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, "sess=%p, fn %x, tag_set %d, tag %Ld, lun_set %d, " - "lun=%Ld, cmd_sn_set %d, cmd_sn %x", sess, params->fn, + "lun=%Ld, cmd_sn_set %d, cmd_sn %d", sess, params->fn, params->tag_set, params->tag, params->lun_set, (uint64_t)mcmd->lun, params->cmd_sn_set, params->cmd_sn); @@ -4551,7 +4575,7 @@ spin_unlock_irqrestore(&scst_mgmt_lock, flags); - tm_dbg_task_mgmt("UNREGISTER SESSION", 1); + tm_dbg_task_mgmt(NULL, "UNREGISTER SESSION", 1); scst_sess_put(sess); @@ -4619,6 +4643,8 @@ TRACE_ENTRY(); + PRINT_INFO("Management thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; set_user_nice(current, -20); @@ -4700,6 +4726,8 @@ sBUG_ON(!list_empty(&scst_sess_init_list)); sBUG_ON(!list_empty(&scst_sess_shut_list)); + PRINT_INFO("Management thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |