Skip to content

Commit 8d2860b

Browse files
Mike ChristieJames Bottomley
authored andcommitted
[SCSI] iscsi: increment expstatsn during login
debugged by Ming and Rohan: The problem Ming and Rohan debugged was that during a normal session login, open-iscsi is not incrementing the exp_statsn counter. It was stuck at zero. From the RFC, it looks like if the login response PDU has a successful status then we should be incrementing that value. Also from the RFC, it looks like if when we drop a connection then reconnect, we should be using the exp_statsn from the old connection in the next relogin attempt. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
1 parent be2df72 commit 8d2860b

File tree

4 files changed

+32
-21
lines changed

4 files changed

+32
-21
lines changed

drivers/scsi/iscsi_tcp.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2298,6 +2298,9 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
22982298
BUG_ON(value);
22992299
session->ofmarker_en = value;
23002300
break;
2301+
case ISCSI_PARAM_EXP_STATSN:
2302+
conn->exp_statsn = value;
2303+
break;
23012304
default:
23022305
break;
23032306
}
@@ -2381,6 +2384,9 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
23812384
inet = inet_sk(tcp_conn->sock->sk);
23822385
*value = be16_to_cpu(inet->dport);
23832386
mutex_unlock(&conn->xmitmutex);
2387+
case ISCSI_PARAM_EXP_STATSN:
2388+
*value = conn->exp_statsn;
2389+
break;
23842390
default:
23852391
return -EINVAL;
23862392
}
@@ -2548,7 +2554,8 @@ static struct iscsi_transport iscsi_tcp_transport = {
25482554
ISCSI_DATASEQ_INORDER_EN |
25492555
ISCSI_ERL |
25502556
ISCSI_CONN_PORT |
2551-
ISCSI_CONN_ADDRESS,
2557+
ISCSI_CONN_ADDRESS |
2558+
ISCSI_EXP_STATSN,
25522559
.host_template = &iscsi_sht,
25532560
.conndata_size = sizeof(struct iscsi_conn),
25542561
.max_conn = 1,

drivers/scsi/libiscsi.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -333,31 +333,34 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
333333
debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n",
334334
opcode, conn->id, mtask->itt, datalen);
335335

336+
rc = iscsi_check_assign_cmdsn(session,
337+
(struct iscsi_nopin*)hdr);
338+
if (rc)
339+
goto done;
340+
336341
switch(opcode) {
342+
case ISCSI_OP_LOGOUT_RSP:
343+
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
344+
/* fall through */
337345
case ISCSI_OP_LOGIN_RSP:
338346
case ISCSI_OP_TEXT_RSP:
339-
case ISCSI_OP_LOGOUT_RSP:
340-
rc = iscsi_check_assign_cmdsn(session,
341-
(struct iscsi_nopin*)hdr);
342-
if (rc)
343-
break;
344-
347+
/*
348+
* login related PDU's exp_statsn is handled in
349+
* userspace
350+
*/
345351
rc = iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen);
346352
list_del(&mtask->running);
347353
if (conn->login_mtask != mtask)
348354
__kfifo_put(session->mgmtpool.queue,
349355
(void*)&mtask, sizeof(void*));
350356
break;
351357
case ISCSI_OP_SCSI_TMFUNC_RSP:
352-
rc = iscsi_check_assign_cmdsn(session,
353-
(struct iscsi_nopin*)hdr);
354-
if (rc)
355-
break;
356-
357358
if (datalen) {
358359
rc = ISCSI_ERR_PROTO;
359360
break;
360361
}
362+
363+
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
361364
conn->tmfrsp_pdus_cnt++;
362365
if (conn->tmabort_state == TMABORT_INITIAL) {
363366
conn->tmabort_state =
@@ -373,10 +376,6 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
373376
rc = ISCSI_ERR_PROTO;
374377
break;
375378
}
376-
rc = iscsi_check_assign_cmdsn(session,
377-
(struct iscsi_nopin*)hdr);
378-
if (rc)
379-
break;
380379
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
381380

382381
rc = iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen);
@@ -404,6 +403,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
404403
case ISCSI_OP_REJECT:
405404
/* we need sth like iscsi_reject_rsp()*/
406405
case ISCSI_OP_ASYNC_EVENT:
406+
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
407407
/* we need sth like iscsi_async_event_rsp() */
408408
rc = ISCSI_ERR_BAD_OPCODE;
409409
break;
@@ -414,6 +414,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
414414
} else
415415
rc = ISCSI_ERR_BAD_ITT;
416416

417+
done:
417418
return rc;
418419
}
419420
EXPORT_SYMBOL_GPL(__iscsi_complete_pdu);
@@ -730,6 +731,7 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
730731
BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
731732
BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
732733

734+
nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
733735
if (!__kfifo_get(session->mgmtpool.queue,
734736
(void*)&mtask, sizeof(void*))) {
735737
spin_unlock_bh(&session->lock);
@@ -738,7 +740,7 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
738740
}
739741

740742
/*
741-
* pre-format CmdSN and ExpStatSN for outgoing PDU.
743+
* pre-format CmdSN for outgoing PDU.
742744
*/
743745
if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {
744746
hdr->itt = mtask->itt | (conn->id << ISCSI_CID_SHIFT) |
@@ -751,8 +753,6 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
751753
/* do not advance CmdSN */
752754
nop->cmdsn = cpu_to_be32(session->cmdsn);
753755

754-
nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
755-
756756
if (data_size) {
757757
memcpy(mtask->data, data, data_size);
758758
mtask->data_count = data_size;
@@ -1647,7 +1647,7 @@ void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
16471647
case STOP_CONN_RECOVER:
16481648
case STOP_CONN_TERM:
16491649
iscsi_start_session_recovery(session, conn, flag);
1650-
return;
1650+
break;
16511651
case STOP_CONN_SUSPEND:
16521652
if (session->tt->suspend_conn_recv)
16531653
session->tt->suspend_conn_recv(conn);

drivers/scsi/scsi_transport_iscsi.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
#include <scsi/iscsi_if.h>
3333

3434
#define ISCSI_SESSION_ATTRS 11
35-
#define ISCSI_CONN_ATTRS 10
35+
#define ISCSI_CONN_ATTRS 11
3636
#define ISCSI_HOST_ATTRS 0
3737

3838
struct iscsi_internal {
@@ -1156,6 +1156,7 @@ iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d");
11561156
iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d");
11571157
iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d");
11581158
iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d");
1159+
iscsi_conn_int_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN, "%u");
11591160

11601161
#define iscsi_conn_str_attr_show(param) \
11611162
static ssize_t \
@@ -1406,6 +1407,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
14061407
SETUP_CONN_RD_ATTR(ofmarker, ISCSI_OFMARKER_EN);
14071408
SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS);
14081409
SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT);
1410+
SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN);
14091411

14101412
if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS)
14111413
SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS);

include/scsi/iscsi_if.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ enum iscsi_param {
188188
ISCSI_PARAM_ERL,
189189
ISCSI_PARAM_IFMARKER_EN,
190190
ISCSI_PARAM_OFMARKER_EN,
191+
ISCSI_PARAM_EXP_STATSN,
191192
ISCSI_PARAM_TARGET_NAME,
192193
ISCSI_PARAM_TPGT,
193194
ISCSI_PARAM_PERSISTENT_ADDRESS,
@@ -216,6 +217,7 @@ enum iscsi_param {
216217
#define ISCSI_ERL (1 << ISCSI_PARAM_ERL)
217218
#define ISCSI_IFMARKER_EN (1 << ISCSI_PARAM_IFMARKER_EN)
218219
#define ISCSI_OFMARKER_EN (1 << ISCSI_PARAM_OFMARKER_EN)
220+
#define ISCSI_EXP_STATSN (1 << ISCSI_PARAM_EXP_STATSN)
219221
#define ISCSI_TARGET_NAME (1 << ISCSI_PARAM_TARGET_NAME)
220222
#define ISCSI_TPGT (1 << ISCSI_PARAM_TPGT)
221223
#define ISCSI_PERSISTENT_ADDRESS (1 << ISCSI_PARAM_PERSISTENT_ADDRESS)

0 commit comments

Comments
 (0)