void iscsi_post_login_handler()

in iscsi/iscsi_target_login.c [674:799]


void iscsi_post_login_handler(
	struct iscsi_np *np,
	struct iscsi_conn *conn,
	u8 zero_tsih)
{
	int stop_timer = 0;
	struct iscsi_session *sess = conn->sess;
	struct se_session *se_sess = sess->se_sess;
	struct iscsi_portal_group *tpg = sess->tpg;
	struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;

	iscsit_inc_conn_usage_count(conn);

	iscsit_collect_login_stats(conn, ISCSI_STATUS_CLS_SUCCESS,
			ISCSI_LOGIN_STATUS_ACCEPT);

	pr_debug("Moving to TARG_CONN_STATE_LOGGED_IN.\n");
	conn->conn_state = TARG_CONN_STATE_LOGGED_IN;

	iscsi_set_connection_parameters(conn->conn_ops, conn->param_list);
	/*
	 * SCSI Initiator -> SCSI Target Port Mapping
	 */
	if (!zero_tsih) {
		iscsi_set_session_parameters(sess->sess_ops,
				conn->param_list, 0);
		iscsi_release_param_list(conn->param_list);
		conn->param_list = NULL;

		spin_lock_bh(&sess->conn_lock);
		atomic_set(&sess->session_continuation, 0);
		if (sess->session_state == TARG_SESS_STATE_FAILED) {
			pr_debug("Moving to"
					" TARG_SESS_STATE_LOGGED_IN.\n");
			sess->session_state = TARG_SESS_STATE_LOGGED_IN;
			stop_timer = 1;
		}

		pr_debug("iSCSI Login successful on CID: %hu from %pISpc to"
			" %pISpc,%hu\n", conn->cid, &conn->login_sockaddr,
			&conn->local_sockaddr, tpg->tpgt);

		list_add_tail(&conn->conn_list, &sess->sess_conn_list);
		atomic_inc(&sess->nconn);
		pr_debug("Incremented iSCSI Connection count to %hu"
			" from node: %s\n", atomic_read(&sess->nconn),
			sess->sess_ops->InitiatorName);
		spin_unlock_bh(&sess->conn_lock);

		iscsi_post_login_start_timers(conn);
		/*
		 * Determine CPU mask to ensure connection's RX and TX kthreads
		 * are scheduled on the same CPU.
		 */
		iscsit_thread_get_cpumask(conn);
		conn->conn_rx_reset_cpumask = 1;
		conn->conn_tx_reset_cpumask = 1;
		/*
		 * Wakeup the sleeping iscsi_target_rx_thread() now that
		 * iscsi_conn is in TARG_CONN_STATE_LOGGED_IN state.
		 */
		complete(&conn->rx_login_comp);
		iscsit_dec_conn_usage_count(conn);

		if (stop_timer) {
			spin_lock_bh(&se_tpg->session_lock);
			iscsit_stop_time2retain_timer(sess);
			spin_unlock_bh(&se_tpg->session_lock);
		}
		iscsit_dec_session_usage_count(sess);
		return;
	}

	iscsi_set_session_parameters(sess->sess_ops, conn->param_list, 1);
	iscsi_release_param_list(conn->param_list);
	conn->param_list = NULL;

	iscsit_determine_maxcmdsn(sess);

	spin_lock_bh(&se_tpg->session_lock);
	__transport_register_session(&sess->tpg->tpg_se_tpg,
			se_sess->se_node_acl, se_sess, sess);
	pr_debug("Moving to TARG_SESS_STATE_LOGGED_IN.\n");
	sess->session_state = TARG_SESS_STATE_LOGGED_IN;

	pr_debug("iSCSI Login successful on CID: %hu from %pISpc to %pISpc,%hu\n",
		conn->cid, &conn->login_sockaddr, &conn->local_sockaddr,
		tpg->tpgt);

	spin_lock_bh(&sess->conn_lock);
	list_add_tail(&conn->conn_list, &sess->sess_conn_list);
	atomic_inc(&sess->nconn);
	pr_debug("Incremented iSCSI Connection count to %hu from node:"
		" %s\n", atomic_read(&sess->nconn),
		sess->sess_ops->InitiatorName);
	spin_unlock_bh(&sess->conn_lock);

	sess->sid = tpg->sid++;
	if (!sess->sid)
		sess->sid = tpg->sid++;
	pr_debug("Established iSCSI session from node: %s\n",
			sess->sess_ops->InitiatorName);

	tpg->nsessions++;
	if (tpg->tpg_tiqn)
		tpg->tpg_tiqn->tiqn_nsessions++;

	pr_debug("Incremented number of active iSCSI sessions to %u on"
		" iSCSI Target Portal Group: %hu\n", tpg->nsessions, tpg->tpgt);
	spin_unlock_bh(&se_tpg->session_lock);

	iscsi_post_login_start_timers(conn);
	/*
	 * Determine CPU mask to ensure connection's RX and TX kthreads
	 * are scheduled on the same CPU.
	 */
	iscsit_thread_get_cpumask(conn);
	conn->conn_rx_reset_cpumask = 1;
	conn->conn_tx_reset_cpumask = 1;
	/*
	 * Wakeup the sleeping iscsi_target_rx_thread() now that
	 * iscsi_conn is in TARG_CONN_STATE_LOGGED_IN state.
	 */
	complete(&conn->rx_login_comp);
	iscsit_dec_conn_usage_count(conn);
}