]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/target/iscsi/iscsi_target_login.c
iscsit: use the itt_t abstract type
[mirror_ubuntu-zesty-kernel.git] / drivers / target / iscsi / iscsi_target_login.c
CommitLineData
e48354ce
NB
1/*******************************************************************************
2 * This file contains the login functions used by the iSCSI Target driver.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 ******************************************************************************/
20
21#include <linux/string.h>
22#include <linux/kthread.h>
23#include <linux/crypto.h>
40401530 24#include <linux/idr.h>
e48354ce
NB
25#include <scsi/iscsi_proto.h>
26#include <target/target_core_base.h>
c4795fb2 27#include <target/target_core_fabric.h>
e48354ce
NB
28
29#include "iscsi_target_core.h"
30#include "iscsi_target_tq.h"
31#include "iscsi_target_device.h"
32#include "iscsi_target_nego.h"
33#include "iscsi_target_erl0.h"
34#include "iscsi_target_erl2.h"
35#include "iscsi_target_login.h"
36#include "iscsi_target_stat.h"
37#include "iscsi_target_tpg.h"
38#include "iscsi_target_util.h"
39#include "iscsi_target.h"
40#include "iscsi_target_parameters.h"
41
e48354ce
NB
42static int iscsi_login_init_conn(struct iscsi_conn *conn)
43{
44 INIT_LIST_HEAD(&conn->conn_list);
45 INIT_LIST_HEAD(&conn->conn_cmd_list);
46 INIT_LIST_HEAD(&conn->immed_queue_list);
47 INIT_LIST_HEAD(&conn->response_queue_list);
48 init_completion(&conn->conn_post_wait_comp);
49 init_completion(&conn->conn_wait_comp);
50 init_completion(&conn->conn_wait_rcfr_comp);
51 init_completion(&conn->conn_waiting_on_uc_comp);
52 init_completion(&conn->conn_logout_comp);
53 init_completion(&conn->rx_half_close_comp);
54 init_completion(&conn->tx_half_close_comp);
55 spin_lock_init(&conn->cmd_lock);
56 spin_lock_init(&conn->conn_usage_lock);
57 spin_lock_init(&conn->immed_queue_lock);
58 spin_lock_init(&conn->nopin_timer_lock);
59 spin_lock_init(&conn->response_queue_lock);
60 spin_lock_init(&conn->state_lock);
61
62 if (!zalloc_cpumask_var(&conn->conn_cpumask, GFP_KERNEL)) {
63 pr_err("Unable to allocate conn->conn_cpumask\n");
64 return -ENOMEM;
65 }
66
67 return 0;
68}
69
70/*
71 * Used by iscsi_target_nego.c:iscsi_target_locate_portal() to setup
72 * per struct iscsi_conn libcrypto contexts for crc32c and crc32-intel
73 */
74int iscsi_login_setup_crypto(struct iscsi_conn *conn)
75{
76 /*
77 * Setup slicing by CRC32C algorithm for RX and TX libcrypto contexts
78 * which will default to crc32c_intel.ko for cpu_has_xmm4_2, or fallback
79 * to software 1x8 byte slicing from crc32c.ko
80 */
81 conn->conn_rx_hash.flags = 0;
82 conn->conn_rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
83 CRYPTO_ALG_ASYNC);
84 if (IS_ERR(conn->conn_rx_hash.tfm)) {
85 pr_err("crypto_alloc_hash() failed for conn_rx_tfm\n");
86 return -ENOMEM;
87 }
88
89 conn->conn_tx_hash.flags = 0;
90 conn->conn_tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
91 CRYPTO_ALG_ASYNC);
92 if (IS_ERR(conn->conn_tx_hash.tfm)) {
93 pr_err("crypto_alloc_hash() failed for conn_tx_tfm\n");
94 crypto_free_hash(conn->conn_rx_hash.tfm);
95 return -ENOMEM;
96 }
97
98 return 0;
99}
100
101static int iscsi_login_check_initiator_version(
102 struct iscsi_conn *conn,
103 u8 version_max,
104 u8 version_min)
105{
106 if ((version_max != 0x00) || (version_min != 0x00)) {
107 pr_err("Unsupported iSCSI IETF Pre-RFC Revision,"
108 " version Min/Max 0x%02x/0x%02x, rejecting login.\n",
109 version_min, version_max);
110 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
111 ISCSI_LOGIN_STATUS_NO_VERSION);
112 return -1;
113 }
114
115 return 0;
116}
117
118int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn)
119{
120 int sessiontype;
121 struct iscsi_param *initiatorname_param = NULL, *sessiontype_param = NULL;
122 struct iscsi_portal_group *tpg = conn->tpg;
123 struct iscsi_session *sess = NULL, *sess_p = NULL;
124 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
125 struct se_session *se_sess, *se_sess_tmp;
126
127 initiatorname_param = iscsi_find_param_from_key(
128 INITIATORNAME, conn->param_list);
129 if (!initiatorname_param)
130 return -1;
131
132 sessiontype_param = iscsi_find_param_from_key(
133 SESSIONTYPE, conn->param_list);
134 if (!sessiontype_param)
135 return -1;
136
137 sessiontype = (strncmp(sessiontype_param->value, NORMAL, 6)) ? 1 : 0;
138
139 spin_lock_bh(&se_tpg->session_lock);
140 list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list,
141 sess_list) {
142
8359cf43 143 sess_p = se_sess->fabric_sess_ptr;
e48354ce
NB
144 spin_lock(&sess_p->conn_lock);
145 if (atomic_read(&sess_p->session_fall_back_to_erl0) ||
146 atomic_read(&sess_p->session_logout) ||
147 (sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
148 spin_unlock(&sess_p->conn_lock);
149 continue;
150 }
8359cf43
JE
151 if (!memcmp(sess_p->isid, conn->sess->isid, 6) &&
152 (!strcmp(sess_p->sess_ops->InitiatorName,
153 initiatorname_param->value) &&
e48354ce
NB
154 (sess_p->sess_ops->SessionType == sessiontype))) {
155 atomic_set(&sess_p->session_reinstatement, 1);
156 spin_unlock(&sess_p->conn_lock);
157 iscsit_inc_session_usage_count(sess_p);
158 iscsit_stop_time2retain_timer(sess_p);
159 sess = sess_p;
160 break;
161 }
162 spin_unlock(&sess_p->conn_lock);
163 }
164 spin_unlock_bh(&se_tpg->session_lock);
165 /*
166 * If the Time2Retain handler has expired, the session is already gone.
167 */
168 if (!sess)
169 return 0;
170
171 pr_debug("%s iSCSI Session SID %u is still active for %s,"
172 " preforming session reinstatement.\n", (sessiontype) ?
173 "Discovery" : "Normal", sess->sid,
174 sess->sess_ops->InitiatorName);
175
176 spin_lock_bh(&sess->conn_lock);
177 if (sess->session_state == TARG_SESS_STATE_FAILED) {
178 spin_unlock_bh(&sess->conn_lock);
179 iscsit_dec_session_usage_count(sess);
99367f01
NB
180 target_put_session(sess->se_sess);
181 return 0;
e48354ce
NB
182 }
183 spin_unlock_bh(&sess->conn_lock);
184
185 iscsit_stop_session(sess, 1, 1);
186 iscsit_dec_session_usage_count(sess);
187
99367f01
NB
188 target_put_session(sess->se_sess);
189 return 0;
e48354ce
NB
190}
191
192static void iscsi_login_set_conn_values(
193 struct iscsi_session *sess,
194 struct iscsi_conn *conn,
195 u16 cid)
196{
197 conn->sess = sess;
198 conn->cid = cid;
199 /*
200 * Generate a random Status sequence number (statsn) for the new
201 * iSCSI connection.
202 */
203 get_random_bytes(&conn->stat_sn, sizeof(u32));
204
205 mutex_lock(&auth_id_lock);
206 conn->auth_id = iscsit_global->auth_id++;
207 mutex_unlock(&auth_id_lock);
208}
209
210/*
211 * This is the leading connection of a new session,
212 * or session reinstatement.
213 */
214static int iscsi_login_zero_tsih_s1(
215 struct iscsi_conn *conn,
216 unsigned char *buf)
217{
218 struct iscsi_session *sess = NULL;
219 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
13b5533a 220 int ret;
e48354ce
NB
221
222 sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL);
223 if (!sess) {
224 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
225 ISCSI_LOGIN_STATUS_NO_RESOURCES);
226 pr_err("Could not allocate memory for session\n");
0957627a 227 return -ENOMEM;
e48354ce
NB
228 }
229
230 iscsi_login_set_conn_values(sess, conn, pdu->cid);
231 sess->init_task_tag = pdu->itt;
8359cf43 232 memcpy(&sess->isid, pdu->isid, 6);
e48354ce
NB
233 sess->exp_cmd_sn = pdu->cmdsn;
234 INIT_LIST_HEAD(&sess->sess_conn_list);
235 INIT_LIST_HEAD(&sess->sess_ooo_cmdsn_list);
236 INIT_LIST_HEAD(&sess->cr_active_list);
237 INIT_LIST_HEAD(&sess->cr_inactive_list);
238 init_completion(&sess->async_msg_comp);
239 init_completion(&sess->reinstatement_comp);
240 init_completion(&sess->session_wait_comp);
241 init_completion(&sess->session_waiting_on_uc_comp);
242 mutex_init(&sess->cmdsn_mutex);
243 spin_lock_init(&sess->conn_lock);
244 spin_lock_init(&sess->cr_a_lock);
245 spin_lock_init(&sess->cr_i_lock);
246 spin_lock_init(&sess->session_usage_lock);
247 spin_lock_init(&sess->ttt_lock);
248
249 if (!idr_pre_get(&sess_idr, GFP_KERNEL)) {
250 pr_err("idr_pre_get() for sess_idr failed\n");
251 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
252 ISCSI_LOGIN_STATUS_NO_RESOURCES);
0957627a
NB
253 kfree(sess);
254 return -ENOMEM;
e48354ce
NB
255 }
256 spin_lock(&sess_idr_lock);
13b5533a 257 ret = idr_get_new(&sess_idr, NULL, &sess->session_index);
e48354ce
NB
258 spin_unlock(&sess_idr_lock);
259
13b5533a
BW
260 if (ret < 0) {
261 pr_err("idr_get_new() for sess_idr failed\n");
262 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
263 ISCSI_LOGIN_STATUS_NO_RESOURCES);
264 kfree(sess);
265 return -ENOMEM;
266 }
267
e48354ce
NB
268 sess->creation_time = get_jiffies_64();
269 spin_lock_init(&sess->session_stats_lock);
270 /*
271 * The FFP CmdSN window values will be allocated from the TPG's
272 * Initiator Node's ACL once the login has been successfully completed.
273 */
274 sess->max_cmd_sn = pdu->cmdsn;
275
276 sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL);
277 if (!sess->sess_ops) {
278 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
279 ISCSI_LOGIN_STATUS_NO_RESOURCES);
280 pr_err("Unable to allocate memory for"
281 " struct iscsi_sess_ops.\n");
0957627a
NB
282 kfree(sess);
283 return -ENOMEM;
e48354ce
NB
284 }
285
286 sess->se_sess = transport_init_session();
0957627a 287 if (IS_ERR(sess->se_sess)) {
e48354ce
NB
288 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
289 ISCSI_LOGIN_STATUS_NO_RESOURCES);
0957627a
NB
290 kfree(sess);
291 return -ENOMEM;
e48354ce
NB
292 }
293
294 return 0;
295}
296
297static int iscsi_login_zero_tsih_s2(
298 struct iscsi_conn *conn)
299{
300 struct iscsi_node_attrib *na;
301 struct iscsi_session *sess = conn->sess;
302 unsigned char buf[32];
303
304 sess->tpg = conn->tpg;
305
306 /*
307 * Assign a new TPG Session Handle. Note this is protected with
308 * struct iscsi_portal_group->np_login_sem from iscsit_access_np().
309 */
310 sess->tsih = ++ISCSI_TPG_S(sess)->ntsih;
311 if (!sess->tsih)
312 sess->tsih = ++ISCSI_TPG_S(sess)->ntsih;
313
314 /*
315 * Create the default params from user defined values..
316 */
317 if (iscsi_copy_param_list(&conn->param_list,
318 ISCSI_TPG_C(conn)->param_list, 1) < 0) {
319 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
320 ISCSI_LOGIN_STATUS_NO_RESOURCES);
321 return -1;
322 }
323
324 iscsi_set_keys_to_negotiate(0, conn->param_list);
325
326 if (sess->sess_ops->SessionType)
327 return iscsi_set_keys_irrelevant_for_discovery(
328 conn->param_list);
329
330 na = iscsit_tpg_get_node_attrib(sess);
331
332 /*
333 * Need to send TargetPortalGroupTag back in first login response
334 * on any iSCSI connection where the Initiator provides TargetName.
335 * See 5.3.1. Login Phase Start
336 *
337 * In our case, we have already located the struct iscsi_tiqn at this point.
338 */
339 memset(buf, 0, 32);
340 sprintf(buf, "TargetPortalGroupTag=%hu", ISCSI_TPG_S(sess)->tpgt);
341 if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
342 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
343 ISCSI_LOGIN_STATUS_NO_RESOURCES);
344 return -1;
345 }
346
347 /*
348 * Workaround for Initiators that have broken connection recovery logic.
349 *
350 * "We would really like to get rid of this." Linux-iSCSI.org team
351 */
352 memset(buf, 0, 32);
353 sprintf(buf, "ErrorRecoveryLevel=%d", na->default_erl);
354 if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
355 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
356 ISCSI_LOGIN_STATUS_NO_RESOURCES);
357 return -1;
358 }
359
360 if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0)
361 return -1;
362
363 return 0;
364}
365
366/*
367 * Remove PSTATE_NEGOTIATE for the four FIM related keys.
368 * The Initiator node will be able to enable FIM by proposing them itself.
369 */
370int iscsi_login_disable_FIM_keys(
371 struct iscsi_param_list *param_list,
372 struct iscsi_conn *conn)
373{
374 struct iscsi_param *param;
375
376 param = iscsi_find_param_from_key("OFMarker", param_list);
377 if (!param) {
378 pr_err("iscsi_find_param_from_key() for"
379 " OFMarker failed\n");
380 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
381 ISCSI_LOGIN_STATUS_NO_RESOURCES);
382 return -1;
383 }
384 param->state &= ~PSTATE_NEGOTIATE;
385
386 param = iscsi_find_param_from_key("OFMarkInt", param_list);
387 if (!param) {
388 pr_err("iscsi_find_param_from_key() for"
389 " IFMarker failed\n");
390 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
391 ISCSI_LOGIN_STATUS_NO_RESOURCES);
392 return -1;
393 }
394 param->state &= ~PSTATE_NEGOTIATE;
395
396 param = iscsi_find_param_from_key("IFMarker", param_list);
397 if (!param) {
398 pr_err("iscsi_find_param_from_key() for"
399 " IFMarker failed\n");
400 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
401 ISCSI_LOGIN_STATUS_NO_RESOURCES);
402 return -1;
403 }
404 param->state &= ~PSTATE_NEGOTIATE;
405
406 param = iscsi_find_param_from_key("IFMarkInt", param_list);
407 if (!param) {
408 pr_err("iscsi_find_param_from_key() for"
409 " IFMarker failed\n");
410 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
411 ISCSI_LOGIN_STATUS_NO_RESOURCES);
412 return -1;
413 }
414 param->state &= ~PSTATE_NEGOTIATE;
415
416 return 0;
417}
418
419static int iscsi_login_non_zero_tsih_s1(
420 struct iscsi_conn *conn,
421 unsigned char *buf)
422{
423 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
424
425 iscsi_login_set_conn_values(NULL, conn, pdu->cid);
426 return 0;
427}
428
429/*
430 * Add a new connection to an existing session.
431 */
432static int iscsi_login_non_zero_tsih_s2(
433 struct iscsi_conn *conn,
434 unsigned char *buf)
435{
436 struct iscsi_portal_group *tpg = conn->tpg;
437 struct iscsi_session *sess = NULL, *sess_p = NULL;
438 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
439 struct se_session *se_sess, *se_sess_tmp;
440 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
441
442 spin_lock_bh(&se_tpg->session_lock);
443 list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list,
444 sess_list) {
445
446 sess_p = (struct iscsi_session *)se_sess->fabric_sess_ptr;
447 if (atomic_read(&sess_p->session_fall_back_to_erl0) ||
448 atomic_read(&sess_p->session_logout) ||
449 (sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED))
450 continue;
8359cf43 451 if (!memcmp(sess_p->isid, pdu->isid, 6) &&
e48354ce
NB
452 (sess_p->tsih == pdu->tsih)) {
453 iscsit_inc_session_usage_count(sess_p);
454 iscsit_stop_time2retain_timer(sess_p);
455 sess = sess_p;
456 break;
457 }
458 }
459 spin_unlock_bh(&se_tpg->session_lock);
460
461 /*
462 * If the Time2Retain handler has expired, the session is already gone.
463 */
464 if (!sess) {
465 pr_err("Initiator attempting to add a connection to"
466 " a non-existent session, rejecting iSCSI Login.\n");
467 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
468 ISCSI_LOGIN_STATUS_NO_SESSION);
469 return -1;
470 }
471
472 /*
473 * Stop the Time2Retain timer if this is a failed session, we restart
474 * the timer if the login is not successful.
475 */
476 spin_lock_bh(&sess->conn_lock);
477 if (sess->session_state == TARG_SESS_STATE_FAILED)
478 atomic_set(&sess->session_continuation, 1);
479 spin_unlock_bh(&sess->conn_lock);
480
481 iscsi_login_set_conn_values(sess, conn, pdu->cid);
482
483 if (iscsi_copy_param_list(&conn->param_list,
484 ISCSI_TPG_C(conn)->param_list, 0) < 0) {
485 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
486 ISCSI_LOGIN_STATUS_NO_RESOURCES);
487 return -1;
488 }
489
490 iscsi_set_keys_to_negotiate(0, conn->param_list);
491 /*
492 * Need to send TargetPortalGroupTag back in first login response
493 * on any iSCSI connection where the Initiator provides TargetName.
494 * See 5.3.1. Login Phase Start
495 *
496 * In our case, we have already located the struct iscsi_tiqn at this point.
497 */
498 memset(buf, 0, 32);
499 sprintf(buf, "TargetPortalGroupTag=%hu", ISCSI_TPG_S(sess)->tpgt);
500 if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
501 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
502 ISCSI_LOGIN_STATUS_NO_RESOURCES);
503 return -1;
504 }
505
506 return iscsi_login_disable_FIM_keys(conn->param_list, conn);
507}
508
509int iscsi_login_post_auth_non_zero_tsih(
510 struct iscsi_conn *conn,
511 u16 cid,
512 u32 exp_statsn)
513{
514 struct iscsi_conn *conn_ptr = NULL;
515 struct iscsi_conn_recovery *cr = NULL;
516 struct iscsi_session *sess = conn->sess;
517
518 /*
519 * By following item 5 in the login table, if we have found
520 * an existing ISID and a valid/existing TSIH and an existing
521 * CID we do connection reinstatement. Currently we dont not
522 * support it so we send back an non-zero status class to the
523 * initiator and release the new connection.
524 */
525 conn_ptr = iscsit_get_conn_from_cid_rcfr(sess, cid);
ee1b1b9c 526 if (conn_ptr) {
e48354ce
NB
527 pr_err("Connection exists with CID %hu for %s,"
528 " performing connection reinstatement.\n",
529 conn_ptr->cid, sess->sess_ops->InitiatorName);
530
531 iscsit_connection_reinstatement_rcfr(conn_ptr);
532 iscsit_dec_conn_usage_count(conn_ptr);
533 }
534
535 /*
536 * Check for any connection recovery entires containing CID.
537 * We use the original ExpStatSN sent in the first login request
538 * to acknowledge commands for the failed connection.
539 *
540 * Also note that an explict logout may have already been sent,
541 * but the response may not be sent due to additional connection
542 * loss.
543 */
544 if (sess->sess_ops->ErrorRecoveryLevel == 2) {
545 cr = iscsit_get_inactive_connection_recovery_entry(
546 sess, cid);
ee1b1b9c 547 if (cr) {
e48354ce
NB
548 pr_debug("Performing implicit logout"
549 " for connection recovery on CID: %hu\n",
550 conn->cid);
551 iscsit_discard_cr_cmds_by_expstatsn(cr, exp_statsn);
552 }
553 }
554
555 /*
556 * Else we follow item 4 from the login table in that we have
557 * found an existing ISID and a valid/existing TSIH and a new
558 * CID we go ahead and continue to add a new connection to the
559 * session.
560 */
561 pr_debug("Adding CID %hu to existing session for %s.\n",
562 cid, sess->sess_ops->InitiatorName);
563
564 if ((atomic_read(&sess->nconn) + 1) > sess->sess_ops->MaxConnections) {
565 pr_err("Adding additional connection to this session"
566 " would exceed MaxConnections %d, login failed.\n",
567 sess->sess_ops->MaxConnections);
568 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
569 ISCSI_LOGIN_STATUS_ISID_ERROR);
570 return -1;
571 }
572
573 return 0;
574}
575
576static void iscsi_post_login_start_timers(struct iscsi_conn *conn)
577{
578 struct iscsi_session *sess = conn->sess;
579
580 if (!sess->sess_ops->SessionType)
581 iscsit_start_nopin_timer(conn);
582}
583
584static int iscsi_post_login_handler(
585 struct iscsi_np *np,
586 struct iscsi_conn *conn,
587 u8 zero_tsih)
588{
589 int stop_timer = 0;
590 struct iscsi_session *sess = conn->sess;
591 struct se_session *se_sess = sess->se_sess;
592 struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess);
593 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
594 struct iscsi_thread_set *ts;
595
596 iscsit_inc_conn_usage_count(conn);
597
598 iscsit_collect_login_stats(conn, ISCSI_STATUS_CLS_SUCCESS,
599 ISCSI_LOGIN_STATUS_ACCEPT);
600
601 pr_debug("Moving to TARG_CONN_STATE_LOGGED_IN.\n");
602 conn->conn_state = TARG_CONN_STATE_LOGGED_IN;
603
604 iscsi_set_connection_parameters(conn->conn_ops, conn->param_list);
605 iscsit_set_sync_and_steering_values(conn);
606 /*
607 * SCSI Initiator -> SCSI Target Port Mapping
608 */
609 ts = iscsi_get_thread_set();
610 if (!zero_tsih) {
611 iscsi_set_session_parameters(sess->sess_ops,
612 conn->param_list, 0);
613 iscsi_release_param_list(conn->param_list);
614 conn->param_list = NULL;
615
616 spin_lock_bh(&sess->conn_lock);
617 atomic_set(&sess->session_continuation, 0);
618 if (sess->session_state == TARG_SESS_STATE_FAILED) {
619 pr_debug("Moving to"
620 " TARG_SESS_STATE_LOGGED_IN.\n");
621 sess->session_state = TARG_SESS_STATE_LOGGED_IN;
622 stop_timer = 1;
623 }
624
625 pr_debug("iSCSI Login successful on CID: %hu from %s to"
2f9bc894
NB
626 " %s:%hu,%hu\n", conn->cid, conn->login_ip,
627 conn->local_ip, conn->local_port, tpg->tpgt);
e48354ce
NB
628
629 list_add_tail(&conn->conn_list, &sess->sess_conn_list);
630 atomic_inc(&sess->nconn);
631 pr_debug("Incremented iSCSI Connection count to %hu"
632 " from node: %s\n", atomic_read(&sess->nconn),
633 sess->sess_ops->InitiatorName);
634 spin_unlock_bh(&sess->conn_lock);
635
636 iscsi_post_login_start_timers(conn);
637 iscsi_activate_thread_set(conn, ts);
638 /*
639 * Determine CPU mask to ensure connection's RX and TX kthreads
640 * are scheduled on the same CPU.
641 */
642 iscsit_thread_get_cpumask(conn);
643 conn->conn_rx_reset_cpumask = 1;
644 conn->conn_tx_reset_cpumask = 1;
645
646 iscsit_dec_conn_usage_count(conn);
647 if (stop_timer) {
648 spin_lock_bh(&se_tpg->session_lock);
649 iscsit_stop_time2retain_timer(sess);
650 spin_unlock_bh(&se_tpg->session_lock);
651 }
652 iscsit_dec_session_usage_count(sess);
653 return 0;
654 }
655
656 iscsi_set_session_parameters(sess->sess_ops, conn->param_list, 1);
657 iscsi_release_param_list(conn->param_list);
658 conn->param_list = NULL;
659
660 iscsit_determine_maxcmdsn(sess);
661
662 spin_lock_bh(&se_tpg->session_lock);
663 __transport_register_session(&sess->tpg->tpg_se_tpg,
8359cf43 664 se_sess->se_node_acl, se_sess, sess);
e48354ce
NB
665 pr_debug("Moving to TARG_SESS_STATE_LOGGED_IN.\n");
666 sess->session_state = TARG_SESS_STATE_LOGGED_IN;
667
668 pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n",
2f9bc894
NB
669 conn->cid, conn->login_ip, conn->local_ip, conn->local_port,
670 tpg->tpgt);
e48354ce
NB
671
672 spin_lock_bh(&sess->conn_lock);
673 list_add_tail(&conn->conn_list, &sess->sess_conn_list);
674 atomic_inc(&sess->nconn);
675 pr_debug("Incremented iSCSI Connection count to %hu from node:"
676 " %s\n", atomic_read(&sess->nconn),
677 sess->sess_ops->InitiatorName);
678 spin_unlock_bh(&sess->conn_lock);
679
680 sess->sid = tpg->sid++;
681 if (!sess->sid)
682 sess->sid = tpg->sid++;
683 pr_debug("Established iSCSI session from node: %s\n",
684 sess->sess_ops->InitiatorName);
685
686 tpg->nsessions++;
687 if (tpg->tpg_tiqn)
688 tpg->tpg_tiqn->tiqn_nsessions++;
689
690 pr_debug("Incremented number of active iSCSI sessions to %u on"
691 " iSCSI Target Portal Group: %hu\n", tpg->nsessions, tpg->tpgt);
692 spin_unlock_bh(&se_tpg->session_lock);
693
694 iscsi_post_login_start_timers(conn);
695 iscsi_activate_thread_set(conn, ts);
696 /*
697 * Determine CPU mask to ensure connection's RX and TX kthreads
698 * are scheduled on the same CPU.
699 */
700 iscsit_thread_get_cpumask(conn);
701 conn->conn_rx_reset_cpumask = 1;
702 conn->conn_tx_reset_cpumask = 1;
703
704 iscsit_dec_conn_usage_count(conn);
705
706 return 0;
707}
708
709static void iscsi_handle_login_thread_timeout(unsigned long data)
710{
711 struct iscsi_np *np = (struct iscsi_np *) data;
712
713 spin_lock_bh(&np->np_thread_lock);
714 pr_err("iSCSI Login timeout on Network Portal %s:%hu\n",
715 np->np_ip, np->np_port);
716
717 if (np->np_login_timer_flags & ISCSI_TF_STOP) {
718 spin_unlock_bh(&np->np_thread_lock);
719 return;
720 }
721
722 if (np->np_thread)
723 send_sig(SIGINT, np->np_thread, 1);
724
725 np->np_login_timer_flags &= ~ISCSI_TF_RUNNING;
726 spin_unlock_bh(&np->np_thread_lock);
727}
728
729static void iscsi_start_login_thread_timer(struct iscsi_np *np)
730{
731 /*
732 * This used the TA_LOGIN_TIMEOUT constant because at this
733 * point we do not have access to ISCSI_TPG_ATTRIB(tpg)->login_timeout
734 */
735 spin_lock_bh(&np->np_thread_lock);
736 init_timer(&np->np_login_timer);
737 np->np_login_timer.expires = (get_jiffies_64() + TA_LOGIN_TIMEOUT * HZ);
738 np->np_login_timer.data = (unsigned long)np;
739 np->np_login_timer.function = iscsi_handle_login_thread_timeout;
740 np->np_login_timer_flags &= ~ISCSI_TF_STOP;
741 np->np_login_timer_flags |= ISCSI_TF_RUNNING;
742 add_timer(&np->np_login_timer);
743
744 pr_debug("Added timeout timer to iSCSI login request for"
745 " %u seconds.\n", TA_LOGIN_TIMEOUT);
746 spin_unlock_bh(&np->np_thread_lock);
747}
748
749static void iscsi_stop_login_thread_timer(struct iscsi_np *np)
750{
751 spin_lock_bh(&np->np_thread_lock);
752 if (!(np->np_login_timer_flags & ISCSI_TF_RUNNING)) {
753 spin_unlock_bh(&np->np_thread_lock);
754 return;
755 }
756 np->np_login_timer_flags |= ISCSI_TF_STOP;
757 spin_unlock_bh(&np->np_thread_lock);
758
759 del_timer_sync(&np->np_login_timer);
760
761 spin_lock_bh(&np->np_thread_lock);
762 np->np_login_timer_flags &= ~ISCSI_TF_RUNNING;
763 spin_unlock_bh(&np->np_thread_lock);
764}
765
766int iscsi_target_setup_login_socket(
767 struct iscsi_np *np,
768 struct __kernel_sockaddr_storage *sockaddr)
769{
770 struct socket *sock;
771 int backlog = 5, ret, opt = 0, len;
772
773 switch (np->np_network_transport) {
774 case ISCSI_TCP:
775 np->np_ip_proto = IPPROTO_TCP;
776 np->np_sock_type = SOCK_STREAM;
777 break;
778 case ISCSI_SCTP_TCP:
779 np->np_ip_proto = IPPROTO_SCTP;
780 np->np_sock_type = SOCK_STREAM;
781 break;
782 case ISCSI_SCTP_UDP:
783 np->np_ip_proto = IPPROTO_SCTP;
784 np->np_sock_type = SOCK_SEQPACKET;
785 break;
786 case ISCSI_IWARP_TCP:
787 case ISCSI_IWARP_SCTP:
788 case ISCSI_INFINIBAND:
789 default:
790 pr_err("Unsupported network_transport: %d\n",
791 np->np_network_transport);
792 return -EINVAL;
793 }
794
795 ret = sock_create(sockaddr->ss_family, np->np_sock_type,
796 np->np_ip_proto, &sock);
797 if (ret < 0) {
798 pr_err("sock_create() failed.\n");
799 return ret;
800 }
801 np->np_socket = sock;
e48354ce
NB
802 /*
803 * Setup the np->np_sockaddr from the passed sockaddr setup
804 * in iscsi_target_configfs.c code..
805 */
8359cf43 806 memcpy(&np->np_sockaddr, sockaddr,
e48354ce
NB
807 sizeof(struct __kernel_sockaddr_storage));
808
809 if (sockaddr->ss_family == AF_INET6)
810 len = sizeof(struct sockaddr_in6);
811 else
812 len = sizeof(struct sockaddr_in);
813 /*
814 * Set SO_REUSEADDR, and disable Nagel Algorithm with TCP_NODELAY.
815 */
8359cf43 816 /* FIXME: Someone please explain why this is endian-safe */
e48354ce
NB
817 opt = 1;
818 if (np->np_network_transport == ISCSI_TCP) {
819 ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
820 (char *)&opt, sizeof(opt));
821 if (ret < 0) {
822 pr_err("kernel_setsockopt() for TCP_NODELAY"
823 " failed: %d\n", ret);
824 goto fail;
825 }
826 }
827
8359cf43 828 /* FIXME: Someone please explain why this is endian-safe */
e48354ce
NB
829 ret = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
830 (char *)&opt, sizeof(opt));
831 if (ret < 0) {
832 pr_err("kernel_setsockopt() for SO_REUSEADDR"
833 " failed\n");
834 goto fail;
835 }
836
9f9ef6d3
DK
837 ret = kernel_setsockopt(sock, IPPROTO_IP, IP_FREEBIND,
838 (char *)&opt, sizeof(opt));
839 if (ret < 0) {
840 pr_err("kernel_setsockopt() for IP_FREEBIND"
841 " failed\n");
842 goto fail;
843 }
844
e48354ce
NB
845 ret = kernel_bind(sock, (struct sockaddr *)&np->np_sockaddr, len);
846 if (ret < 0) {
847 pr_err("kernel_bind() failed: %d\n", ret);
848 goto fail;
849 }
850
851 ret = kernel_listen(sock, backlog);
852 if (ret != 0) {
853 pr_err("kernel_listen() failed: %d\n", ret);
854 goto fail;
855 }
856
857 return 0;
858
859fail:
860 np->np_socket = NULL;
bf6932f4 861 if (sock)
e48354ce 862 sock_release(sock);
e48354ce
NB
863 return ret;
864}
865
866static int __iscsi_target_login_thread(struct iscsi_np *np)
867{
868 u8 buffer[ISCSI_HDR_LEN], iscsi_opcode, zero_tsih = 0;
bf6932f4 869 int err, ret = 0, stop;
e48354ce
NB
870 struct iscsi_conn *conn = NULL;
871 struct iscsi_login *login;
872 struct iscsi_portal_group *tpg = NULL;
873 struct socket *new_sock, *sock;
874 struct kvec iov;
875 struct iscsi_login_req *pdu;
876 struct sockaddr_in sock_in;
877 struct sockaddr_in6 sock_in6;
878
879 flush_signals(current);
e48354ce 880 sock = np->np_socket;
e48354ce
NB
881
882 spin_lock_bh(&np->np_thread_lock);
883 if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
884 np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
885 complete(&np->np_restart_comp);
886 } else {
887 np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
888 }
889 spin_unlock_bh(&np->np_thread_lock);
890
891 if (kernel_accept(sock, &new_sock, 0) < 0) {
892 spin_lock_bh(&np->np_thread_lock);
893 if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
894 spin_unlock_bh(&np->np_thread_lock);
895 complete(&np->np_restart_comp);
896 /* Get another socket */
897 return 1;
898 }
899 spin_unlock_bh(&np->np_thread_lock);
900 goto out;
901 }
e48354ce
NB
902 iscsi_start_login_thread_timer(np);
903
904 conn = kzalloc(sizeof(struct iscsi_conn), GFP_KERNEL);
905 if (!conn) {
906 pr_err("Could not allocate memory for"
907 " new connection\n");
e48354ce
NB
908 sock_release(new_sock);
909 /* Get another socket */
910 return 1;
911 }
912
913 pr_debug("Moving to TARG_CONN_STATE_FREE.\n");
914 conn->conn_state = TARG_CONN_STATE_FREE;
915 conn->sock = new_sock;
916
e48354ce
NB
917 pr_debug("Moving to TARG_CONN_STATE_XPT_UP.\n");
918 conn->conn_state = TARG_CONN_STATE_XPT_UP;
919
920 /*
921 * Allocate conn->conn_ops early as a failure calling
922 * iscsit_tx_login_rsp() below will call tx_data().
923 */
924 conn->conn_ops = kzalloc(sizeof(struct iscsi_conn_ops), GFP_KERNEL);
925 if (!conn->conn_ops) {
926 pr_err("Unable to allocate memory for"
927 " struct iscsi_conn_ops.\n");
928 goto new_sess_out;
929 }
930 /*
931 * Perform the remaining iSCSI connection initialization items..
932 */
933 if (iscsi_login_init_conn(conn) < 0)
934 goto new_sess_out;
935
936 memset(buffer, 0, ISCSI_HDR_LEN);
937 memset(&iov, 0, sizeof(struct kvec));
938 iov.iov_base = buffer;
939 iov.iov_len = ISCSI_HDR_LEN;
940
941 if (rx_data(conn, &iov, 1, ISCSI_HDR_LEN) <= 0) {
942 pr_err("rx_data() returned an error.\n");
943 goto new_sess_out;
944 }
945
946 iscsi_opcode = (buffer[0] & ISCSI_OPCODE_MASK);
947 if (!(iscsi_opcode & ISCSI_OP_LOGIN)) {
948 pr_err("First opcode is not login request,"
949 " failing login request.\n");
950 goto new_sess_out;
951 }
952
953 pdu = (struct iscsi_login_req *) buffer;
954 pdu->cid = be16_to_cpu(pdu->cid);
955 pdu->tsih = be16_to_cpu(pdu->tsih);
e48354ce
NB
956 pdu->cmdsn = be32_to_cpu(pdu->cmdsn);
957 pdu->exp_statsn = be32_to_cpu(pdu->exp_statsn);
66c7db68 958
e48354ce
NB
959 /*
960 * Used by iscsit_tx_login_rsp() for Login Resonses PDUs
961 * when Status-Class != 0.
962 */
963 conn->login_itt = pdu->itt;
964
965 spin_lock_bh(&np->np_thread_lock);
966 if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
967 spin_unlock_bh(&np->np_thread_lock);
968 pr_err("iSCSI Network Portal on %s:%hu currently not"
969 " active.\n", np->np_ip, np->np_port);
970 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
971 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
972 goto new_sess_out;
973 }
974 spin_unlock_bh(&np->np_thread_lock);
975
976 if (np->np_sockaddr.ss_family == AF_INET6) {
977 memset(&sock_in6, 0, sizeof(struct sockaddr_in6));
978
979 if (conn->sock->ops->getname(conn->sock,
980 (struct sockaddr *)&sock_in6, &err, 1) < 0) {
981 pr_err("sock_ops->getname() failed.\n");
982 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
983 ISCSI_LOGIN_STATUS_TARGET_ERROR);
984 goto new_sess_out;
985 }
6626a057
CB
986 snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c",
987 &sock_in6.sin6_addr.in6_u);
988 conn->login_port = ntohs(sock_in6.sin6_port);
2f9bc894
NB
989
990 if (conn->sock->ops->getname(conn->sock,
991 (struct sockaddr *)&sock_in6, &err, 0) < 0) {
992 pr_err("sock_ops->getname() failed.\n");
993 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
994 ISCSI_LOGIN_STATUS_TARGET_ERROR);
995 goto new_sess_out;
996 }
997 snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI6c",
998 &sock_in6.sin6_addr.in6_u);
999 conn->local_port = ntohs(sock_in6.sin6_port);
1000
e48354ce
NB
1001 } else {
1002 memset(&sock_in, 0, sizeof(struct sockaddr_in));
1003
1004 if (conn->sock->ops->getname(conn->sock,
1005 (struct sockaddr *)&sock_in, &err, 1) < 0) {
1006 pr_err("sock_ops->getname() failed.\n");
1007 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1008 ISCSI_LOGIN_STATUS_TARGET_ERROR);
1009 goto new_sess_out;
1010 }
1011 sprintf(conn->login_ip, "%pI4", &sock_in.sin_addr.s_addr);
1012 conn->login_port = ntohs(sock_in.sin_port);
2f9bc894
NB
1013
1014 if (conn->sock->ops->getname(conn->sock,
1015 (struct sockaddr *)&sock_in, &err, 0) < 0) {
1016 pr_err("sock_ops->getname() failed.\n");
1017 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1018 ISCSI_LOGIN_STATUS_TARGET_ERROR);
1019 goto new_sess_out;
1020 }
1021 sprintf(conn->local_ip, "%pI4", &sock_in.sin_addr.s_addr);
1022 conn->local_port = ntohs(sock_in.sin_port);
e48354ce
NB
1023 }
1024
1025 conn->network_transport = np->np_network_transport;
1026
1027 pr_debug("Received iSCSI login request from %s on %s Network"
1028 " Portal %s:%hu\n", conn->login_ip,
1029 (conn->network_transport == ISCSI_TCP) ? "TCP" : "SCTP",
2f9bc894 1030 conn->local_ip, conn->local_port);
e48354ce
NB
1031
1032 pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n");
1033 conn->conn_state = TARG_CONN_STATE_IN_LOGIN;
1034
1035 if (iscsi_login_check_initiator_version(conn, pdu->max_version,
1036 pdu->min_version) < 0)
1037 goto new_sess_out;
1038
1039 zero_tsih = (pdu->tsih == 0x0000);
ee1b1b9c 1040 if (zero_tsih) {
e48354ce
NB
1041 /*
1042 * This is the leading connection of a new session.
1043 * We wait until after authentication to check for
1044 * session reinstatement.
1045 */
1046 if (iscsi_login_zero_tsih_s1(conn, buffer) < 0)
1047 goto new_sess_out;
1048 } else {
1049 /*
1050 * Add a new connection to an existing session.
1051 * We check for a non-existant session in
1052 * iscsi_login_non_zero_tsih_s2() below based
1053 * on ISID/TSIH, but wait until after authentication
1054 * to check for connection reinstatement, etc.
1055 */
1056 if (iscsi_login_non_zero_tsih_s1(conn, buffer) < 0)
1057 goto new_sess_out;
1058 }
1059
1060 /*
1061 * This will process the first login request, and call
1062 * iscsi_target_locate_portal(), and return a valid struct iscsi_login.
1063 */
1064 login = iscsi_target_init_negotiation(np, conn, buffer);
1065 if (!login) {
1066 tpg = conn->tpg;
1067 goto new_sess_out;
1068 }
1069
1070 tpg = conn->tpg;
1071 if (!tpg) {
1072 pr_err("Unable to locate struct iscsi_conn->tpg\n");
1073 goto new_sess_out;
1074 }
1075
1076 if (zero_tsih) {
1077 if (iscsi_login_zero_tsih_s2(conn) < 0) {
1078 iscsi_target_nego_release(login, conn);
1079 goto new_sess_out;
1080 }
1081 } else {
1082 if (iscsi_login_non_zero_tsih_s2(conn, buffer) < 0) {
1083 iscsi_target_nego_release(login, conn);
1084 goto old_sess_out;
1085 }
1086 }
1087
1088 if (iscsi_target_start_negotiation(login, conn) < 0)
1089 goto new_sess_out;
1090
1091 if (!conn->sess) {
1092 pr_err("struct iscsi_conn session pointer is NULL!\n");
1093 goto new_sess_out;
1094 }
1095
1096 iscsi_stop_login_thread_timer(np);
1097
1098 if (signal_pending(current))
1099 goto new_sess_out;
1100
1101 ret = iscsi_post_login_handler(np, conn, zero_tsih);
1102
1103 if (ret < 0)
1104 goto new_sess_out;
1105
1106 iscsit_deaccess_np(np, tpg);
1107 tpg = NULL;
1108 /* Get another socket */
1109 return 1;
1110
1111new_sess_out:
1112 pr_err("iSCSI Login negotiation failed.\n");
1113 iscsit_collect_login_stats(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
1114 ISCSI_LOGIN_STATUS_INIT_ERR);
1115 if (!zero_tsih || !conn->sess)
1116 goto old_sess_out;
1117 if (conn->sess->se_sess)
1118 transport_free_session(conn->sess->se_sess);
1119 if (conn->sess->session_index != 0) {
1120 spin_lock_bh(&sess_idr_lock);
1121 idr_remove(&sess_idr, conn->sess->session_index);
1122 spin_unlock_bh(&sess_idr_lock);
1123 }
1124 if (conn->sess->sess_ops)
1125 kfree(conn->sess->sess_ops);
1126 if (conn->sess)
1127 kfree(conn->sess);
1128old_sess_out:
1129 iscsi_stop_login_thread_timer(np);
1130 /*
1131 * If login negotiation fails check if the Time2Retain timer
1132 * needs to be restarted.
1133 */
1134 if (!zero_tsih && conn->sess) {
1135 spin_lock_bh(&conn->sess->conn_lock);
1136 if (conn->sess->session_state == TARG_SESS_STATE_FAILED) {
1137 struct se_portal_group *se_tpg =
1138 &ISCSI_TPG_C(conn)->tpg_se_tpg;
1139
1140 atomic_set(&conn->sess->session_continuation, 0);
1141 spin_unlock_bh(&conn->sess->conn_lock);
1142 spin_lock_bh(&se_tpg->session_lock);
1143 iscsit_start_time2retain_handler(conn->sess);
1144 spin_unlock_bh(&se_tpg->session_lock);
1145 } else
1146 spin_unlock_bh(&conn->sess->conn_lock);
1147 iscsit_dec_session_usage_count(conn->sess);
1148 }
1149
1150 if (!IS_ERR(conn->conn_rx_hash.tfm))
1151 crypto_free_hash(conn->conn_rx_hash.tfm);
1152 if (!IS_ERR(conn->conn_tx_hash.tfm))
1153 crypto_free_hash(conn->conn_tx_hash.tfm);
1154
1155 if (conn->conn_cpumask)
1156 free_cpumask_var(conn->conn_cpumask);
1157
1158 kfree(conn->conn_ops);
1159
1160 if (conn->param_list) {
1161 iscsi_release_param_list(conn->param_list);
1162 conn->param_list = NULL;
1163 }
bf6932f4 1164 if (conn->sock)
e48354ce 1165 sock_release(conn->sock);
e48354ce
NB
1166 kfree(conn);
1167
1168 if (tpg) {
1169 iscsit_deaccess_np(np, tpg);
1170 tpg = NULL;
1171 }
1172
1173out:
1174 stop = kthread_should_stop();
1175 if (!stop && signal_pending(current)) {
1176 spin_lock_bh(&np->np_thread_lock);
1177 stop = (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN);
1178 spin_unlock_bh(&np->np_thread_lock);
1179 }
1180 /* Wait for another socket.. */
1181 if (!stop)
1182 return 1;
1183
1184 iscsi_stop_login_thread_timer(np);
1185 spin_lock_bh(&np->np_thread_lock);
1186 np->np_thread_state = ISCSI_NP_THREAD_EXIT;
1187 spin_unlock_bh(&np->np_thread_lock);
1188 return 0;
1189}
1190
1191int iscsi_target_login_thread(void *arg)
1192{
8359cf43 1193 struct iscsi_np *np = arg;
e48354ce
NB
1194 int ret;
1195
1196 allow_signal(SIGINT);
1197
1198 while (!kthread_should_stop()) {
1199 ret = __iscsi_target_login_thread(np);
1200 /*
1201 * We break and exit here unless another sock_accept() call
1202 * is expected.
1203 */
1204 if (ret != 1)
1205 break;
1206 }
1207
1208 return 0;
1209}