aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/iscsi_tcp.c83
-rw-r--r--drivers/scsi/iscsi_tcp.h2
-rw-r--r--drivers/scsi/libiscsi.c10
-rw-r--r--include/scsi/libiscsi.h8
4 files changed, 38 insertions, 65 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index b6c68be6b866..aa20adc79f02 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -511,13 +511,28 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
511 break; 511 break;
512 case ISCSI_OP_LOGIN_RSP: 512 case ISCSI_OP_LOGIN_RSP:
513 case ISCSI_OP_TEXT_RSP: 513 case ISCSI_OP_TEXT_RSP:
514 case ISCSI_OP_LOGOUT_RSP:
515 case ISCSI_OP_NOOP_IN:
516 case ISCSI_OP_REJECT: 514 case ISCSI_OP_REJECT:
517 case ISCSI_OP_ASYNC_EVENT: 515 case ISCSI_OP_ASYNC_EVENT:
516 /*
517 * It is possible that we could get a PDU with a buffer larger
518 * than 8K, but there are no targets that currently do this.
519 * For now we fail until we find a vendor that needs it
520 */
521 if (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH <
522 tcp_conn->in.datalen) {
523 printk(KERN_ERR "iscsi_tcp: received buffer of len %u "
524 "but conn buffer is only %u (opcode %0x)\n",
525 tcp_conn->in.datalen,
526 DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, opcode);
527 rc = ISCSI_ERR_PROTO;
528 break;
529 }
530
518 if (tcp_conn->in.datalen) 531 if (tcp_conn->in.datalen)
519 goto copy_hdr; 532 goto copy_hdr;
520 /* fall through */ 533 /* fall through */
534 case ISCSI_OP_LOGOUT_RSP:
535 case ISCSI_OP_NOOP_IN:
521 case ISCSI_OP_SCSI_TMFUNC_RSP: 536 case ISCSI_OP_SCSI_TMFUNC_RSP:
522 rc = iscsi_complete_pdu(conn, hdr, NULL, 0); 537 rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
523 break; 538 break;
@@ -625,9 +640,9 @@ iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask,
625 * byte counters. 640 * byte counters.
626 **/ 641 **/
627static inline int 642static inline int
628iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn) 643iscsi_tcp_copy(struct iscsi_conn *conn)
629{ 644{
630 void *buf = tcp_conn->data; 645 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
631 int buf_size = tcp_conn->in.datalen; 646 int buf_size = tcp_conn->in.datalen;
632 int buf_left = buf_size - tcp_conn->data_copied; 647 int buf_left = buf_size - tcp_conn->data_copied;
633 int size = min(tcp_conn->in.copy, buf_left); 648 int size = min(tcp_conn->in.copy, buf_left);
@@ -638,7 +653,7 @@ iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn)
638 BUG_ON(size <= 0); 653 BUG_ON(size <= 0);
639 654
640 rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, 655 rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset,
641 (char*)buf + tcp_conn->data_copied, size); 656 (char*)conn->data + tcp_conn->data_copied, size);
642 BUG_ON(rc); 657 BUG_ON(rc);
643 658
644 tcp_conn->in.offset += size; 659 tcp_conn->in.offset += size;
@@ -785,22 +800,21 @@ iscsi_data_recv(struct iscsi_conn *conn)
785 spin_unlock(&conn->session->lock); 800 spin_unlock(&conn->session->lock);
786 case ISCSI_OP_TEXT_RSP: 801 case ISCSI_OP_TEXT_RSP:
787 case ISCSI_OP_LOGIN_RSP: 802 case ISCSI_OP_LOGIN_RSP:
788 case ISCSI_OP_NOOP_IN:
789 case ISCSI_OP_ASYNC_EVENT: 803 case ISCSI_OP_ASYNC_EVENT:
790 case ISCSI_OP_REJECT: 804 case ISCSI_OP_REJECT:
791 /* 805 /*
792 * Collect data segment to the connection's data 806 * Collect data segment to the connection's data
793 * placeholder 807 * placeholder
794 */ 808 */
795 if (iscsi_tcp_copy(tcp_conn)) { 809 if (iscsi_tcp_copy(conn)) {
796 rc = -EAGAIN; 810 rc = -EAGAIN;
797 goto exit; 811 goto exit;
798 } 812 }
799 813
800 rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, tcp_conn->data, 814 rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, conn->data,
801 tcp_conn->in.datalen); 815 tcp_conn->in.datalen);
802 if (!rc && conn->datadgst_en && opcode != ISCSI_OP_LOGIN_RSP) 816 if (!rc && conn->datadgst_en && opcode != ISCSI_OP_LOGIN_RSP)
803 iscsi_recv_digest_update(tcp_conn, tcp_conn->data, 817 iscsi_recv_digest_update(tcp_conn, conn->data,
804 tcp_conn->in.datalen); 818 tcp_conn->in.datalen);
805 break; 819 break;
806 default: 820 default:
@@ -1911,21 +1925,9 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
1911 tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; 1925 tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
1912 /* initial operational parameters */ 1926 /* initial operational parameters */
1913 tcp_conn->hdr_size = sizeof(struct iscsi_hdr); 1927 tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
1914 tcp_conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
1915
1916 /* allocate initial PDU receive place holder */
1917 if (tcp_conn->data_size <= PAGE_SIZE)
1918 tcp_conn->data = kmalloc(tcp_conn->data_size, GFP_KERNEL);
1919 else
1920 tcp_conn->data = (void*)__get_free_pages(GFP_KERNEL,
1921 get_order(tcp_conn->data_size));
1922 if (!tcp_conn->data)
1923 goto max_recv_dlenght_alloc_fail;
1924 1928
1925 return cls_conn; 1929 return cls_conn;
1926 1930
1927max_recv_dlenght_alloc_fail:
1928 kfree(tcp_conn);
1929tcp_conn_alloc_fail: 1931tcp_conn_alloc_fail:
1930 iscsi_conn_teardown(cls_conn); 1932 iscsi_conn_teardown(cls_conn);
1931 return NULL; 1933 return NULL;
@@ -1973,12 +1975,6 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
1973 crypto_free_tfm(tcp_conn->data_rx_tfm); 1975 crypto_free_tfm(tcp_conn->data_rx_tfm);
1974 } 1976 }
1975 1977
1976 /* free conn->data, size = MaxRecvDataSegmentLength */
1977 if (tcp_conn->data_size <= PAGE_SIZE)
1978 kfree(tcp_conn->data);
1979 else
1980 free_pages((unsigned long)tcp_conn->data,
1981 get_order(tcp_conn->data_size));
1982 kfree(tcp_conn); 1978 kfree(tcp_conn);
1983} 1979}
1984 1980
@@ -2131,39 +2127,6 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
2131 int value; 2127 int value;
2132 2128
2133 switch(param) { 2129 switch(param) {
2134 case ISCSI_PARAM_MAX_RECV_DLENGTH: {
2135 char *saveptr = tcp_conn->data;
2136 gfp_t flags = GFP_KERNEL;
2137
2138 sscanf(buf, "%d", &value);
2139 if (tcp_conn->data_size >= value) {
2140 iscsi_set_param(cls_conn, param, buf, buflen);
2141 break;
2142 }
2143
2144 spin_lock_bh(&session->lock);
2145 if (conn->stop_stage == STOP_CONN_RECOVER)
2146 flags = GFP_ATOMIC;
2147 spin_unlock_bh(&session->lock);
2148
2149 if (value <= PAGE_SIZE)
2150 tcp_conn->data = kmalloc(value, flags);
2151 else
2152 tcp_conn->data = (void*)__get_free_pages(flags,
2153 get_order(value));
2154 if (tcp_conn->data == NULL) {
2155 tcp_conn->data = saveptr;
2156 return -ENOMEM;
2157 }
2158 if (tcp_conn->data_size <= PAGE_SIZE)
2159 kfree(saveptr);
2160 else
2161 free_pages((unsigned long)saveptr,
2162 get_order(tcp_conn->data_size));
2163 iscsi_set_param(cls_conn, param, buf, buflen);
2164 tcp_conn->data_size = value;
2165 break;
2166 }
2167 case ISCSI_PARAM_HDRDGST_EN: 2130 case ISCSI_PARAM_HDRDGST_EN:
2168 iscsi_set_param(cls_conn, param, buf, buflen); 2131 iscsi_set_param(cls_conn, param, buf, buflen);
2169 tcp_conn->hdr_size = sizeof(struct iscsi_hdr); 2132 tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index 808302832e68..6a4ee704e46e 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -78,8 +78,6 @@ struct iscsi_tcp_conn {
78 char hdrext[4*sizeof(__u16) + 78 char hdrext[4*sizeof(__u16) +
79 sizeof(__u32)]; 79 sizeof(__u32)];
80 int data_copied; 80 int data_copied;
81 char *data; /* data placeholder */
82 int data_size; /* actual recv_dlength */
83 int stop_stage; /* conn_stop() flag: * 81 int stop_stage; /* conn_stop() flag: *
84 * stop to recover, * 82 * stop to recover, *
85 * stop to terminate */ 83 * stop to terminate */
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index c989bc6180b3..03b3dee49009 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -360,6 +360,10 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
360 360
361 switch(opcode) { 361 switch(opcode) {
362 case ISCSI_OP_LOGOUT_RSP: 362 case ISCSI_OP_LOGOUT_RSP:
363 if (datalen) {
364 rc = ISCSI_ERR_PROTO;
365 break;
366 }
363 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; 367 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
364 /* fall through */ 368 /* fall through */
365 case ISCSI_OP_LOGIN_RSP: 369 case ISCSI_OP_LOGIN_RSP:
@@ -383,7 +387,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
383 iscsi_tmf_rsp(conn, hdr); 387 iscsi_tmf_rsp(conn, hdr);
384 break; 388 break;
385 case ISCSI_OP_NOOP_IN: 389 case ISCSI_OP_NOOP_IN:
386 if (hdr->ttt != ISCSI_RESERVED_TAG) { 390 if (hdr->ttt != ISCSI_RESERVED_TAG || datalen) {
387 rc = ISCSI_ERR_PROTO; 391 rc = ISCSI_ERR_PROTO;
388 break; 392 break;
389 } 393 }
@@ -1405,7 +1409,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
1405 data = kmalloc(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL); 1409 data = kmalloc(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL);
1406 if (!data) 1410 if (!data)
1407 goto login_mtask_data_alloc_fail; 1411 goto login_mtask_data_alloc_fail;
1408 conn->login_mtask->data = data; 1412 conn->login_mtask->data = conn->data = data;
1409 1413
1410 init_timer(&conn->tmabort_timer); 1414 init_timer(&conn->tmabort_timer);
1411 mutex_init(&conn->xmitmutex); 1415 mutex_init(&conn->xmitmutex);
@@ -1477,7 +1481,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1477 } 1481 }
1478 1482
1479 spin_lock_bh(&session->lock); 1483 spin_lock_bh(&session->lock);
1480 kfree(conn->login_mtask->data); 1484 kfree(conn->data);
1481 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, 1485 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
1482 sizeof(void*)); 1486 sizeof(void*));
1483 list_del(&conn->item); 1487 list_del(&conn->item);
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 3f69f7e58f89..41904f611d12 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -135,6 +135,14 @@ struct iscsi_conn {
135 int id; /* CID */ 135 int id; /* CID */
136 struct list_head item; /* maintains list of conns */ 136 struct list_head item; /* maintains list of conns */
137 int c_stage; /* connection state */ 137 int c_stage; /* connection state */
138 /*
139 * Preallocated buffer for pdus that have data but do not
140 * originate from scsi-ml. We never have two pdus using the
141 * buffer at the same time. It is only allocated to
142 * the default max recv size because the pdus we support
143 * should always fit in this buffer
144 */
145 char *data;
138 struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */ 146 struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */
139 struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */ 147 struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */
140 struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ 148 struct iscsi_cmd_task *ctask; /* xmit ctask in progress */