diff options
Diffstat (limited to 'drivers/target/iscsi/iscsi_target.c')
| -rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 80 |
1 files changed, 36 insertions, 44 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 9e67c7678c86..9eb10d34682c 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
| @@ -502,7 +502,7 @@ void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd) | |||
| 502 | EXPORT_SYMBOL(iscsit_aborted_task); | 502 | EXPORT_SYMBOL(iscsit_aborted_task); |
| 503 | 503 | ||
| 504 | static void iscsit_do_crypto_hash_buf(struct ahash_request *, const void *, | 504 | static void iscsit_do_crypto_hash_buf(struct ahash_request *, const void *, |
| 505 | u32, u32, u8 *, u8 *); | 505 | u32, u32, const void *, void *); |
| 506 | static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *); | 506 | static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *); |
| 507 | 507 | ||
| 508 | static int | 508 | static int |
| @@ -523,7 +523,7 @@ iscsit_xmit_nondatain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
| 523 | 523 | ||
| 524 | iscsit_do_crypto_hash_buf(conn->conn_tx_hash, hdr, | 524 | iscsit_do_crypto_hash_buf(conn->conn_tx_hash, hdr, |
| 525 | ISCSI_HDR_LEN, 0, NULL, | 525 | ISCSI_HDR_LEN, 0, NULL, |
| 526 | (u8 *)header_digest); | 526 | header_digest); |
| 527 | 527 | ||
| 528 | iov[0].iov_len += ISCSI_CRC_LEN; | 528 | iov[0].iov_len += ISCSI_CRC_LEN; |
| 529 | tx_size += ISCSI_CRC_LEN; | 529 | tx_size += ISCSI_CRC_LEN; |
| @@ -550,9 +550,8 @@ iscsit_xmit_nondatain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
| 550 | if (conn->conn_ops->DataDigest) { | 550 | if (conn->conn_ops->DataDigest) { |
| 551 | iscsit_do_crypto_hash_buf(conn->conn_tx_hash, | 551 | iscsit_do_crypto_hash_buf(conn->conn_tx_hash, |
| 552 | data_buf, data_buf_len, | 552 | data_buf, data_buf_len, |
| 553 | padding, | 553 | padding, &cmd->pad_bytes, |
| 554 | (u8 *)&cmd->pad_bytes, | 554 | &cmd->data_crc); |
| 555 | (u8 *)&cmd->data_crc); | ||
| 556 | 555 | ||
| 557 | iov[niov].iov_base = &cmd->data_crc; | 556 | iov[niov].iov_base = &cmd->data_crc; |
| 558 | iov[niov++].iov_len = ISCSI_CRC_LEN; | 557 | iov[niov++].iov_len = ISCSI_CRC_LEN; |
| @@ -597,7 +596,7 @@ iscsit_xmit_datain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
| 597 | 596 | ||
| 598 | iscsit_do_crypto_hash_buf(conn->conn_tx_hash, cmd->pdu, | 597 | iscsit_do_crypto_hash_buf(conn->conn_tx_hash, cmd->pdu, |
| 599 | ISCSI_HDR_LEN, 0, NULL, | 598 | ISCSI_HDR_LEN, 0, NULL, |
| 600 | (u8 *)header_digest); | 599 | header_digest); |
| 601 | 600 | ||
| 602 | iov[0].iov_len += ISCSI_CRC_LEN; | 601 | iov[0].iov_len += ISCSI_CRC_LEN; |
| 603 | tx_size += ISCSI_CRC_LEN; | 602 | tx_size += ISCSI_CRC_LEN; |
| @@ -836,6 +835,7 @@ static int iscsit_add_reject_from_cmd( | |||
| 836 | unsigned char *buf) | 835 | unsigned char *buf) |
| 837 | { | 836 | { |
| 838 | struct iscsi_conn *conn; | 837 | struct iscsi_conn *conn; |
| 838 | const bool do_put = cmd->se_cmd.se_tfo != NULL; | ||
| 839 | 839 | ||
| 840 | if (!cmd->conn) { | 840 | if (!cmd->conn) { |
| 841 | pr_err("cmd->conn is NULL for ITT: 0x%08x\n", | 841 | pr_err("cmd->conn is NULL for ITT: 0x%08x\n", |
| @@ -866,7 +866,7 @@ static int iscsit_add_reject_from_cmd( | |||
| 866 | * Perform the kref_put now if se_cmd has already been setup by | 866 | * Perform the kref_put now if se_cmd has already been setup by |
| 867 | * scsit_setup_scsi_cmd() | 867 | * scsit_setup_scsi_cmd() |
| 868 | */ | 868 | */ |
| 869 | if (cmd->se_cmd.se_tfo != NULL) { | 869 | if (do_put) { |
| 870 | pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n"); | 870 | pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n"); |
| 871 | target_put_sess_cmd(&cmd->se_cmd); | 871 | target_put_sess_cmd(&cmd->se_cmd); |
| 872 | } | 872 | } |
| @@ -1410,13 +1410,9 @@ static u32 iscsit_do_crypto_hash_sg( | |||
| 1410 | return data_crc; | 1410 | return data_crc; |
| 1411 | } | 1411 | } |
| 1412 | 1412 | ||
| 1413 | static void iscsit_do_crypto_hash_buf( | 1413 | static void iscsit_do_crypto_hash_buf(struct ahash_request *hash, |
| 1414 | struct ahash_request *hash, | 1414 | const void *buf, u32 payload_length, u32 padding, |
| 1415 | const void *buf, | 1415 | const void *pad_bytes, void *data_crc) |
| 1416 | u32 payload_length, | ||
| 1417 | u32 padding, | ||
| 1418 | u8 *pad_bytes, | ||
| 1419 | u8 *data_crc) | ||
| 1420 | { | 1416 | { |
| 1421 | struct scatterlist sg[2]; | 1417 | struct scatterlist sg[2]; |
| 1422 | 1418 | ||
| @@ -1462,9 +1458,9 @@ __iscsit_check_dataout_hdr(struct iscsi_conn *conn, void *buf, | |||
| 1462 | iscsit_mod_dataout_timer(cmd); | 1458 | iscsit_mod_dataout_timer(cmd); |
| 1463 | 1459 | ||
| 1464 | if ((be32_to_cpu(hdr->offset) + payload_length) > cmd->se_cmd.data_length) { | 1460 | if ((be32_to_cpu(hdr->offset) + payload_length) > cmd->se_cmd.data_length) { |
| 1465 | pr_err("DataOut Offset: %u, Length %u greater than" | 1461 | pr_err("DataOut Offset: %u, Length %u greater than iSCSI Command EDTL %u, protocol error.\n", |
| 1466 | " iSCSI Command EDTL %u, protocol error.\n", | 1462 | be32_to_cpu(hdr->offset), payload_length, |
| 1467 | hdr->offset, payload_length, cmd->se_cmd.data_length); | 1463 | cmd->se_cmd.data_length); |
| 1468 | return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID, buf); | 1464 | return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID, buf); |
| 1469 | } | 1465 | } |
| 1470 | 1466 | ||
| @@ -1878,10 +1874,9 @@ static int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
| 1878 | } | 1874 | } |
| 1879 | 1875 | ||
| 1880 | if (conn->conn_ops->DataDigest) { | 1876 | if (conn->conn_ops->DataDigest) { |
| 1881 | iscsit_do_crypto_hash_buf(conn->conn_rx_hash, | 1877 | iscsit_do_crypto_hash_buf(conn->conn_rx_hash, ping_data, |
| 1882 | ping_data, payload_length, | 1878 | payload_length, padding, |
| 1883 | padding, cmd->pad_bytes, | 1879 | cmd->pad_bytes, &data_crc); |
| 1884 | (u8 *)&data_crc); | ||
| 1885 | 1880 | ||
| 1886 | if (checksum != data_crc) { | 1881 | if (checksum != data_crc) { |
| 1887 | pr_err("Ping data CRC32C DataDigest" | 1882 | pr_err("Ping data CRC32C DataDigest" |
| @@ -1962,7 +1957,6 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
| 1962 | struct iscsi_tmr_req *tmr_req; | 1957 | struct iscsi_tmr_req *tmr_req; |
| 1963 | struct iscsi_tm *hdr; | 1958 | struct iscsi_tm *hdr; |
| 1964 | int out_of_order_cmdsn = 0, ret; | 1959 | int out_of_order_cmdsn = 0, ret; |
| 1965 | bool sess_ref = false; | ||
| 1966 | u8 function, tcm_function = TMR_UNKNOWN; | 1960 | u8 function, tcm_function = TMR_UNKNOWN; |
| 1967 | 1961 | ||
| 1968 | hdr = (struct iscsi_tm *) buf; | 1962 | hdr = (struct iscsi_tm *) buf; |
| @@ -1995,22 +1989,23 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
| 1995 | 1989 | ||
| 1996 | cmd->data_direction = DMA_NONE; | 1990 | cmd->data_direction = DMA_NONE; |
| 1997 | cmd->tmr_req = kzalloc(sizeof(*cmd->tmr_req), GFP_KERNEL); | 1991 | cmd->tmr_req = kzalloc(sizeof(*cmd->tmr_req), GFP_KERNEL); |
| 1998 | if (!cmd->tmr_req) | 1992 | if (!cmd->tmr_req) { |
| 1999 | return iscsit_add_reject_cmd(cmd, | 1993 | return iscsit_add_reject_cmd(cmd, |
| 2000 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1994 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
| 2001 | buf); | 1995 | buf); |
| 1996 | } | ||
| 1997 | |||
| 1998 | transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops, | ||
| 1999 | conn->sess->se_sess, 0, DMA_NONE, | ||
| 2000 | TCM_SIMPLE_TAG, cmd->sense_buffer + 2); | ||
| 2001 | |||
| 2002 | target_get_sess_cmd(&cmd->se_cmd, true); | ||
| 2002 | 2003 | ||
| 2003 | /* | 2004 | /* |
| 2004 | * TASK_REASSIGN for ERL=2 / connection stays inside of | 2005 | * TASK_REASSIGN for ERL=2 / connection stays inside of |
| 2005 | * LIO-Target $FABRIC_MOD | 2006 | * LIO-Target $FABRIC_MOD |
| 2006 | */ | 2007 | */ |
| 2007 | if (function != ISCSI_TM_FUNC_TASK_REASSIGN) { | 2008 | if (function != ISCSI_TM_FUNC_TASK_REASSIGN) { |
| 2008 | transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops, | ||
| 2009 | conn->sess->se_sess, 0, DMA_NONE, | ||
| 2010 | TCM_SIMPLE_TAG, cmd->sense_buffer + 2); | ||
| 2011 | |||
| 2012 | target_get_sess_cmd(&cmd->se_cmd, true); | ||
| 2013 | sess_ref = true; | ||
| 2014 | tcm_function = iscsit_convert_tmf(function); | 2009 | tcm_function = iscsit_convert_tmf(function); |
| 2015 | if (tcm_function == TMR_UNKNOWN) { | 2010 | if (tcm_function == TMR_UNKNOWN) { |
| 2016 | pr_err("Unknown iSCSI TMR Function:" | 2011 | pr_err("Unknown iSCSI TMR Function:" |
| @@ -2101,12 +2096,14 @@ attach: | |||
| 2101 | 2096 | ||
| 2102 | if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { | 2097 | if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { |
| 2103 | int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn); | 2098 | int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn); |
| 2104 | if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP) | 2099 | if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP) { |
| 2105 | out_of_order_cmdsn = 1; | 2100 | out_of_order_cmdsn = 1; |
| 2106 | else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) | 2101 | } else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) { |
| 2102 | target_put_sess_cmd(&cmd->se_cmd); | ||
| 2107 | return 0; | 2103 | return 0; |
| 2108 | else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | 2104 | } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) { |
| 2109 | return -1; | 2105 | return -1; |
| 2106 | } | ||
| 2110 | } | 2107 | } |
| 2111 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); | 2108 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); |
| 2112 | 2109 | ||
| @@ -2126,12 +2123,8 @@ attach: | |||
| 2126 | * For connection recovery, this is also the default action for | 2123 | * For connection recovery, this is also the default action for |
| 2127 | * TMR TASK_REASSIGN. | 2124 | * TMR TASK_REASSIGN. |
| 2128 | */ | 2125 | */ |
| 2129 | if (sess_ref) { | ||
| 2130 | pr_debug("Handle TMR, using sess_ref=true check\n"); | ||
| 2131 | target_put_sess_cmd(&cmd->se_cmd); | ||
| 2132 | } | ||
| 2133 | |||
| 2134 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); | 2126 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); |
| 2127 | target_put_sess_cmd(&cmd->se_cmd); | ||
| 2135 | return 0; | 2128 | return 0; |
| 2136 | } | 2129 | } |
| 2137 | EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd); | 2130 | EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd); |
| @@ -2287,10 +2280,9 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
| 2287 | goto reject; | 2280 | goto reject; |
| 2288 | 2281 | ||
| 2289 | if (conn->conn_ops->DataDigest) { | 2282 | if (conn->conn_ops->DataDigest) { |
| 2290 | iscsit_do_crypto_hash_buf(conn->conn_rx_hash, | 2283 | iscsit_do_crypto_hash_buf(conn->conn_rx_hash, text_in, |
| 2291 | text_in, payload_length, | 2284 | payload_length, padding, |
| 2292 | padding, (u8 *)&pad_bytes, | 2285 | &pad_bytes, &data_crc); |
| 2293 | (u8 *)&data_crc); | ||
| 2294 | 2286 | ||
| 2295 | if (checksum != data_crc) { | 2287 | if (checksum != data_crc) { |
| 2296 | pr_err("Text data CRC32C DataDigest" | 2288 | pr_err("Text data CRC32C DataDigest" |
| @@ -3978,9 +3970,9 @@ static void iscsit_get_rx_pdu(struct iscsi_conn *conn) | |||
| 3978 | return; | 3970 | return; |
| 3979 | } | 3971 | } |
| 3980 | 3972 | ||
| 3981 | iscsit_do_crypto_hash_buf(conn->conn_rx_hash, | 3973 | iscsit_do_crypto_hash_buf(conn->conn_rx_hash, buffer, |
| 3982 | buffer, ISCSI_HDR_LEN, | 3974 | ISCSI_HDR_LEN, 0, NULL, |
| 3983 | 0, NULL, (u8 *)&checksum); | 3975 | &checksum); |
| 3984 | 3976 | ||
| 3985 | if (digest != checksum) { | 3977 | if (digest != checksum) { |
| 3986 | pr_err("HeaderDigest CRC32C failed," | 3978 | pr_err("HeaderDigest CRC32C failed," |
