aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-05-02 20:46:47 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-05-10 11:13:21 -0400
commit8d2860b3c3e933304f49171770658c00ed26fd79 (patch)
tree979395449d53d41bd22732a4be1387f9af73a994
parentbe2df72e7ec5fa5e6e1ccccab6cef97ecbb9c191 (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.c9
-rw-r--r--drivers/scsi/libiscsi.c38
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c4
-rw-r--r--include/scsi/iscsi_if.h2
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
417done:
417 return rc; 418 return rc;
418} 419}
419EXPORT_SYMBOL_GPL(__iscsi_complete_pdu); 420EXPORT_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
38struct iscsi_internal { 38struct iscsi_internal {
@@ -1156,6 +1156,7 @@ iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d");
1156iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); 1156iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d");
1157iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d"); 1157iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d");
1158iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d"); 1158iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d");
1159iscsi_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) \
1161static ssize_t \ 1162static 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)