diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2006-05-02 20:46:47 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-05-10 11:13:21 -0400 |
commit | 8d2860b3c3e933304f49171770658c00ed26fd79 (patch) | |
tree | 979395449d53d41bd22732a4be1387f9af73a994 | |
parent | be2df72e7ec5fa5e6e1ccccab6cef97ecbb9c191 (diff) |
[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>
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 9 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 38 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 4 | ||||
-rw-r--r-- | include/scsi/iscsi_if.h | 2 |
4 files changed, 32 insertions, 21 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 41f4bb557ea6..c0ce6ab81a9d 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -2298,6 +2298,9 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | |||
2298 | BUG_ON(value); | 2298 | BUG_ON(value); |
2299 | session->ofmarker_en = value; | 2299 | session->ofmarker_en = value; |
2300 | break; | 2300 | break; |
2301 | case ISCSI_PARAM_EXP_STATSN: | ||
2302 | conn->exp_statsn = value; | ||
2303 | break; | ||
2301 | default: | 2304 | default: |
2302 | break; | 2305 | break; |
2303 | } | 2306 | } |
@@ -2381,6 +2384,9 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | |||
2381 | inet = inet_sk(tcp_conn->sock->sk); | 2384 | inet = inet_sk(tcp_conn->sock->sk); |
2382 | *value = be16_to_cpu(inet->dport); | 2385 | *value = be16_to_cpu(inet->dport); |
2383 | mutex_unlock(&conn->xmitmutex); | 2386 | mutex_unlock(&conn->xmitmutex); |
2387 | case ISCSI_PARAM_EXP_STATSN: | ||
2388 | *value = conn->exp_statsn; | ||
2389 | break; | ||
2384 | default: | 2390 | default: |
2385 | return -EINVAL; | 2391 | return -EINVAL; |
2386 | } | 2392 | } |
@@ -2548,7 +2554,8 @@ static struct iscsi_transport iscsi_tcp_transport = { | |||
2548 | ISCSI_DATASEQ_INORDER_EN | | 2554 | ISCSI_DATASEQ_INORDER_EN | |
2549 | ISCSI_ERL | | 2555 | ISCSI_ERL | |
2550 | ISCSI_CONN_PORT | | 2556 | ISCSI_CONN_PORT | |
2551 | ISCSI_CONN_ADDRESS, | 2557 | ISCSI_CONN_ADDRESS | |
2558 | ISCSI_EXP_STATSN, | ||
2552 | .host_template = &iscsi_sht, | 2559 | .host_template = &iscsi_sht, |
2553 | .conndata_size = sizeof(struct iscsi_conn), | 2560 | .conndata_size = sizeof(struct iscsi_conn), |
2554 | .max_conn = 1, | 2561 | .max_conn = 1, |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index a99f2ef44e87..4750d4888100 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -333,15 +333,21 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
333 | debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n", | 333 | debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n", |
334 | opcode, conn->id, mtask->itt, datalen); | 334 | opcode, conn->id, mtask->itt, datalen); |
335 | 335 | ||
336 | rc = iscsi_check_assign_cmdsn(session, | ||
337 | (struct iscsi_nopin*)hdr); | ||
338 | if (rc) | ||
339 | goto done; | ||
340 | |||
336 | switch(opcode) { | 341 | switch(opcode) { |
342 | case ISCSI_OP_LOGOUT_RSP: | ||
343 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | ||
344 | /* fall through */ | ||
337 | case ISCSI_OP_LOGIN_RSP: | 345 | case ISCSI_OP_LOGIN_RSP: |
338 | case ISCSI_OP_TEXT_RSP: | 346 | case ISCSI_OP_TEXT_RSP: |
339 | case ISCSI_OP_LOGOUT_RSP: | 347 | /* |
340 | rc = iscsi_check_assign_cmdsn(session, | 348 | * login related PDU's exp_statsn is handled in |
341 | (struct iscsi_nopin*)hdr); | 349 | * userspace |
342 | if (rc) | 350 | */ |
343 | break; | ||
344 | |||
345 | rc = iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen); | 351 | rc = iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen); |
346 | list_del(&mtask->running); | 352 | list_del(&mtask->running); |
347 | if (conn->login_mtask != mtask) | 353 | if (conn->login_mtask != mtask) |
@@ -349,15 +355,12 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
349 | (void*)&mtask, sizeof(void*)); | 355 | (void*)&mtask, sizeof(void*)); |
350 | break; | 356 | break; |
351 | case ISCSI_OP_SCSI_TMFUNC_RSP: | 357 | case ISCSI_OP_SCSI_TMFUNC_RSP: |
352 | rc = iscsi_check_assign_cmdsn(session, | ||
353 | (struct iscsi_nopin*)hdr); | ||
354 | if (rc) | ||
355 | break; | ||
356 | |||
357 | if (datalen) { | 358 | if (datalen) { |
358 | rc = ISCSI_ERR_PROTO; | 359 | rc = ISCSI_ERR_PROTO; |
359 | break; | 360 | break; |
360 | } | 361 | } |
362 | |||
363 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | ||
361 | conn->tmfrsp_pdus_cnt++; | 364 | conn->tmfrsp_pdus_cnt++; |
362 | if (conn->tmabort_state == TMABORT_INITIAL) { | 365 | if (conn->tmabort_state == TMABORT_INITIAL) { |
363 | conn->tmabort_state = | 366 | conn->tmabort_state = |
@@ -373,10 +376,6 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
373 | rc = ISCSI_ERR_PROTO; | 376 | rc = ISCSI_ERR_PROTO; |
374 | break; | 377 | break; |
375 | } | 378 | } |
376 | rc = iscsi_check_assign_cmdsn(session, | ||
377 | (struct iscsi_nopin*)hdr); | ||
378 | if (rc) | ||
379 | break; | ||
380 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | 379 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; |
381 | 380 | ||
382 | rc = iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen); | 381 | 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, | |||
404 | case ISCSI_OP_REJECT: | 403 | case ISCSI_OP_REJECT: |
405 | /* we need sth like iscsi_reject_rsp()*/ | 404 | /* we need sth like iscsi_reject_rsp()*/ |
406 | case ISCSI_OP_ASYNC_EVENT: | 405 | case ISCSI_OP_ASYNC_EVENT: |
406 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | ||
407 | /* we need sth like iscsi_async_event_rsp() */ | 407 | /* we need sth like iscsi_async_event_rsp() */ |
408 | rc = ISCSI_ERR_BAD_OPCODE; | 408 | rc = ISCSI_ERR_BAD_OPCODE; |
409 | break; | 409 | break; |
@@ -414,6 +414,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
414 | } else | 414 | } else |
415 | rc = ISCSI_ERR_BAD_ITT; | 415 | rc = ISCSI_ERR_BAD_ITT; |
416 | 416 | ||
417 | done: | ||
417 | return rc; | 418 | return rc; |
418 | } | 419 | } |
419 | EXPORT_SYMBOL_GPL(__iscsi_complete_pdu); | 420 | EXPORT_SYMBOL_GPL(__iscsi_complete_pdu); |
@@ -730,6 +731,7 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
730 | BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); | 731 | BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); |
731 | BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); | 732 | BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); |
732 | 733 | ||
734 | nop->exp_statsn = cpu_to_be32(conn->exp_statsn); | ||
733 | if (!__kfifo_get(session->mgmtpool.queue, | 735 | if (!__kfifo_get(session->mgmtpool.queue, |
734 | (void*)&mtask, sizeof(void*))) { | 736 | (void*)&mtask, sizeof(void*))) { |
735 | spin_unlock_bh(&session->lock); | 737 | spin_unlock_bh(&session->lock); |
@@ -738,7 +740,7 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
738 | } | 740 | } |
739 | 741 | ||
740 | /* | 742 | /* |
741 | * pre-format CmdSN and ExpStatSN for outgoing PDU. | 743 | * pre-format CmdSN for outgoing PDU. |
742 | */ | 744 | */ |
743 | if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { | 745 | if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { |
744 | hdr->itt = mtask->itt | (conn->id << ISCSI_CID_SHIFT) | | 746 | 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, | |||
751 | /* do not advance CmdSN */ | 753 | /* do not advance CmdSN */ |
752 | nop->cmdsn = cpu_to_be32(session->cmdsn); | 754 | nop->cmdsn = cpu_to_be32(session->cmdsn); |
753 | 755 | ||
754 | nop->exp_statsn = cpu_to_be32(conn->exp_statsn); | ||
755 | |||
756 | if (data_size) { | 756 | if (data_size) { |
757 | memcpy(mtask->data, data, data_size); | 757 | memcpy(mtask->data, data, data_size); |
758 | mtask->data_count = data_size; | 758 | mtask->data_count = data_size; |
@@ -1647,7 +1647,7 @@ void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) | |||
1647 | case STOP_CONN_RECOVER: | 1647 | case STOP_CONN_RECOVER: |
1648 | case STOP_CONN_TERM: | 1648 | case STOP_CONN_TERM: |
1649 | iscsi_start_session_recovery(session, conn, flag); | 1649 | iscsi_start_session_recovery(session, conn, flag); |
1650 | return; | 1650 | break; |
1651 | case STOP_CONN_SUSPEND: | 1651 | case STOP_CONN_SUSPEND: |
1652 | if (session->tt->suspend_conn_recv) | 1652 | if (session->tt->suspend_conn_recv) |
1653 | session->tt->suspend_conn_recv(conn); | 1653 | session->tt->suspend_conn_recv(conn); |
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 1b96f7c4ce7a..44adafac861f 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <scsi/iscsi_if.h> | 32 | #include <scsi/iscsi_if.h> |
33 | 33 | ||
34 | #define ISCSI_SESSION_ATTRS 11 | 34 | #define ISCSI_SESSION_ATTRS 11 |
35 | #define ISCSI_CONN_ATTRS 10 | 35 | #define ISCSI_CONN_ATTRS 11 |
36 | #define ISCSI_HOST_ATTRS 0 | 36 | #define ISCSI_HOST_ATTRS 0 |
37 | 37 | ||
38 | struct iscsi_internal { | 38 | struct iscsi_internal { |
@@ -1156,6 +1156,7 @@ iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d"); | |||
1156 | iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); | 1156 | iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); |
1157 | iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d"); | 1157 | iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d"); |
1158 | iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d"); | 1158 | iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d"); |
1159 | iscsi_conn_int_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN, "%u"); | ||
1159 | 1160 | ||
1160 | #define iscsi_conn_str_attr_show(param) \ | 1161 | #define iscsi_conn_str_attr_show(param) \ |
1161 | static ssize_t \ | 1162 | static ssize_t \ |
@@ -1406,6 +1407,7 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
1406 | SETUP_CONN_RD_ATTR(ofmarker, ISCSI_OFMARKER_EN); | 1407 | SETUP_CONN_RD_ATTR(ofmarker, ISCSI_OFMARKER_EN); |
1407 | SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); | 1408 | SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); |
1408 | SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); | 1409 | SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); |
1410 | SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); | ||
1409 | 1411 | ||
1410 | if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS) | 1412 | if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS) |
1411 | SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); | 1413 | SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); |
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index feff74e544b7..253797c60095 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h | |||
@@ -188,6 +188,7 @@ enum iscsi_param { | |||
188 | ISCSI_PARAM_ERL, | 188 | ISCSI_PARAM_ERL, |
189 | ISCSI_PARAM_IFMARKER_EN, | 189 | ISCSI_PARAM_IFMARKER_EN, |
190 | ISCSI_PARAM_OFMARKER_EN, | 190 | ISCSI_PARAM_OFMARKER_EN, |
191 | ISCSI_PARAM_EXP_STATSN, | ||
191 | ISCSI_PARAM_TARGET_NAME, | 192 | ISCSI_PARAM_TARGET_NAME, |
192 | ISCSI_PARAM_TPGT, | 193 | ISCSI_PARAM_TPGT, |
193 | ISCSI_PARAM_PERSISTENT_ADDRESS, | 194 | ISCSI_PARAM_PERSISTENT_ADDRESS, |
@@ -216,6 +217,7 @@ enum iscsi_param { | |||
216 | #define ISCSI_ERL (1 << ISCSI_PARAM_ERL) | 217 | #define ISCSI_ERL (1 << ISCSI_PARAM_ERL) |
217 | #define ISCSI_IFMARKER_EN (1 << ISCSI_PARAM_IFMARKER_EN) | 218 | #define ISCSI_IFMARKER_EN (1 << ISCSI_PARAM_IFMARKER_EN) |
218 | #define ISCSI_OFMARKER_EN (1 << ISCSI_PARAM_OFMARKER_EN) | 219 | #define ISCSI_OFMARKER_EN (1 << ISCSI_PARAM_OFMARKER_EN) |
220 | #define ISCSI_EXP_STATSN (1 << ISCSI_PARAM_EXP_STATSN) | ||
219 | #define ISCSI_TARGET_NAME (1 << ISCSI_PARAM_TARGET_NAME) | 221 | #define ISCSI_TARGET_NAME (1 << ISCSI_PARAM_TARGET_NAME) |
220 | #define ISCSI_TPGT (1 << ISCSI_PARAM_TPGT) | 222 | #define ISCSI_TPGT (1 << ISCSI_PARAM_TPGT) |
221 | #define ISCSI_PERSISTENT_ADDRESS (1 << ISCSI_PARAM_PERSISTENT_ADDRESS) | 223 | #define ISCSI_PERSISTENT_ADDRESS (1 << ISCSI_PARAM_PERSISTENT_ADDRESS) |