Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 33563
b: refs/heads/master
c: c8dc1e5
h: refs/heads/master
i:
  33561: 57106f7
  33559: da75aa6
v: v3
  • Loading branch information
Mike Christie authored and James Bottomley committed Jul 28, 2006
1 parent 11ad1ee commit aabb09b
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 66 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9aaa2b4621280b6de1ecfb6dd7cd5cbe59fd1264
refs/heads/master: c8dc1e523b0f1e6dd71cdabd8c7d7587c6dc27f9
83 changes: 23 additions & 60 deletions trunk/drivers/scsi/iscsi_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,13 +511,28 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
break;
case ISCSI_OP_LOGIN_RSP:
case ISCSI_OP_TEXT_RSP:
case ISCSI_OP_LOGOUT_RSP:
case ISCSI_OP_NOOP_IN:
case ISCSI_OP_REJECT:
case ISCSI_OP_ASYNC_EVENT:
/*
* It is possible that we could get a PDU with a buffer larger
* than 8K, but there are no targets that currently do this.
* For now we fail until we find a vendor that needs it
*/
if (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH <
tcp_conn->in.datalen) {
printk(KERN_ERR "iscsi_tcp: received buffer of len %u "
"but conn buffer is only %u (opcode %0x)\n",
tcp_conn->in.datalen,
DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, opcode);
rc = ISCSI_ERR_PROTO;
break;
}

if (tcp_conn->in.datalen)
goto copy_hdr;
/* fall through */
case ISCSI_OP_LOGOUT_RSP:
case ISCSI_OP_NOOP_IN:
case ISCSI_OP_SCSI_TMFUNC_RSP:
rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
break;
Expand Down Expand Up @@ -625,9 +640,9 @@ iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask,
* byte counters.
**/
static inline int
iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn)
iscsi_tcp_copy(struct iscsi_conn *conn)
{
void *buf = tcp_conn->data;
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
int buf_size = tcp_conn->in.datalen;
int buf_left = buf_size - tcp_conn->data_copied;
int size = min(tcp_conn->in.copy, buf_left);
Expand All @@ -638,7 +653,7 @@ iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn)
BUG_ON(size <= 0);

rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset,
(char*)buf + tcp_conn->data_copied, size);
(char*)conn->data + tcp_conn->data_copied, size);
BUG_ON(rc);

tcp_conn->in.offset += size;
Expand Down Expand Up @@ -785,22 +800,21 @@ iscsi_data_recv(struct iscsi_conn *conn)
spin_unlock(&conn->session->lock);
case ISCSI_OP_TEXT_RSP:
case ISCSI_OP_LOGIN_RSP:
case ISCSI_OP_NOOP_IN:
case ISCSI_OP_ASYNC_EVENT:
case ISCSI_OP_REJECT:
/*
* Collect data segment to the connection's data
* placeholder
*/
if (iscsi_tcp_copy(tcp_conn)) {
if (iscsi_tcp_copy(conn)) {
rc = -EAGAIN;
goto exit;
}

rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, tcp_conn->data,
rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, conn->data,
tcp_conn->in.datalen);
if (!rc && conn->datadgst_en && opcode != ISCSI_OP_LOGIN_RSP)
iscsi_recv_digest_update(tcp_conn, tcp_conn->data,
iscsi_recv_digest_update(tcp_conn, conn->data,
tcp_conn->in.datalen);
break;
default:
Expand Down Expand Up @@ -1911,21 +1925,9 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
/* initial operational parameters */
tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
tcp_conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;

/* allocate initial PDU receive place holder */
if (tcp_conn->data_size <= PAGE_SIZE)
tcp_conn->data = kmalloc(tcp_conn->data_size, GFP_KERNEL);
else
tcp_conn->data = (void*)__get_free_pages(GFP_KERNEL,
get_order(tcp_conn->data_size));
if (!tcp_conn->data)
goto max_recv_dlenght_alloc_fail;

return cls_conn;

max_recv_dlenght_alloc_fail:
kfree(tcp_conn);
tcp_conn_alloc_fail:
iscsi_conn_teardown(cls_conn);
return NULL;
Expand Down Expand Up @@ -1973,12 +1975,6 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
crypto_free_tfm(tcp_conn->data_rx_tfm);
}

/* free conn->data, size = MaxRecvDataSegmentLength */
if (tcp_conn->data_size <= PAGE_SIZE)
kfree(tcp_conn->data);
else
free_pages((unsigned long)tcp_conn->data,
get_order(tcp_conn->data_size));
kfree(tcp_conn);
}

Expand Down Expand Up @@ -2131,39 +2127,6 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
int value;

switch(param) {
case ISCSI_PARAM_MAX_RECV_DLENGTH: {
char *saveptr = tcp_conn->data;
gfp_t flags = GFP_KERNEL;

sscanf(buf, "%d", &value);
if (tcp_conn->data_size >= value) {
iscsi_set_param(cls_conn, param, buf, buflen);
break;
}

spin_lock_bh(&session->lock);
if (conn->stop_stage == STOP_CONN_RECOVER)
flags = GFP_ATOMIC;
spin_unlock_bh(&session->lock);

if (value <= PAGE_SIZE)
tcp_conn->data = kmalloc(value, flags);
else
tcp_conn->data = (void*)__get_free_pages(flags,
get_order(value));
if (tcp_conn->data == NULL) {
tcp_conn->data = saveptr;
return -ENOMEM;
}
if (tcp_conn->data_size <= PAGE_SIZE)
kfree(saveptr);
else
free_pages((unsigned long)saveptr,
get_order(tcp_conn->data_size));
iscsi_set_param(cls_conn, param, buf, buflen);
tcp_conn->data_size = value;
break;
}
case ISCSI_PARAM_HDRDGST_EN:
iscsi_set_param(cls_conn, param, buf, buflen);
tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
Expand Down
2 changes: 0 additions & 2 deletions trunk/drivers/scsi/iscsi_tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ struct iscsi_tcp_conn {
char hdrext[4*sizeof(__u16) +
sizeof(__u32)];
int data_copied;
char *data; /* data placeholder */
int data_size; /* actual recv_dlength */
int stop_stage; /* conn_stop() flag: *
* stop to recover, *
* stop to terminate */
Expand Down
10 changes: 7 additions & 3 deletions trunk/drivers/scsi/libiscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,10 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,

switch(opcode) {
case ISCSI_OP_LOGOUT_RSP:
if (datalen) {
rc = ISCSI_ERR_PROTO;
break;
}
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
/* fall through */
case ISCSI_OP_LOGIN_RSP:
Expand All @@ -383,7 +387,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
iscsi_tmf_rsp(conn, hdr);
break;
case ISCSI_OP_NOOP_IN:
if (hdr->ttt != ISCSI_RESERVED_TAG) {
if (hdr->ttt != ISCSI_RESERVED_TAG || datalen) {
rc = ISCSI_ERR_PROTO;
break;
}
Expand Down Expand Up @@ -1405,7 +1409,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
data = kmalloc(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL);
if (!data)
goto login_mtask_data_alloc_fail;
conn->login_mtask->data = data;
conn->login_mtask->data = conn->data = data;

init_timer(&conn->tmabort_timer);
mutex_init(&conn->xmitmutex);
Expand Down Expand Up @@ -1477,7 +1481,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
}

spin_lock_bh(&session->lock);
kfree(conn->login_mtask->data);
kfree(conn->data);
__kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
sizeof(void*));
list_del(&conn->item);
Expand Down
8 changes: 8 additions & 0 deletions trunk/include/scsi/libiscsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ struct iscsi_conn {
int id; /* CID */
struct list_head item; /* maintains list of conns */
int c_stage; /* connection state */
/*
* Preallocated buffer for pdus that have data but do not
* originate from scsi-ml. We never have two pdus using the
* buffer at the same time. It is only allocated to
* the default max recv size because the pdus we support
* should always fit in this buffer
*/
char *data;
struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */
struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */
struct iscsi_cmd_task *ctask; /* xmit ctask in progress */
Expand Down

0 comments on commit aabb09b

Please sign in to comment.