mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-21 22:21:21 +00:00
[SCSI] iscsi: Some fixes in preparation for bidirectional support - exp_datasn
This patch fixes handling of expected datasn/r2tsn as received from target. It is done according to: T10 rfc3720 section 3.2.2.3. Data Sequencing. . unify expected datasn/r2tsn into one counter . calculate than check expected datasn/r2tsn. On error print a message and fail the request. (TODO use iscsi retransmits) . remove the FIXME ;) . avoid zero length memset Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
8ad5781ae9
commit
d473cc7f15
4 changed files with 15 additions and 11 deletions
|
@ -229,10 +229,13 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
||||||
if (tcp_conn->in.datalen == 0)
|
if (tcp_conn->in.datalen == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (ctask->datasn != datasn)
|
if (tcp_ctask->exp_datasn != datasn) {
|
||||||
|
debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->datasn(%d)\n",
|
||||||
|
__FUNCTION__, tcp_ctask->exp_datasn, datasn);
|
||||||
return ISCSI_ERR_DATASN;
|
return ISCSI_ERR_DATASN;
|
||||||
|
}
|
||||||
|
|
||||||
ctask->datasn++;
|
tcp_ctask->exp_datasn++;
|
||||||
|
|
||||||
tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
|
tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
|
||||||
if (tcp_ctask->data_offset + tcp_conn->in.datalen > ctask->total_length)
|
if (tcp_ctask->data_offset + tcp_conn->in.datalen > ctask->total_length)
|
||||||
|
@ -365,15 +368,16 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
||||||
return ISCSI_ERR_DATALEN;
|
return ISCSI_ERR_DATALEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcp_ctask->exp_r2tsn && tcp_ctask->exp_r2tsn != r2tsn)
|
if (tcp_ctask->exp_datasn != r2tsn){
|
||||||
|
debug_tcp("%s: ctask->exp_datasn(%d) != rhdr->r2tsn(%d)\n",
|
||||||
|
__FUNCTION__, tcp_ctask->exp_datasn, r2tsn);
|
||||||
return ISCSI_ERR_R2TSN;
|
return ISCSI_ERR_R2TSN;
|
||||||
|
}
|
||||||
|
|
||||||
rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
|
rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* FIXME: use R2TSN to detect missing R2T */
|
|
||||||
|
|
||||||
/* fill-in new R2T associated with the task */
|
/* fill-in new R2T associated with the task */
|
||||||
spin_lock(&session->lock);
|
spin_lock(&session->lock);
|
||||||
if (!ctask->sc || ctask->mtask ||
|
if (!ctask->sc || ctask->mtask ||
|
||||||
|
@ -414,7 +418,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
||||||
|
|
||||||
iscsi_solicit_data_init(conn, ctask, r2t);
|
iscsi_solicit_data_init(conn, ctask, r2t);
|
||||||
|
|
||||||
tcp_ctask->exp_r2tsn = r2tsn + 1;
|
tcp_ctask->exp_datasn = r2tsn + 1;
|
||||||
__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
|
__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
|
||||||
tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
|
tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
|
||||||
list_move_tail(&ctask->running, &conn->xmitqueue);
|
list_move_tail(&ctask->running, &conn->xmitqueue);
|
||||||
|
@ -1284,10 +1288,10 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
|
||||||
|
|
||||||
tcp_ctask->sent = 0;
|
tcp_ctask->sent = 0;
|
||||||
tcp_ctask->sg_count = 0;
|
tcp_ctask->sg_count = 0;
|
||||||
|
tcp_ctask->exp_datasn = 0;
|
||||||
|
|
||||||
if (sc->sc_data_direction == DMA_TO_DEVICE) {
|
if (sc->sc_data_direction == DMA_TO_DEVICE) {
|
||||||
tcp_ctask->xmstate = XMSTATE_W_HDR;
|
tcp_ctask->xmstate = XMSTATE_W_HDR;
|
||||||
tcp_ctask->exp_r2tsn = 0;
|
|
||||||
BUG_ON(ctask->total_length == 0);
|
BUG_ON(ctask->total_length == 0);
|
||||||
|
|
||||||
if (sc->use_sg) {
|
if (sc->use_sg) {
|
||||||
|
|
|
@ -152,7 +152,7 @@ struct iscsi_tcp_cmd_task {
|
||||||
struct scatterlist *sg; /* per-cmd SG list */
|
struct scatterlist *sg; /* per-cmd SG list */
|
||||||
struct scatterlist *bad_sg; /* assert statement */
|
struct scatterlist *bad_sg; /* assert statement */
|
||||||
int sg_count; /* SG's to process */
|
int sg_count; /* SG's to process */
|
||||||
uint32_t exp_r2tsn;
|
uint32_t exp_datasn; /* expected target's R2TSN/DataSN */
|
||||||
int data_offset;
|
int data_offset;
|
||||||
struct iscsi_r2t_info *r2t; /* in progress R2T */
|
struct iscsi_r2t_info *r2t; /* in progress R2T */
|
||||||
struct iscsi_queue r2tpool;
|
struct iscsi_queue r2tpool;
|
||||||
|
|
|
@ -120,7 +120,9 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
|
||||||
session->cmdsn++;
|
session->cmdsn++;
|
||||||
hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
|
hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
|
||||||
memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
|
memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
|
||||||
memset(&hdr->cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len);
|
if (sc->cmd_len < MAX_COMMAND_SIZE)
|
||||||
|
memset(&hdr->cdb[sc->cmd_len], 0,
|
||||||
|
MAX_COMMAND_SIZE - sc->cmd_len);
|
||||||
|
|
||||||
ctask->data_count = 0;
|
ctask->data_count = 0;
|
||||||
if (sc->sc_data_direction == DMA_TO_DEVICE) {
|
if (sc->sc_data_direction == DMA_TO_DEVICE) {
|
||||||
|
@ -165,7 +167,6 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
|
||||||
/* No unsolicit Data-Out's */
|
/* No unsolicit Data-Out's */
|
||||||
ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL;
|
ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL;
|
||||||
} else {
|
} else {
|
||||||
ctask->datasn = 0;
|
|
||||||
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
|
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
|
||||||
zero_data(hdr->dlength);
|
zero_data(hdr->dlength);
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,6 @@ struct iscsi_cmd_task {
|
||||||
*/
|
*/
|
||||||
struct iscsi_cmd *hdr;
|
struct iscsi_cmd *hdr;
|
||||||
int itt; /* this ITT */
|
int itt; /* this ITT */
|
||||||
int datasn; /* DataSN */
|
|
||||||
|
|
||||||
uint32_t unsol_datasn;
|
uint32_t unsol_datasn;
|
||||||
int imm_count; /* imm-data (bytes) */
|
int imm_count; /* imm-data (bytes) */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue