diff options
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 209 |
1 files changed, 79 insertions, 130 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 848fb2aa4ca3..058f094f945a 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -43,13 +43,10 @@ | |||
43 | 43 | ||
44 | #include "iscsi_tcp.h" | 44 | #include "iscsi_tcp.h" |
45 | 45 | ||
46 | #define ISCSI_TCP_VERSION "1.0-595" | ||
47 | |||
48 | MODULE_AUTHOR("Dmitry Yusupov <dmitry_yus@yahoo.com>, " | 46 | MODULE_AUTHOR("Dmitry Yusupov <dmitry_yus@yahoo.com>, " |
49 | "Alex Aizman <itn780@yahoo.com>"); | 47 | "Alex Aizman <itn780@yahoo.com>"); |
50 | MODULE_DESCRIPTION("iSCSI/TCP data-path"); | 48 | MODULE_DESCRIPTION("iSCSI/TCP data-path"); |
51 | MODULE_LICENSE("GPL"); | 49 | MODULE_LICENSE("GPL"); |
52 | MODULE_VERSION(ISCSI_TCP_VERSION); | ||
53 | /* #define DEBUG_TCP */ | 50 | /* #define DEBUG_TCP */ |
54 | #define DEBUG_ASSERT | 51 | #define DEBUG_ASSERT |
55 | 52 | ||
@@ -185,11 +182,19 @@ iscsi_hdr_extract(struct iscsi_tcp_conn *tcp_conn) | |||
185 | * must be called with session lock | 182 | * must be called with session lock |
186 | */ | 183 | */ |
187 | static void | 184 | static void |
188 | __iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | 185 | iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) |
189 | { | 186 | { |
190 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 187 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
188 | struct iscsi_r2t_info *r2t; | ||
191 | struct scsi_cmnd *sc; | 189 | struct scsi_cmnd *sc; |
192 | 190 | ||
191 | /* flush ctask's r2t queues */ | ||
192 | while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) { | ||
193 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, | ||
194 | sizeof(void*)); | ||
195 | debug_scsi("iscsi_tcp_cleanup_ctask pending r2t dropped\n"); | ||
196 | } | ||
197 | |||
193 | sc = ctask->sc; | 198 | sc = ctask->sc; |
194 | if (unlikely(!sc)) | 199 | if (unlikely(!sc)) |
195 | return; | 200 | return; |
@@ -374,6 +379,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
374 | spin_unlock(&session->lock); | 379 | spin_unlock(&session->lock); |
375 | return 0; | 380 | return 0; |
376 | } | 381 | } |
382 | |||
377 | rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); | 383 | rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); |
378 | BUG_ON(!rc); | 384 | BUG_ON(!rc); |
379 | 385 | ||
@@ -399,7 +405,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
399 | tcp_ctask->exp_r2tsn = r2tsn + 1; | 405 | tcp_ctask->exp_r2tsn = r2tsn + 1; |
400 | tcp_ctask->xmstate |= XMSTATE_SOL_HDR; | 406 | tcp_ctask->xmstate |= XMSTATE_SOL_HDR; |
401 | __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); | 407 | __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); |
402 | __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); | 408 | list_move_tail(&ctask->running, &conn->xmitqueue); |
403 | 409 | ||
404 | scsi_queue_work(session->host, &conn->xmitwork); | 410 | scsi_queue_work(session->host, &conn->xmitwork); |
405 | conn->r2t_pdus_cnt++; | 411 | conn->r2t_pdus_cnt++; |
@@ -477,6 +483,8 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn) | |||
477 | case ISCSI_OP_SCSI_DATA_IN: | 483 | case ISCSI_OP_SCSI_DATA_IN: |
478 | tcp_conn->in.ctask = session->cmds[itt]; | 484 | tcp_conn->in.ctask = session->cmds[itt]; |
479 | rc = iscsi_data_rsp(conn, tcp_conn->in.ctask); | 485 | rc = iscsi_data_rsp(conn, tcp_conn->in.ctask); |
486 | if (rc) | ||
487 | return rc; | ||
480 | /* fall through */ | 488 | /* fall through */ |
481 | case ISCSI_OP_SCSI_CMD_RSP: | 489 | case ISCSI_OP_SCSI_CMD_RSP: |
482 | tcp_conn->in.ctask = session->cmds[itt]; | 490 | tcp_conn->in.ctask = session->cmds[itt]; |
@@ -484,7 +492,7 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn) | |||
484 | goto copy_hdr; | 492 | goto copy_hdr; |
485 | 493 | ||
486 | spin_lock(&session->lock); | 494 | spin_lock(&session->lock); |
487 | __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); | 495 | iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask); |
488 | rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); | 496 | rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); |
489 | spin_unlock(&session->lock); | 497 | spin_unlock(&session->lock); |
490 | break; | 498 | break; |
@@ -500,13 +508,28 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn) | |||
500 | break; | 508 | break; |
501 | case ISCSI_OP_LOGIN_RSP: | 509 | case ISCSI_OP_LOGIN_RSP: |
502 | case ISCSI_OP_TEXT_RSP: | 510 | case ISCSI_OP_TEXT_RSP: |
503 | case ISCSI_OP_LOGOUT_RSP: | ||
504 | case ISCSI_OP_NOOP_IN: | ||
505 | case ISCSI_OP_REJECT: | 511 | case ISCSI_OP_REJECT: |
506 | case ISCSI_OP_ASYNC_EVENT: | 512 | case ISCSI_OP_ASYNC_EVENT: |
513 | /* | ||
514 | * It is possible that we could get a PDU with a buffer larger | ||
515 | * than 8K, but there are no targets that currently do this. | ||
516 | * For now we fail until we find a vendor that needs it | ||
517 | */ | ||
518 | if (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH < | ||
519 | tcp_conn->in.datalen) { | ||
520 | printk(KERN_ERR "iscsi_tcp: received buffer of len %u " | ||
521 | "but conn buffer is only %u (opcode %0x)\n", | ||
522 | tcp_conn->in.datalen, | ||
523 | DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, opcode); | ||
524 | rc = ISCSI_ERR_PROTO; | ||
525 | break; | ||
526 | } | ||
527 | |||
507 | if (tcp_conn->in.datalen) | 528 | if (tcp_conn->in.datalen) |
508 | goto copy_hdr; | 529 | goto copy_hdr; |
509 | /* fall through */ | 530 | /* fall through */ |
531 | case ISCSI_OP_LOGOUT_RSP: | ||
532 | case ISCSI_OP_NOOP_IN: | ||
510 | case ISCSI_OP_SCSI_TMFUNC_RSP: | 533 | case ISCSI_OP_SCSI_TMFUNC_RSP: |
511 | rc = iscsi_complete_pdu(conn, hdr, NULL, 0); | 534 | rc = iscsi_complete_pdu(conn, hdr, NULL, 0); |
512 | break; | 535 | break; |
@@ -523,7 +546,7 @@ copy_hdr: | |||
523 | * skbs to complete the command then we have to copy the header | 546 | * skbs to complete the command then we have to copy the header |
524 | * for later use | 547 | * for later use |
525 | */ | 548 | */ |
526 | if (tcp_conn->in.zero_copy_hdr && tcp_conn->in.copy < | 549 | if (tcp_conn->in.zero_copy_hdr && tcp_conn->in.copy <= |
527 | (tcp_conn->in.datalen + tcp_conn->in.padding + | 550 | (tcp_conn->in.datalen + tcp_conn->in.padding + |
528 | (conn->datadgst_en ? 4 : 0))) { | 551 | (conn->datadgst_en ? 4 : 0))) { |
529 | debug_tcp("Copying header for later use. in.copy %d in.datalen" | 552 | debug_tcp("Copying header for later use. in.copy %d in.datalen" |
@@ -614,9 +637,9 @@ iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask, | |||
614 | * byte counters. | 637 | * byte counters. |
615 | **/ | 638 | **/ |
616 | static inline int | 639 | static inline int |
617 | iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn) | 640 | iscsi_tcp_copy(struct iscsi_conn *conn) |
618 | { | 641 | { |
619 | void *buf = tcp_conn->data; | 642 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
620 | int buf_size = tcp_conn->in.datalen; | 643 | int buf_size = tcp_conn->in.datalen; |
621 | int buf_left = buf_size - tcp_conn->data_copied; | 644 | int buf_left = buf_size - tcp_conn->data_copied; |
622 | int size = min(tcp_conn->in.copy, buf_left); | 645 | int size = min(tcp_conn->in.copy, buf_left); |
@@ -627,7 +650,7 @@ iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn) | |||
627 | BUG_ON(size <= 0); | 650 | BUG_ON(size <= 0); |
628 | 651 | ||
629 | rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, | 652 | rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, |
630 | (char*)buf + tcp_conn->data_copied, size); | 653 | (char*)conn->data + tcp_conn->data_copied, size); |
631 | BUG_ON(rc); | 654 | BUG_ON(rc); |
632 | 655 | ||
633 | tcp_conn->in.offset += size; | 656 | tcp_conn->in.offset += size; |
@@ -745,10 +768,11 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) | |||
745 | done: | 768 | done: |
746 | /* check for non-exceptional status */ | 769 | /* check for non-exceptional status */ |
747 | if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) { | 770 | if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) { |
748 | debug_scsi("done [sc %lx res %d itt 0x%x]\n", | 771 | debug_scsi("done [sc %lx res %d itt 0x%x flags 0x%x]\n", |
749 | (long)sc, sc->result, ctask->itt); | 772 | (long)sc, sc->result, ctask->itt, |
773 | tcp_conn->in.hdr->flags); | ||
750 | spin_lock(&conn->session->lock); | 774 | spin_lock(&conn->session->lock); |
751 | __iscsi_ctask_cleanup(conn, ctask); | 775 | iscsi_tcp_cleanup_ctask(conn, ctask); |
752 | __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0); | 776 | __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0); |
753 | spin_unlock(&conn->session->lock); | 777 | spin_unlock(&conn->session->lock); |
754 | } | 778 | } |
@@ -769,26 +793,25 @@ iscsi_data_recv(struct iscsi_conn *conn) | |||
769 | break; | 793 | break; |
770 | case ISCSI_OP_SCSI_CMD_RSP: | 794 | case ISCSI_OP_SCSI_CMD_RSP: |
771 | spin_lock(&conn->session->lock); | 795 | spin_lock(&conn->session->lock); |
772 | __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); | 796 | iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask); |
773 | spin_unlock(&conn->session->lock); | 797 | spin_unlock(&conn->session->lock); |
774 | case ISCSI_OP_TEXT_RSP: | 798 | case ISCSI_OP_TEXT_RSP: |
775 | case ISCSI_OP_LOGIN_RSP: | 799 | case ISCSI_OP_LOGIN_RSP: |
776 | case ISCSI_OP_NOOP_IN: | ||
777 | case ISCSI_OP_ASYNC_EVENT: | 800 | case ISCSI_OP_ASYNC_EVENT: |
778 | case ISCSI_OP_REJECT: | 801 | case ISCSI_OP_REJECT: |
779 | /* | 802 | /* |
780 | * Collect data segment to the connection's data | 803 | * Collect data segment to the connection's data |
781 | * placeholder | 804 | * placeholder |
782 | */ | 805 | */ |
783 | if (iscsi_tcp_copy(tcp_conn)) { | 806 | if (iscsi_tcp_copy(conn)) { |
784 | rc = -EAGAIN; | 807 | rc = -EAGAIN; |
785 | goto exit; | 808 | goto exit; |
786 | } | 809 | } |
787 | 810 | ||
788 | rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, tcp_conn->data, | 811 | rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, conn->data, |
789 | tcp_conn->in.datalen); | 812 | tcp_conn->in.datalen); |
790 | if (!rc && conn->datadgst_en && opcode != ISCSI_OP_LOGIN_RSP) | 813 | if (!rc && conn->datadgst_en && opcode != ISCSI_OP_LOGIN_RSP) |
791 | iscsi_recv_digest_update(tcp_conn, tcp_conn->data, | 814 | iscsi_recv_digest_update(tcp_conn, conn->data, |
792 | tcp_conn->in.datalen); | 815 | tcp_conn->in.datalen); |
793 | break; | 816 | break; |
794 | default: | 817 | default: |
@@ -843,7 +866,7 @@ more: | |||
843 | if (rc == -EAGAIN) | 866 | if (rc == -EAGAIN) |
844 | goto nomore; | 867 | goto nomore; |
845 | else { | 868 | else { |
846 | iscsi_conn_failure(conn, rc); | 869 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); |
847 | return 0; | 870 | return 0; |
848 | } | 871 | } |
849 | } | 872 | } |
@@ -897,7 +920,7 @@ more: | |||
897 | if (rc) { | 920 | if (rc) { |
898 | if (rc == -EAGAIN) | 921 | if (rc == -EAGAIN) |
899 | goto again; | 922 | goto again; |
900 | iscsi_conn_failure(conn, rc); | 923 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); |
901 | return 0; | 924 | return 0; |
902 | } | 925 | } |
903 | tcp_conn->in.copy -= tcp_conn->in.padding; | 926 | tcp_conn->in.copy -= tcp_conn->in.padding; |
@@ -1028,9 +1051,8 @@ iscsi_conn_set_callbacks(struct iscsi_conn *conn) | |||
1028 | } | 1051 | } |
1029 | 1052 | ||
1030 | static void | 1053 | static void |
1031 | iscsi_conn_restore_callbacks(struct iscsi_conn *conn) | 1054 | iscsi_conn_restore_callbacks(struct iscsi_tcp_conn *tcp_conn) |
1032 | { | 1055 | { |
1033 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | ||
1034 | struct sock *sk = tcp_conn->sock->sk; | 1056 | struct sock *sk = tcp_conn->sock->sk; |
1035 | 1057 | ||
1036 | /* restore socket callbacks, see also: iscsi_conn_set_callbacks() */ | 1058 | /* restore socket callbacks, see also: iscsi_conn_set_callbacks() */ |
@@ -1308,7 +1330,7 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask) | |||
1308 | ctask->imm_count - | 1330 | ctask->imm_count - |
1309 | ctask->unsol_count; | 1331 | ctask->unsol_count; |
1310 | 1332 | ||
1311 | debug_scsi("cmd [itt %x total %d imm %d imm_data %d " | 1333 | debug_scsi("cmd [itt 0x%x total %d imm %d imm_data %d " |
1312 | "r2t_data %d]\n", | 1334 | "r2t_data %d]\n", |
1313 | ctask->itt, ctask->total_length, ctask->imm_count, | 1335 | ctask->itt, ctask->total_length, ctask->imm_count, |
1314 | ctask->unsol_count, tcp_ctask->r2t_data_count); | 1336 | ctask->unsol_count, tcp_ctask->r2t_data_count); |
@@ -1636,7 +1658,7 @@ handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
1636 | } | 1658 | } |
1637 | solicit_again: | 1659 | solicit_again: |
1638 | /* | 1660 | /* |
1639 | * send Data-Out whitnin this R2T sequence. | 1661 | * send Data-Out within this R2T sequence. |
1640 | */ | 1662 | */ |
1641 | if (!r2t->data_count) | 1663 | if (!r2t->data_count) |
1642 | goto data_out_done; | 1664 | goto data_out_done; |
@@ -1731,7 +1753,7 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
1731 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 1753 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
1732 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 1754 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
1733 | struct iscsi_data_task *dtask = tcp_ctask->dtask; | 1755 | struct iscsi_data_task *dtask = tcp_ctask->dtask; |
1734 | int sent, rc; | 1756 | int sent = 0, rc; |
1735 | 1757 | ||
1736 | tcp_ctask->xmstate &= ~XMSTATE_W_PAD; | 1758 | tcp_ctask->xmstate &= ~XMSTATE_W_PAD; |
1737 | iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, | 1759 | iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, |
@@ -1900,27 +1922,32 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) | |||
1900 | tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; | 1922 | tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; |
1901 | /* initial operational parameters */ | 1923 | /* initial operational parameters */ |
1902 | tcp_conn->hdr_size = sizeof(struct iscsi_hdr); | 1924 | tcp_conn->hdr_size = sizeof(struct iscsi_hdr); |
1903 | tcp_conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; | ||
1904 | |||
1905 | /* allocate initial PDU receive place holder */ | ||
1906 | if (tcp_conn->data_size <= PAGE_SIZE) | ||
1907 | tcp_conn->data = kmalloc(tcp_conn->data_size, GFP_KERNEL); | ||
1908 | else | ||
1909 | tcp_conn->data = (void*)__get_free_pages(GFP_KERNEL, | ||
1910 | get_order(tcp_conn->data_size)); | ||
1911 | if (!tcp_conn->data) | ||
1912 | goto max_recv_dlenght_alloc_fail; | ||
1913 | 1925 | ||
1914 | return cls_conn; | 1926 | return cls_conn; |
1915 | 1927 | ||
1916 | max_recv_dlenght_alloc_fail: | ||
1917 | kfree(tcp_conn); | ||
1918 | tcp_conn_alloc_fail: | 1928 | tcp_conn_alloc_fail: |
1919 | iscsi_conn_teardown(cls_conn); | 1929 | iscsi_conn_teardown(cls_conn); |
1920 | return NULL; | 1930 | return NULL; |
1921 | } | 1931 | } |
1922 | 1932 | ||
1923 | static void | 1933 | static void |
1934 | iscsi_tcp_release_conn(struct iscsi_conn *conn) | ||
1935 | { | ||
1936 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | ||
1937 | |||
1938 | if (!tcp_conn->sock) | ||
1939 | return; | ||
1940 | |||
1941 | sock_hold(tcp_conn->sock->sk); | ||
1942 | iscsi_conn_restore_callbacks(tcp_conn); | ||
1943 | sock_put(tcp_conn->sock->sk); | ||
1944 | |||
1945 | sock_release(tcp_conn->sock); | ||
1946 | tcp_conn->sock = NULL; | ||
1947 | conn->recv_lock = NULL; | ||
1948 | } | ||
1949 | |||
1950 | static void | ||
1924 | iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) | 1951 | iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) |
1925 | { | 1952 | { |
1926 | struct iscsi_conn *conn = cls_conn->dd_data; | 1953 | struct iscsi_conn *conn = cls_conn->dd_data; |
@@ -1930,6 +1957,7 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) | |||
1930 | if (conn->hdrdgst_en || conn->datadgst_en) | 1957 | if (conn->hdrdgst_en || conn->datadgst_en) |
1931 | digest = 1; | 1958 | digest = 1; |
1932 | 1959 | ||
1960 | iscsi_tcp_release_conn(conn); | ||
1933 | iscsi_conn_teardown(cls_conn); | 1961 | iscsi_conn_teardown(cls_conn); |
1934 | 1962 | ||
1935 | /* now free tcp_conn */ | 1963 | /* now free tcp_conn */ |
@@ -1944,15 +1972,18 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) | |||
1944 | crypto_free_tfm(tcp_conn->data_rx_tfm); | 1972 | crypto_free_tfm(tcp_conn->data_rx_tfm); |
1945 | } | 1973 | } |
1946 | 1974 | ||
1947 | /* free conn->data, size = MaxRecvDataSegmentLength */ | ||
1948 | if (tcp_conn->data_size <= PAGE_SIZE) | ||
1949 | kfree(tcp_conn->data); | ||
1950 | else | ||
1951 | free_pages((unsigned long)tcp_conn->data, | ||
1952 | get_order(tcp_conn->data_size)); | ||
1953 | kfree(tcp_conn); | 1975 | kfree(tcp_conn); |
1954 | } | 1976 | } |
1955 | 1977 | ||
1978 | static void | ||
1979 | iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) | ||
1980 | { | ||
1981 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
1982 | |||
1983 | iscsi_conn_stop(cls_conn, flag); | ||
1984 | iscsi_tcp_release_conn(conn); | ||
1985 | } | ||
1986 | |||
1956 | static int | 1987 | static int |
1957 | iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, | 1988 | iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, |
1958 | struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, | 1989 | struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, |
@@ -2001,52 +2032,6 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, | |||
2001 | return 0; | 2032 | return 0; |
2002 | } | 2033 | } |
2003 | 2034 | ||
2004 | static void | ||
2005 | iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | ||
2006 | { | ||
2007 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | ||
2008 | struct iscsi_r2t_info *r2t; | ||
2009 | |||
2010 | /* flush ctask's r2t queues */ | ||
2011 | while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) | ||
2012 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, | ||
2013 | sizeof(void*)); | ||
2014 | |||
2015 | __iscsi_ctask_cleanup(conn, ctask); | ||
2016 | } | ||
2017 | |||
2018 | static void | ||
2019 | iscsi_tcp_suspend_conn_rx(struct iscsi_conn *conn) | ||
2020 | { | ||
2021 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | ||
2022 | struct sock *sk; | ||
2023 | |||
2024 | if (!tcp_conn->sock) | ||
2025 | return; | ||
2026 | |||
2027 | sk = tcp_conn->sock->sk; | ||
2028 | write_lock_bh(&sk->sk_callback_lock); | ||
2029 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); | ||
2030 | write_unlock_bh(&sk->sk_callback_lock); | ||
2031 | } | ||
2032 | |||
2033 | static void | ||
2034 | iscsi_tcp_terminate_conn(struct iscsi_conn *conn) | ||
2035 | { | ||
2036 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | ||
2037 | |||
2038 | if (!tcp_conn->sock) | ||
2039 | return; | ||
2040 | |||
2041 | sock_hold(tcp_conn->sock->sk); | ||
2042 | iscsi_conn_restore_callbacks(conn); | ||
2043 | sock_put(tcp_conn->sock->sk); | ||
2044 | |||
2045 | sock_release(tcp_conn->sock); | ||
2046 | tcp_conn->sock = NULL; | ||
2047 | conn->recv_lock = NULL; | ||
2048 | } | ||
2049 | |||
2050 | /* called with host lock */ | 2035 | /* called with host lock */ |
2051 | static void | 2036 | static void |
2052 | iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask, | 2037 | iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask, |
@@ -2057,6 +2042,7 @@ iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask, | |||
2057 | iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr, | 2042 | iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr, |
2058 | sizeof(struct iscsi_hdr)); | 2043 | sizeof(struct iscsi_hdr)); |
2059 | tcp_mtask->xmstate = XMSTATE_IMM_HDR; | 2044 | tcp_mtask->xmstate = XMSTATE_IMM_HDR; |
2045 | tcp_mtask->sent = 0; | ||
2060 | 2046 | ||
2061 | if (mtask->data_count) | 2047 | if (mtask->data_count) |
2062 | iscsi_buf_init_iov(&tcp_mtask->sendbuf, (char*)mtask->data, | 2048 | iscsi_buf_init_iov(&tcp_mtask->sendbuf, (char*)mtask->data, |
@@ -2138,39 +2124,6 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | |||
2138 | int value; | 2124 | int value; |
2139 | 2125 | ||
2140 | switch(param) { | 2126 | switch(param) { |
2141 | case ISCSI_PARAM_MAX_RECV_DLENGTH: { | ||
2142 | char *saveptr = tcp_conn->data; | ||
2143 | gfp_t flags = GFP_KERNEL; | ||
2144 | |||
2145 | sscanf(buf, "%d", &value); | ||
2146 | if (tcp_conn->data_size >= value) { | ||
2147 | iscsi_set_param(cls_conn, param, buf, buflen); | ||
2148 | break; | ||
2149 | } | ||
2150 | |||
2151 | spin_lock_bh(&session->lock); | ||
2152 | if (conn->stop_stage == STOP_CONN_RECOVER) | ||
2153 | flags = GFP_ATOMIC; | ||
2154 | spin_unlock_bh(&session->lock); | ||
2155 | |||
2156 | if (value <= PAGE_SIZE) | ||
2157 | tcp_conn->data = kmalloc(value, flags); | ||
2158 | else | ||
2159 | tcp_conn->data = (void*)__get_free_pages(flags, | ||
2160 | get_order(value)); | ||
2161 | if (tcp_conn->data == NULL) { | ||
2162 | tcp_conn->data = saveptr; | ||
2163 | return -ENOMEM; | ||
2164 | } | ||
2165 | if (tcp_conn->data_size <= PAGE_SIZE) | ||
2166 | kfree(saveptr); | ||
2167 | else | ||
2168 | free_pages((unsigned long)saveptr, | ||
2169 | get_order(tcp_conn->data_size)); | ||
2170 | iscsi_set_param(cls_conn, param, buf, buflen); | ||
2171 | tcp_conn->data_size = value; | ||
2172 | break; | ||
2173 | } | ||
2174 | case ISCSI_PARAM_HDRDGST_EN: | 2127 | case ISCSI_PARAM_HDRDGST_EN: |
2175 | iscsi_set_param(cls_conn, param, buf, buflen); | 2128 | iscsi_set_param(cls_conn, param, buf, buflen); |
2176 | tcp_conn->hdr_size = sizeof(struct iscsi_hdr); | 2129 | tcp_conn->hdr_size = sizeof(struct iscsi_hdr); |
@@ -2361,8 +2314,7 @@ static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session) | |||
2361 | } | 2314 | } |
2362 | 2315 | ||
2363 | static struct scsi_host_template iscsi_sht = { | 2316 | static struct scsi_host_template iscsi_sht = { |
2364 | .name = "iSCSI Initiator over TCP/IP, v" | 2317 | .name = "iSCSI Initiator over TCP/IP", |
2365 | ISCSI_TCP_VERSION, | ||
2366 | .queuecommand = iscsi_queuecommand, | 2318 | .queuecommand = iscsi_queuecommand, |
2367 | .change_queue_depth = iscsi_change_queue_depth, | 2319 | .change_queue_depth = iscsi_change_queue_depth, |
2368 | .can_queue = ISCSI_XMIT_CMDS_MAX - 1, | 2320 | .can_queue = ISCSI_XMIT_CMDS_MAX - 1, |
@@ -2414,10 +2366,7 @@ static struct iscsi_transport iscsi_tcp_transport = { | |||
2414 | .get_conn_param = iscsi_tcp_conn_get_param, | 2366 | .get_conn_param = iscsi_tcp_conn_get_param, |
2415 | .get_session_param = iscsi_session_get_param, | 2367 | .get_session_param = iscsi_session_get_param, |
2416 | .start_conn = iscsi_conn_start, | 2368 | .start_conn = iscsi_conn_start, |
2417 | .stop_conn = iscsi_conn_stop, | 2369 | .stop_conn = iscsi_tcp_conn_stop, |
2418 | /* these are called as part of conn recovery */ | ||
2419 | .suspend_conn_recv = iscsi_tcp_suspend_conn_rx, | ||
2420 | .terminate_conn = iscsi_tcp_terminate_conn, | ||
2421 | /* IO */ | 2370 | /* IO */ |
2422 | .send_pdu = iscsi_conn_send_pdu, | 2371 | .send_pdu = iscsi_conn_send_pdu, |
2423 | .get_stats = iscsi_conn_get_stats, | 2372 | .get_stats = iscsi_conn_get_stats, |