Commit 0af967f5 authored by Mike Christie's avatar Mike Christie Committed by James Bottomley

[SCSI] libiscsi, iscsi_tcp, iser: add session cmds array accessor

Currently to get a ctask from the session cmd array, you have to
know to use the itt modifier. To make this easier on LLDs and
so in the future we can easilly kill the session array and use
the host shared map instead, this patch adds a nice wrapper
to strip the itt into a session->cmds index and return a ctask.
Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent b40977d9
...@@ -98,7 +98,6 @@ iscsi_iser_recv(struct iscsi_conn *conn, ...@@ -98,7 +98,6 @@ iscsi_iser_recv(struct iscsi_conn *conn,
struct iscsi_hdr *hdr, char *rx_data, int rx_data_len) struct iscsi_hdr *hdr, char *rx_data, int rx_data_len)
{ {
int rc = 0; int rc = 0;
uint32_t ret_itt;
int datalen; int datalen;
int ahslen; int ahslen;
...@@ -114,12 +113,7 @@ iscsi_iser_recv(struct iscsi_conn *conn, ...@@ -114,12 +113,7 @@ iscsi_iser_recv(struct iscsi_conn *conn,
/* read AHS */ /* read AHS */
ahslen = hdr->hlength * 4; ahslen = hdr->hlength * 4;
/* verify itt (itt encoding: age+cid+itt) */
rc = iscsi_verify_itt(conn, hdr, &ret_itt);
if (!rc)
rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len); rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);
if (rc && rc != ISCSI_ERR_NO_SCSI_CMD) if (rc && rc != ISCSI_ERR_NO_SCSI_CMD)
goto error; goto error;
......
...@@ -537,13 +537,11 @@ void iser_rcv_completion(struct iser_desc *rx_desc, ...@@ -537,13 +537,11 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
{ {
struct iser_dto *dto = &rx_desc->dto; struct iser_dto *dto = &rx_desc->dto;
struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn; struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
struct iscsi_session *session = conn->iscsi_conn->session;
struct iscsi_cmd_task *ctask; struct iscsi_cmd_task *ctask;
struct iscsi_iser_cmd_task *iser_ctask; struct iscsi_iser_cmd_task *iser_ctask;
struct iscsi_hdr *hdr; struct iscsi_hdr *hdr;
char *rx_data = NULL; char *rx_data = NULL;
int rx_data_len = 0; int rx_data_len = 0;
unsigned int itt;
unsigned char opcode; unsigned char opcode;
hdr = &rx_desc->iscsi_header; hdr = &rx_desc->iscsi_header;
...@@ -559,19 +557,18 @@ void iser_rcv_completion(struct iser_desc *rx_desc, ...@@ -559,19 +557,18 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
opcode = hdr->opcode & ISCSI_OPCODE_MASK; opcode = hdr->opcode & ISCSI_OPCODE_MASK;
if (opcode == ISCSI_OP_SCSI_CMD_RSP) { if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
itt = get_itt(hdr->itt); /* mask out cid and age bits */ ctask = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
if (!(itt < session->cmds_max)) if (!ctask)
iser_err("itt can't be matched to task!!! " iser_err("itt can't be matched to task!!! "
"conn %p opcode %d cmds_max %d itt %d\n", "conn %p opcode %d itt %d\n",
conn->iscsi_conn,opcode,session->cmds_max,itt); conn->iscsi_conn, opcode, hdr->itt);
/* use the mapping given with the cmds array indexed by itt */ else {
ctask = (struct iscsi_cmd_task *)session->cmds[itt];
iser_ctask = ctask->dd_data; iser_ctask = ctask->dd_data;
iser_dbg("itt %d ctask %p\n",itt,ctask); iser_dbg("itt %d ctask %p\n",hdr->itt, ctask);
iser_ctask->status = ISER_TASK_STATUS_COMPLETED; iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
iser_ctask_rdma_finalize(iser_ctask); iser_ctask_rdma_finalize(iser_ctask);
} }
}
iser_dto_buffs_release(dto); iser_dto_buffs_release(dto);
iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len); iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);
......
...@@ -740,7 +740,6 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) ...@@ -740,7 +740,6 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
struct iscsi_session *session = conn->session; struct iscsi_session *session = conn->session;
struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct iscsi_cmd_task *ctask; struct iscsi_cmd_task *ctask;
uint32_t itt;
/* verify PDU length */ /* verify PDU length */
tcp_conn->in.datalen = ntoh24(hdr->dlength); tcp_conn->in.datalen = ntoh24(hdr->dlength);
...@@ -758,7 +757,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) ...@@ -758,7 +757,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
opcode = hdr->opcode & ISCSI_OPCODE_MASK; opcode = hdr->opcode & ISCSI_OPCODE_MASK;
/* verify itt (itt encoding: age+cid+itt) */ /* verify itt (itt encoding: age+cid+itt) */
rc = iscsi_verify_itt(conn, hdr, &itt); rc = iscsi_verify_itt(conn, hdr->itt);
if (rc) if (rc)
return rc; return rc;
...@@ -767,7 +766,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) ...@@ -767,7 +766,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
switch(opcode) { switch(opcode) {
case ISCSI_OP_SCSI_DATA_IN: case ISCSI_OP_SCSI_DATA_IN:
ctask = session->cmds[itt]; ctask = iscsi_itt_to_ctask(conn, hdr->itt);
if (!ctask)
return ISCSI_ERR_BAD_ITT;
spin_lock(&conn->session->lock); spin_lock(&conn->session->lock);
rc = iscsi_data_rsp(conn, ctask); rc = iscsi_data_rsp(conn, ctask);
spin_unlock(&conn->session->lock); spin_unlock(&conn->session->lock);
...@@ -810,7 +812,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) ...@@ -810,7 +812,10 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
rc = iscsi_complete_pdu(conn, hdr, NULL, 0); rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
break; break;
case ISCSI_OP_R2T: case ISCSI_OP_R2T:
ctask = session->cmds[itt]; ctask = iscsi_itt_to_ctask(conn, hdr->itt);
if (!ctask)
return ISCSI_ERR_BAD_ITT;
if (ahslen) if (ahslen)
rc = ISCSI_ERR_AHSLEN; rc = ISCSI_ERR_AHSLEN;
else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) { else if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
......
...@@ -640,6 +640,10 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, ...@@ -640,6 +640,10 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
uint32_t itt; uint32_t itt;
conn->last_recv = jiffies; conn->last_recv = jiffies;
rc = iscsi_verify_itt(conn, hdr->itt);
if (rc)
return rc;
if (hdr->itt != RESERVED_ITT) if (hdr->itt != RESERVED_ITT)
itt = get_itt(hdr->itt); itt = get_itt(hdr->itt);
else else
...@@ -776,28 +780,23 @@ int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, ...@@ -776,28 +780,23 @@ int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
} }
EXPORT_SYMBOL_GPL(iscsi_complete_pdu); EXPORT_SYMBOL_GPL(iscsi_complete_pdu);
/* verify itt (itt encoding: age+cid+itt) */ int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt)
int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
uint32_t *ret_itt)
{ {
struct iscsi_session *session = conn->session; struct iscsi_session *session = conn->session;
struct iscsi_cmd_task *ctask; struct iscsi_cmd_task *ctask;
uint32_t itt;
if (hdr->itt != RESERVED_ITT) { if (itt == RESERVED_ITT)
if (((__force u32)hdr->itt & ISCSI_AGE_MASK) != return 0;
if (((__force u32)itt & ISCSI_AGE_MASK) !=
(session->age << ISCSI_AGE_SHIFT)) { (session->age << ISCSI_AGE_SHIFT)) {
iscsi_conn_printk(KERN_ERR, conn, iscsi_conn_printk(KERN_ERR, conn,
"received itt %x expected session " "received itt %x expected session age (%x)\n",
"age (%x)\n", (__force u32)hdr->itt, (__force u32)itt,
session->age & ISCSI_AGE_MASK); session->age & ISCSI_AGE_MASK);
return ISCSI_ERR_BAD_ITT; return ISCSI_ERR_BAD_ITT;
} }
itt = get_itt(hdr->itt);
} else
itt = ~0U;
if (itt < session->cmds_max) { if (itt < session->cmds_max) {
ctask = session->cmds[itt]; ctask = session->cmds[itt];
...@@ -817,11 +816,38 @@ int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr, ...@@ -817,11 +816,38 @@ int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
} }
} }
*ret_itt = itt;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(iscsi_verify_itt); EXPORT_SYMBOL_GPL(iscsi_verify_itt);
struct iscsi_cmd_task *
iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)
{
struct iscsi_session *session = conn->session;
struct iscsi_cmd_task *ctask;
uint32_t i;
if (iscsi_verify_itt(conn, itt))
return NULL;
if (itt == RESERVED_ITT)
return NULL;
i = get_itt(itt);
if (i >= session->cmds_max)
return NULL;
ctask = session->cmds[i];
if (!ctask->sc)
return NULL;
if (ctask->sc->SCp.phase != session->age)
return NULL;
return ctask;
}
EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask);
void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
{ {
struct iscsi_session *session = conn->session; struct iscsi_session *session = conn->session;
......
...@@ -385,8 +385,8 @@ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, ...@@ -385,8 +385,8 @@ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
char *, uint32_t); char *, uint32_t);
extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
char *, int); char *, int);
extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *, extern int iscsi_verify_itt(struct iscsi_conn *, itt_t);
uint32_t *); extern struct iscsi_cmd_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask);
extern void iscsi_free_mgmt_task(struct iscsi_conn *conn, extern void iscsi_free_mgmt_task(struct iscsi_conn *conn,
struct iscsi_mgmt_task *mtask); struct iscsi_mgmt_task *mtask);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment