diff options
Diffstat (limited to 'drivers/target/iscsi')
20 files changed, 335 insertions, 300 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 97c0f78c3c9c..d6ce2182e672 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -427,7 +427,7 @@ int iscsit_reset_np_thread( return 0; } -int iscsit_del_np_comm(struct iscsi_np *np) +static int iscsit_del_np_comm(struct iscsi_np *np) { if (np->np_socket) sock_release(np->np_socket); @@ -785,10 +785,6 @@ static int iscsit_handle_scsi_cmd( hdr = (struct iscsi_scsi_req *) buf; payload_length = ntoh24(hdr->dlength); - hdr->itt = be32_to_cpu(hdr->itt); - hdr->data_length = be32_to_cpu(hdr->data_length); - hdr->cmdsn = be32_to_cpu(hdr->cmdsn); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); /* FIXME; Add checks for AdditionalHeaderSegment */ @@ -852,7 +848,7 @@ done: buf, conn); } - if ((hdr->data_length == payload_length) && + if ((be32_to_cpu(hdr->data_length )== payload_length) && (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) { pr_err("Expected Data Transfer Length and Length of" " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL" @@ -861,7 +857,7 @@ done: buf, conn); } - if (payload_length > hdr->data_length) { + if (payload_length > be32_to_cpu(hdr->data_length)) { pr_err("DataSegmentLength: %u is greater than" " EDTL: %u, protocol error.\n", payload_length, hdr->data_length); @@ -869,10 +865,10 @@ done: buf, conn); } - if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) { + if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { pr_err("DataSegmentLength: %u is greater than" - " MaxRecvDataSegmentLength: %u, protocol error.\n", - payload_length, conn->conn_ops->MaxRecvDataSegmentLength); + " MaxXmitDataSegmentLength: %u, protocol error.\n", + payload_length, conn->conn_ops->MaxXmitDataSegmentLength); return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, buf, conn); } @@ -932,8 +928,8 @@ done: spin_unlock_bh(&conn->sess->ttt_lock); } else if (hdr->flags & ISCSI_FLAG_CMD_WRITE) cmd->targ_xfer_tag = 0xFFFFFFFF; - cmd->cmd_sn = hdr->cmdsn; - cmd->exp_stat_sn = hdr->exp_statsn; + cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); + cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); cmd->first_burst_len = payload_length; if (cmd->data_direction == DMA_FROM_DEVICE) { @@ -952,8 +948,9 @@ done: * Initialize struct se_cmd descriptor from target_core_mod infrastructure */ transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops, - conn->sess->se_sess, hdr->data_length, cmd->data_direction, - sam_task_attr, &cmd->sense_buffer[0]); + conn->sess->se_sess, be32_to_cpu(hdr->data_length), + cmd->data_direction, sam_task_attr, + cmd->sense_buffer + 2); pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x," " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, @@ -1028,7 +1025,7 @@ attach_cmd: 1, 0, buf, cmd); } - iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); + iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); /* * If no Immediate Data is attached, it's OK to return now. @@ -1194,11 +1191,6 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) hdr = (struct iscsi_data *) buf; payload_length = ntoh24(hdr->dlength); - hdr->itt = be32_to_cpu(hdr->itt); - hdr->ttt = be32_to_cpu(hdr->ttt); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); - hdr->datasn = be32_to_cpu(hdr->datasn); - hdr->offset = be32_to_cpu(hdr->offset); if (!payload_length) { pr_err("DataOUT payload is ZERO, protocol error.\n"); @@ -1216,10 +1208,10 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) } spin_unlock_bh(&conn->sess->session_stats_lock); - if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) { + if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { pr_err("DataSegmentLength: %u is greater than" - " MaxRecvDataSegmentLength: %u\n", payload_length, - conn->conn_ops->MaxRecvDataSegmentLength); + " MaxXmitDataSegmentLength: %u\n", payload_length, + conn->conn_ops->MaxXmitDataSegmentLength); return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, buf, conn); } @@ -1250,7 +1242,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) se_cmd = &cmd->se_cmd; iscsit_mod_dataout_timer(cmd); - if ((hdr->offset + payload_length) > cmd->se_cmd.data_length) { + if ((be32_to_cpu(hdr->offset) + payload_length) > cmd->se_cmd.data_length) { pr_err("DataOut Offset: %u, Length %u greater than" " iSCSI Command EDTL %u, protocol error.\n", hdr->offset, payload_length, cmd->se_cmd.data_length); @@ -1333,7 +1325,8 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) rx_size += payload_length; iov = &cmd->iov_data[0]; - iov_ret = iscsit_map_iovec(cmd, iov, hdr->offset, payload_length); + iov_ret = iscsit_map_iovec(cmd, iov, be32_to_cpu(hdr->offset), + payload_length); if (iov_ret < 0) return -1; @@ -1364,7 +1357,8 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) u32 data_crc; data_crc = iscsit_do_crypto_hash_sg(&conn->conn_rx_hash, cmd, - hdr->offset, payload_length, padding, + be32_to_cpu(hdr->offset), + payload_length, padding, cmd->pad_bytes); if (checksum != data_crc) { @@ -1425,30 +1419,26 @@ static int iscsit_handle_nop_out( hdr = (struct iscsi_nopout *) buf; payload_length = ntoh24(hdr->dlength); - hdr->itt = be32_to_cpu(hdr->itt); - hdr->ttt = be32_to_cpu(hdr->ttt); - hdr->cmdsn = be32_to_cpu(hdr->cmdsn); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); - if ((hdr->itt == 0xFFFFFFFF) && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { + if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { pr_err("NOPOUT ITT is reserved, but Immediate Bit is" " not set, protocol error.\n"); return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, buf, conn); } - if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) { + if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { pr_err("NOPOUT Ping Data DataSegmentLength: %u is" - " greater than MaxRecvDataSegmentLength: %u, protocol" + " greater than MaxXmitDataSegmentLength: %u, protocol" " error.\n", payload_length, - conn->conn_ops->MaxRecvDataSegmentLength); + conn->conn_ops->MaxXmitDataSegmentLength); return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, buf, conn); } pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%09x," " CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n", - (hdr->itt == 0xFFFFFFFF) ? "Response" : "Request", + hdr->itt == RESERVED_ITT ? "Response" : "Request", hdr->itt, hdr->ttt, hdr->cmdsn, hdr->exp_statsn, payload_length); /* @@ -1458,7 +1448,7 @@ static int iscsit_handle_nop_out( * Either way, make sure we allocate an struct iscsi_cmd, as both * can contain ping data. */ - if (hdr->ttt == 0xFFFFFFFF) { + if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); if (!cmd) return iscsit_add_reject( @@ -1471,12 +1461,12 @@ static int iscsit_handle_nop_out( 1 : 0); conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; cmd->targ_xfer_tag = 0xFFFFFFFF; - cmd->cmd_sn = hdr->cmdsn; - cmd->exp_stat_sn = hdr->exp_statsn; + cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); + cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); cmd->data_direction = DMA_NONE; } - if (payload_length && (hdr->ttt == 0xFFFFFFFF)) { + if (payload_length && hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { rx_size = payload_length; ping_data = kzalloc(payload_length + 1, GFP_KERNEL); if (!ping_data) { @@ -1556,7 +1546,7 @@ static int iscsit_handle_nop_out( pr_debug("Ping Data: \"%s\"\n", ping_data); } - if (hdr->itt != 0xFFFFFFFF) { + if (hdr->itt != RESERVED_ITT) { if (!cmd) { pr_err("Checking CmdSN for NOPOUT," " but cmd is NULL!\n"); @@ -1569,7 +1559,7 @@ static int iscsit_handle_nop_out( list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); - iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); + iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); if (hdr->opcode & ISCSI_OP_IMMEDIATE) { iscsit_add_cmd_to_response_queue(cmd, conn, @@ -1590,11 +1580,11 @@ static int iscsit_handle_nop_out( return 0; } - if (hdr->ttt != 0xFFFFFFFF) { + if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) { /* * This was a response to a unsolicited NOPIN ping. */ - cmd = iscsit_find_cmd_from_ttt(conn, hdr->ttt); + cmd = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt)); if (!cmd) return -1; @@ -1639,12 +1629,6 @@ static int iscsit_handle_task_mgt_cmd( u8 function; hdr = (struct iscsi_tm *) buf; - hdr->itt = be32_to_cpu(hdr->itt); - hdr->rtt = be32_to_cpu(hdr->rtt); - hdr->cmdsn = be32_to_cpu(hdr->cmdsn); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); - hdr->refcmdsn = be32_to_cpu(hdr->refcmdsn); - hdr->exp_datasn = be32_to_cpu(hdr->exp_datasn); hdr->flags &= ~ISCSI_FLAG_CMD_FINAL; function = hdr->flags; @@ -1655,9 +1639,9 @@ static int iscsit_handle_task_mgt_cmd( if ((function != ISCSI_TM_FUNC_ABORT_TASK) && ((function != ISCSI_TM_FUNC_TASK_REASSIGN) && - (hdr->rtt != ISCSI_RESERVED_TAG))) { + hdr->rtt != RESERVED_ITT)) { pr_err("RefTaskTag should be set to 0xFFFFFFFF.\n"); - hdr->rtt = ISCSI_RESERVED_TAG; + hdr->rtt = RESERVED_ITT; } if ((function == ISCSI_TM_FUNC_TASK_REASSIGN) && @@ -1669,8 +1653,8 @@ static int iscsit_handle_task_mgt_cmd( buf, conn); } if ((function != ISCSI_TM_FUNC_ABORT_TASK) && - (hdr->refcmdsn != ISCSI_RESERVED_TAG)) - hdr->refcmdsn = ISCSI_RESERVED_TAG; + be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG) + hdr->refcmdsn = cpu_to_be32(ISCSI_RESERVED_TAG); cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); if (!cmd) @@ -1700,7 +1684,7 @@ static int iscsit_handle_task_mgt_cmd( transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops, conn->sess->se_sess, 0, DMA_NONE, - MSG_SIMPLE_TAG, &cmd->sense_buffer[0]); + MSG_SIMPLE_TAG, cmd->sense_buffer + 2); switch (function) { case ISCSI_TM_FUNC_ABORT_TASK: @@ -1747,8 +1731,8 @@ static int iscsit_handle_task_mgt_cmd( cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); cmd->init_task_tag = hdr->itt; cmd->targ_xfer_tag = 0xFFFFFFFF; - cmd->cmd_sn = hdr->cmdsn; - cmd->exp_stat_sn = hdr->exp_statsn; + cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); + cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); se_tmr = cmd->se_cmd.se_tmr_req; tmr_req = cmd->tmr_req; /* @@ -1832,7 +1816,7 @@ attach: ISCSI_REASON_PROTOCOL_ERROR, 1, 0, buf, cmd); } - iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); + iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); if (out_of_order_cmdsn || !(hdr->opcode & ISCSI_OP_IMMEDIATE)) return 0; @@ -1869,15 +1853,11 @@ static int iscsit_handle_text_cmd( hdr = (struct iscsi_text *) buf; payload_length = ntoh24(hdr->dlength); - hdr->itt = be32_to_cpu(hdr->itt); - hdr->ttt = be32_to_cpu(hdr->ttt); - hdr->cmdsn = be32_to_cpu(hdr->cmdsn); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); - if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) { + if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { pr_err("Unable to accept text parameter length: %u" - "greater than MaxRecvDataSegmentLength %u.\n", - payload_length, conn->conn_ops->MaxRecvDataSegmentLength); + "greater than MaxXmitDataSegmentLength %u.\n", + payload_length, conn->conn_ops->MaxXmitDataSegmentLength); return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, buf, conn); } @@ -1989,15 +1969,15 @@ static int iscsit_handle_text_cmd( cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; cmd->targ_xfer_tag = 0xFFFFFFFF; - cmd->cmd_sn = hdr->cmdsn; - cmd->exp_stat_sn = hdr->exp_statsn; + cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); + cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); cmd->data_direction = DMA_NONE; spin_lock_bh(&conn->cmd_lock); list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); - iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); + iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); @@ -2131,10 +2111,6 @@ static int iscsit_handle_logout_cmd( hdr = (struct iscsi_logout *) buf; reason_code = (hdr->flags & 0x7f); - hdr->itt = be32_to_cpu(hdr->itt); - hdr->cid = be16_to_cpu(hdr->cid); - hdr->cmdsn = be32_to_cpu(hdr->cmdsn); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); if (tiqn) { spin_lock(&tiqn->logout_stats.lock); @@ -2166,9 +2142,9 @@ static int iscsit_handle_logout_cmd( cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; cmd->targ_xfer_tag = 0xFFFFFFFF; - cmd->cmd_sn = hdr->cmdsn; - cmd->exp_stat_sn = hdr->exp_statsn; - cmd->logout_cid = hdr->cid; + cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); + cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); + cmd->logout_cid = be16_to_cpu(hdr->cid); cmd->logout_reason = reason_code; cmd->data_direction = DMA_NONE; @@ -2178,7 +2154,7 @@ static int iscsit_handle_logout_cmd( */ if ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION) || ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION) && - (hdr->cid == conn->cid))) + be16_to_cpu(hdr->cid) == conn->cid)) logout_remove = 1; spin_lock_bh(&conn->cmd_lock); @@ -2186,7 +2162,7 @@ static int iscsit_handle_logout_cmd( spin_unlock_bh(&conn->cmd_lock); if (reason_code != ISCSI_LOGOUT_REASON_RECOVERY) - iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); + iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); /* * Immediate commands are executed, well, immediately. @@ -2219,11 +2195,6 @@ static int iscsit_handle_snack( hdr = (struct iscsi_snack *) buf; hdr->flags &= ~ISCSI_FLAG_CMD_FINAL; - hdr->itt = be32_to_cpu(hdr->itt); - hdr->ttt = be32_to_cpu(hdr->ttt); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); - hdr->begrun = be32_to_cpu(hdr->begrun); - hdr->runlength = be32_to_cpu(hdr->runlength); pr_debug("Got ISCSI_INIT_SNACK, ITT: 0x%08x, ExpStatSN:" " 0x%08x, Type: 0x%02x, BegRun: 0x%08x, RunLength: 0x%08x," @@ -2243,13 +2214,18 @@ static int iscsit_handle_snack( switch (hdr->flags & ISCSI_FLAG_SNACK_TYPE_MASK) { case 0: return iscsit_handle_recovery_datain_or_r2t(conn, buf, - hdr->itt, hdr->ttt, hdr->begrun, hdr->runlength); + hdr->itt, + be32_to_cpu(hdr->ttt), + be32_to_cpu(hdr->begrun), + be32_to_cpu(hdr->runlength)); case ISCSI_FLAG_SNACK_TYPE_STATUS: - return iscsit_handle_status_snack(conn, hdr->itt, hdr->ttt, - hdr->begrun, hdr->runlength); + return iscsit_handle_status_snack(conn, hdr->itt, + be32_to_cpu(hdr->ttt), + be32_to_cpu(hdr->begrun), be32_to_cpu(hdr->runlength)); case ISCSI_FLAG_SNACK_TYPE_DATA_ACK: - return iscsit_handle_data_ack(conn, hdr->ttt, hdr->begrun, - hdr->runlength); + return iscsit_handle_data_ack(conn, be32_to_cpu(hdr->ttt), + be32_to_cpu(hdr->begrun), + be32_to_cpu(hdr->runlength)); case ISCSI_FLAG_SNACK_TYPE_RDATA: /* FIXME: Support R-Data SNACK */ pr_err("R-Data SNACK Not Supported.\n"); @@ -2414,7 +2390,7 @@ static int iscsit_send_conn_drop_async_message( hdr = (struct iscsi_async *) cmd->pdu; hdr->opcode = ISCSI_OP_ASYNC_EVENT; hdr->flags = ISCSI_FLAG_CMD_FINAL; - cmd->init_task_tag = 0xFFFFFFFF; + cmd->init_task_tag = RESERVED_ITT; cmd->targ_xfer_tag = 0xFFFFFFFF; put_unaligned_be64(0xFFFFFFFFFFFFFFFFULL, &hdr->rsvd4[0]); cmd->stat_sn = conn->stat_sn++; @@ -2536,12 +2512,17 @@ static int iscsit_send_data_in( else put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun); - hdr->itt = cpu_to_be32(cmd->init_task_tag); - hdr->ttt = (hdr->flags & ISCSI_FLAG_DATA_ACK) ? - cpu_to_be32(cmd->targ_xfer_tag) : - 0xFFFFFFFF; - hdr->statsn = (set_statsn) ? cpu_to_be32(cmd->stat_sn) : - 0xFFFFFFFF; + hdr->itt = cmd->init_task_tag; + + if (hdr->flags & ISCSI_FLAG_DATA_ACK) + hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); + else + hdr->ttt = cpu_to_be32(0xFFFFFFFF); + if (set_statsn) + hdr->statsn = cpu_to_be32(cmd->stat_sn); + else + hdr->statsn = cpu_to_be32(0xFFFFFFFF); + hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); hdr->datasn = cpu_to_be32(datain.data_sn); @@ -2708,7 +2689,7 @@ static int iscsit_send_logout_response( hdr->opcode = ISCSI_OP_LOGOUT_RSP; hdr->flags |= ISCSI_FLAG_CMD_FINAL; hdr->response = cmd->logout_response; - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); @@ -2759,7 +2740,7 @@ static int iscsit_send_unsolicited_nopin( memset(hdr, 0, ISCSI_HDR_LEN); hdr->opcode = ISCSI_OP_NOOP_IN; hdr->flags |= ISCSI_FLAG_CMD_FINAL; - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); cmd->stat_sn = conn->stat_sn; hdr->statsn = cpu_to_be32(cmd->stat_sn); @@ -2816,7 +2797,7 @@ static int iscsit_send_nopin_response( hdr->flags |= ISCSI_FLAG_CMD_FINAL; hton24(hdr->dlength, cmd->buf_ptr_size); put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun); - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); @@ -2906,7 +2887,7 @@ static int iscsit_send_r2t( hdr->flags |= ISCSI_FLAG_CMD_FINAL; int_to_scsilun(cmd->se_cmd.orig_fe_lun, (struct scsi_lun *)&hdr->lun); - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; spin_lock_bh(&conn->sess->ttt_lock); r2t->targ_xfer_tag = conn->sess->targ_xfer_tag++; if (r2t->targ_xfer_tag == 0xFFFFFFFF) @@ -3074,7 +3055,7 @@ static int iscsit_send_status( } hdr->response = cmd->iscsi_response; hdr->cmd_status = cmd->se_cmd.scsi_status; - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; hdr->statsn = cpu_to_be32(cmd->stat_sn); iscsit_increment_maxcmdsn(cmd, conn->sess); @@ -3092,15 +3073,18 @@ static int iscsit_send_status( if (cmd->se_cmd.sense_buffer && ((cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) || (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) { + put_unaligned_be16(cmd->se_cmd.scsi_sense_length, cmd->sense_buffer); + cmd->se_cmd.scsi_sense_length += sizeof (__be16); + padding = -(cmd->se_cmd.scsi_sense_length) & 3; - hton24(hdr->dlength, cmd->se_cmd.scsi_sense_length); - iov[iov_count].iov_base = cmd->se_cmd.sense_buffer; + hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length); + iov[iov_count].iov_base = cmd->sense_buffer; iov[iov_count++].iov_len = (cmd->se_cmd.scsi_sense_length + padding); tx_size += cmd->se_cmd.scsi_sense_length; if (padding) { - memset(cmd->se_cmd.sense_buffer + + memset(cmd->sense_buffer + cmd->se_cmd.scsi_sense_length, 0, padding); tx_size += padding; pr_debug("Adding %u bytes of padding to" @@ -3109,7 +3093,7 @@ static int iscsit_send_status( if (conn->conn_ops->DataDigest) { iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, - cmd->se_cmd.sense_buffer, + cmd->sense_buffer, (cmd->se_cmd.scsi_sense_length + padding), 0, NULL, (u8 *)&cmd->data_crc); @@ -3184,7 +3168,7 @@ static int iscsit_send_task_mgt_rsp( hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; hdr->flags = ISCSI_FLAG_CMD_FINAL; hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr); - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); @@ -3236,7 +3220,7 @@ static bool iscsit_check_inaddr_any(struct iscsi_np *np) struct sockaddr_in * sock_in = (struct sockaddr_in *)&np->np_sockaddr; - if (sock_in->sin_addr.s_addr == INADDR_ANY) + if (sock_in->sin_addr.s_addr == htonl(INADDR_ANY)) ret = true; } @@ -3271,7 +3255,6 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) len += 1; if ((len + payload_len) > buffer_len) { - spin_unlock(&tiqn->tiqn_tpg_lock); end_of_buf = 1; goto eob; } @@ -3358,7 +3341,7 @@ static int iscsit_send_text_rsp( hdr->opcode = ISCSI_OP_TEXT_RSP; hdr->flags |= ISCSI_FLAG_CMD_FINAL; hton24(hdr->dlength, text_length); - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); @@ -3424,6 +3407,7 @@ static int iscsit_send_reject( hdr->opcode = ISCSI_OP_REJECT; hdr->flags |= ISCSI_FLAG_CMD_FINAL; hton24(hdr->dlength, ISCSI_HDR_LEN); + hdr->ffffffff = cpu_to_be32(0xffffffff); cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index 12abb4c9e34e..f1e4f3155bac 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h @@ -38,4 +38,9 @@ extern struct kmem_cache *lio_cmd_cache; extern struct kmem_cache *lio_qr_cache; extern struct kmem_cache *lio_r2t_cache; +extern struct idr sess_idr; +extern struct mutex auth_id_lock; +extern spinlock_t sess_idr_lock; + + #endif /*** ISCSI_TARGET_H ***/ diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index a7b25e783b58..ff6fd4fb624d 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -135,7 +135,7 @@ static struct configfs_attribute *lio_target_portal_attrs[] = { #define MAX_PORTAL_LEN 256 -struct se_tpg_np *lio_target_call_addnptotpg( +static struct se_tpg_np *lio_target_call_addnptotpg( struct se_portal_group *se_tpg, struct config_group *group, const char *name) @@ -1034,6 +1034,9 @@ TPG_PARAM_ATTR(ImmediateData, S_IRUGO | S_IWUSR); DEF_TPG_PARAM(MaxRecvDataSegmentLength); TPG_PARAM_ATTR(MaxRecvDataSegmentLength, S_IRUGO | S_IWUSR); +DEF_TPG_PARAM(MaxXmitDataSegmentLength); +TPG_PARAM_ATTR(MaxXmitDataSegmentLength, S_IRUGO | S_IWUSR); + DEF_TPG_PARAM(MaxBurstLength); TPG_PARAM_ATTR(MaxBurstLength, S_IRUGO | S_IWUSR); @@ -1079,6 +1082,7 @@ static struct configfs_attribute *lio_target_tpg_param_attrs[] = { &iscsi_tpg_param_InitialR2T.attr, &iscsi_tpg_param_ImmediateData.attr, &iscsi_tpg_param_MaxRecvDataSegmentLength.attr, + &iscsi_tpg_param_MaxXmitDataSegmentLength.attr, &iscsi_tpg_param_MaxBurstLength.attr, &iscsi_tpg_param_FirstBurstLength.attr, &iscsi_tpg_param_DefaultTime2Wait.attr, @@ -1166,7 +1170,7 @@ static struct configfs_attribute *lio_target_tpg_attrs[] = { /* Start items for lio_target_tiqn_cit */ -struct se_portal_group *lio_target_tiqn_addtpg( +static struct se_portal_group *lio_target_tiqn_addtpg( struct se_wwn *wwn, struct config_group *group, const char *name) @@ -1216,7 +1220,7 @@ out: return NULL; } -void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg) +static void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg) { struct iscsi_portal_group *tpg; struct iscsi_tiqn *tiqn; @@ -1248,7 +1252,7 @@ static struct configfs_attribute *lio_target_wwn_attrs[] = { NULL, }; -struct se_wwn *lio_target_call_coreaddtiqn( +static struct se_wwn *lio_target_call_coreaddtiqn( struct target_fabric_configfs *tf, struct config_group *group, const char *name) @@ -1296,7 +1300,7 @@ struct se_wwn *lio_target_call_coreaddtiqn( return &tiqn->tiqn_wwn; } -void lio_target_call_coredeltiqn( +static void lio_target_call_coredeltiqn( struct se_wwn *wwn) { struct iscsi_tiqn *tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn); @@ -1471,7 +1475,8 @@ static u32 iscsi_get_task_tag(struct se_cmd *se_cmd) { struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); - return cmd->init_task_tag; + /* only used for printks or comparism with ->ref_task_tag */ + return (__force u32)cmd->init_task_tag; } static int iscsi_get_cmd_state(struct se_cmd *se_cmd) @@ -1542,29 +1547,6 @@ static int lio_queue_status(struct se_cmd *se_cmd) return 0; } -static u16 lio_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) -{ - unsigned char *buffer = se_cmd->sense_buffer; - /* - * From RFC-3720 10.4.7. Data Segment - Sense and Response Data Segment - * 16-bit SenseLength. - */ - buffer[0] = ((sense_length >> 8) & 0xff); - buffer[1] = (sense_length & 0xff); - /* - * Return two byte offset into allocated sense_buffer. - */ - return 2; -} - -static u16 lio_get_fabric_sense_len(void) -{ - /* - * Return two byte offset into allocated sense_buffer. - */ - return 2; -} - static int lio_queue_tm_rsp(struct se_cmd *se_cmd) { struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); @@ -1748,8 +1730,6 @@ int iscsi_target_register_configfs(void) fabric->tf_ops.queue_data_in = &lio_queue_data_in; fabric->tf_ops.queue_status = &lio_queue_status; fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp; - fabric->tf_ops.set_fabric_sense_len = &lio_set_fabric_sense_len; - fabric->tf_ops.get_fabric_sense_len = &lio_get_fabric_sense_len; /* * Setup function pointers for generic logic in target_core_fabric_configfs.c */ diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 8a908b28d8b2..2ba9f9b9435c 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -25,10 +25,10 @@ #define NA_DATAOUT_TIMEOUT_RETRIES 5 #define NA_DATAOUT_TIMEOUT_RETRIES_MAX 15 #define NA_DATAOUT_TIMEOUT_RETRIES_MIN 1 -#define NA_NOPIN_TIMEOUT 5 +#define NA_NOPIN_TIMEOUT 15 #define NA_NOPIN_TIMEOUT_MAX 60 #define NA_NOPIN_TIMEOUT_MIN 3 -#define NA_NOPIN_RESPONSE_TIMEOUT 5 +#define NA_NOPIN_RESPONSE_TIMEOUT 30 #define NA_NOPIN_RESPONSE_TIMEOUT_MAX 60 #define NA_NOPIN_RESPONSE_TIMEOUT_MIN 3 #define NA_RANDOM_DATAIN_PDU_OFFSETS 0 @@ -239,6 +239,7 @@ struct iscsi_conn_ops { u8 HeaderDigest; /* [0,1] == [None,CRC32C] */ u8 DataDigest; /* [0,1] == [None,CRC32C] */ u32 MaxRecvDataSegmentLength; /* [512..2**24-1] */ + u32 MaxXmitDataSegmentLength; /* [512..2**24-1] */ u8 OFMarker; /* [0,1] == [No,Yes] */ u8 IFMarker; /* [0,1] == [No,Yes] */ u32 OFMarkInt; /* [1..65535] */ @@ -360,7 +361,7 @@ struct iscsi_cmd { /* Command flags */ enum cmd_flags_table cmd_flags; /* Initiator Task Tag assigned from Initiator */ - u32 init_task_tag; + itt_t init_task_tag; /* Target Transfer Tag assigned from Target */ u32 targ_xfer_tag; /* CmdSN assigned from Initiator */ @@ -478,7 +479,6 @@ struct iscsi_cmd { struct iscsi_tmr_req { bool task_reassign:1; - u32 ref_cmd_sn; u32 exp_data_sn; struct iscsi_cmd *ref_cmd; struct iscsi_conn_recovery *conn_recovery; @@ -505,7 +505,7 @@ struct iscsi_conn { u32 auth_id; u32 conn_flags; /* Used for iscsi_tx_login_rsp() */ - u32 login_itt; + itt_t login_itt; u32 exp_statsn; /* Per connection status sequence number */ u32 stat_sn; @@ -578,6 +578,7 @@ struct iscsi_conn_recovery { u16 cid; u32 cmd_count; u32 maxrecvdatasegmentlength; + u32 maxxmitdatasegmentlength; int ready_for_reallegiance; struct list_head conn_recovery_cmd_list; spinlock_t conn_recovery_cmd_lock; @@ -597,7 +598,7 @@ struct iscsi_session { /* state session is currently in */ u32 session_state; /* session wide counter: initiator assigned task tag */ - u32 init_task_tag; + itt_t init_task_tag; /* session wide counter: target assigned task tag */ u32 targ_xfer_tag; u32 cmdsn_window; @@ -663,7 +664,7 @@ struct iscsi_login { u8 version_max; char isid[6]; u32 cmd_sn; - u32 init_task_tag; + itt_t init_task_tag; u32 initial_exp_statsn; u32 rsp_length; u16 cid; diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index 1a02016ecdab..8aacf611b86d 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c @@ -48,9 +48,9 @@ void iscsit_set_dataout_sequence_values( if (cmd->unsolicited_data) { cmd->seq_start_offset = cmd->write_data_done; cmd->seq_end_offset = (cmd->write_data_done + - (cmd->se_cmd.data_length > - conn->sess->sess_ops->FirstBurstLength) ? - conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length); + ((cmd->se_cmd.data_length > + conn->sess->sess_ops->FirstBurstLength) ? + conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length)); return; } @@ -95,14 +95,15 @@ static int iscsit_dataout_within_command_recovery_check( */ if (conn->sess->sess_ops->DataSequenceInOrder) { if ((cmd->cmd_flags & ICF_WITHIN_COMMAND_RECOVERY) && - (cmd->write_data_done != hdr->offset)) + cmd->write_data_done != be32_to_cpu(hdr->offset)) goto dump; cmd->cmd_flags &= ~ICF_WITHIN_COMMAND_RECOVERY; } else { struct iscsi_seq *seq; - seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length); + seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset), + payload_length); if (!seq) return DATAOUT_CANNOT_RECOVER; /* @@ -111,15 +112,15 @@ static int iscsit_dataout_within_command_recovery_check( cmd->seq_ptr = seq; if (conn->sess->sess_ops->DataPDUInOrder) { - if ((seq->status == - DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) && - ((seq->offset != hdr->offset) || - (seq->data_sn != hdr->datasn))) + if (seq->status == + DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY && + (seq->offset != be32_to_cpu(hdr->offset) || + seq->data_sn != be32_to_cpu(hdr->datasn))) goto dump; } else { - if ((seq->status == - DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) && - (seq->data_sn != hdr->datasn)) + if (seq->status == + DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY && + seq->data_sn != be32_to_cpu(hdr->datasn)) goto dump; } @@ -148,12 +149,12 @@ static int iscsit_dataout_check_unsolicited_sequence( u32 payload_length = ntoh24(hdr->dlength); - if ((hdr->offset < cmd->seq_start_offset) || - ((hdr->offset + payload_length) > cmd->seq_end_offset)) { + if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) || + ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) { pr_err("Command ITT: 0x%08x with Offset: %u," " Length: %u outside of Unsolicited Sequence %u:%u while" " DataSequenceInOrder=Yes.\n", cmd->init_task_tag, - hdr->offset, payload_length, cmd->seq_start_offset, + be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset, cmd->seq_end_offset); return DATAOUT_CANNOT_RECOVER; } @@ -236,12 +237,12 @@ static int iscsit_dataout_check_sequence( * fullfilling an Recovery R2T, it's best to just dump the * payload here, instead of erroring out. */ - if ((hdr->offset < cmd->seq_start_offset) || - ((hdr->offset + payload_length) > cmd->seq_end_offset)) { + if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) || + ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) { pr_err("Command ITT: 0x%08x with Offset: %u," " Length: %u outside of Sequence %u:%u while" " DataSequenceInOrder=Yes.\n", cmd->init_task_tag, - hdr->offset, payload_length, cmd->seq_start_offset, + be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset, cmd->seq_end_offset); if (iscsit_dump_data_payload(conn, payload_length, 1) < 0) @@ -251,7 +252,8 @@ static int iscsit_dataout_check_sequence( next_burst_len = (cmd->next_burst_len + payload_length); } else { - seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length); + seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset), + payload_length); if (!seq) return DATAOUT_CANNOT_RECOVER; /* @@ -366,16 +368,16 @@ static int iscsit_dataout_check_datasn( data_sn = seq->data_sn; } - if (hdr->datasn > data_sn) { + if (be32_to_cpu(hdr->datasn) > data_sn) { pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x" " higher than expected 0x%08x.\n", cmd->init_task_tag, - hdr->datasn, data_sn); + be32_to_cpu(hdr->datasn), data_sn); recovery = 1; goto recover; - } else if (hdr->datasn < data_sn) { + } else if (be32_to_cpu(hdr->datasn) < data_sn) { pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x" " lower than expected 0x%08x, discarding payload.\n", - cmd->init_task_tag, hdr->datasn, data_sn); + cmd->init_task_tag, be32_to_cpu(hdr->datasn), data_sn); dump = 1; goto dump; } @@ -415,26 +417,27 @@ static int iscsit_dataout_pre_datapduinorder_yes( * error has occured and fail the connection. */ if (conn->sess->sess_ops->DataSequenceInOrder) { - if (hdr->offset != cmd->write_data_done) { + if (be32_to_cpu(hdr->offset) != cmd->write_data_done) { pr_err("Command ITT: 0x%08x, received offset" " %u different than expected %u.\n", cmd->init_task_tag, - hdr->offset, cmd->write_data_done); + be32_to_cpu(hdr->offset), cmd->write_data_done); recovery = 1; goto recover; } } else { struct iscsi_seq *seq = cmd->seq_ptr; - if (hdr->offset > seq->offset) { + if (be32_to_cpu(hdr->offset) > seq->offset) { pr_err("Command ITT: 0x%08x, received offset" " %u greater than expected %u.\n", cmd->init_task_tag, - hdr->offset, seq->offset); + be32_to_cpu(hdr->offset), seq->offset); recovery = 1; goto recover; - } else if (hdr->offset < seq->offset) { + } else if (be32_to_cpu(hdr->offset) < seq->offset) { pr_err("Command ITT: 0x%08x, received offset" " %u less than expected %u, discarding payload.\n", - cmd->init_task_tag, hdr->offset, seq->offset); + cmd->init_task_tag, be32_to_cpu(hdr->offset), + seq->offset); dump = 1; goto dump; } @@ -453,7 +456,7 @@ dump: return DATAOUT_CANNOT_RECOVER; return (recovery) ? iscsit_recover_dataout_sequence(cmd, - hdr->offset, payload_length) : + be32_to_cpu(hdr->offset), payload_length) : (dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY : DATAOUT_NORMAL; } @@ -465,7 +468,8 @@ static int iscsit_dataout_pre_datapduinorder_no( struct iscsi_data *hdr = (struct iscsi_data *) buf; u32 payload_length = ntoh24(hdr->dlength); - pdu = iscsit_get_pdu_holder(cmd, hdr->offset, payload_length); + pdu = iscsit_get_pdu_holder(cmd, be32_to_cpu(hdr->offset), + payload_length); if (!pdu) return DATAOUT_CANNOT_RECOVER; @@ -479,7 +483,7 @@ static int iscsit_dataout_pre_datapduinorder_no( case ISCSI_PDU_RECEIVED_OK: pr_err("Command ITT: 0x%08x received already gotten" " Offset: %u, Length: %u\n", cmd->init_task_tag, - hdr->offset, payload_length); + be32_to_cpu(hdr->offset), payload_length); return iscsit_dump_data_payload(cmd->conn, payload_length, 1); default: return DATAOUT_CANNOT_RECOVER; @@ -553,7 +557,7 @@ static int iscsit_dataout_post_crc_passed( if (cmd->unsolicited_data) { if ((cmd->first_burst_len + payload_length) == conn->sess->sess_ops->FirstBurstLength) { - if (iscsit_dataout_update_r2t(cmd, hdr->offset, + if (iscsit_dataout_update_r2t(cmd, be32_to_cpu(hdr->offset), payload_length) < 0) return DATAOUT_CANNOT_RECOVER; send_r2t = 1; @@ -561,7 +565,8 @@ static int iscsit_dataout_post_crc_passed( if (!conn->sess->sess_ops->DataPDUInOrder) { ret = iscsit_dataout_update_datapduinorder_no(cmd, - hdr->datasn, (hdr->flags & ISCSI_FLAG_CMD_FINAL)); + be32_to_cpu(hdr->datasn), + (hdr->flags & ISCSI_FLAG_CMD_FINAL)); if (ret == DATAOUT_CANNOT_RECOVER) return ret; } @@ -586,7 +591,8 @@ static int iscsit_dataout_post_crc_passed( if (conn->sess->sess_ops->DataSequenceInOrder) { if ((cmd->next_burst_len + payload_length) == conn->sess->sess_ops->MaxBurstLength) { - if (iscsit_dataout_update_r2t(cmd, hdr->offset, + if (iscsit_dataout_update_r2t(cmd, + be32_to_cpu(hdr->offset), payload_length) < 0) return DATAOUT_CANNOT_RECOVER; send_r2t = 1; @@ -594,7 +600,7 @@ static int iscsit_dataout_post_crc_passed( if (!conn->sess->sess_ops->DataPDUInOrder) { ret = iscsit_dataout_update_datapduinorder_no( - cmd, hdr->datasn, + cmd, be32_to_cpu(hdr->datasn), (hdr->flags & ISCSI_FLAG_CMD_FINAL)); if (ret == DATAOUT_CANNOT_RECOVER) return ret; @@ -610,7 +616,8 @@ static int iscsit_dataout_post_crc_passed( if ((seq->next_burst_len + payload_length) == seq->xfer_len) { - if (iscsit_dataout_update_r2t(cmd, hdr->offset, + if (iscsit_dataout_update_r2t(cmd, + be32_to_cpu(hdr->offset), payload_length) < 0) return DATAOUT_CANNOT_RECOVER; send_r2t = 1; @@ -618,7 +625,7 @@ static int iscsit_dataout_post_crc_passed( if (!conn->sess->sess_ops->DataPDUInOrder) { ret = iscsit_dataout_update_datapduinorder_no( - cmd, hdr->datasn, + cmd, be32_to_cpu(hdr->datasn), (hdr->flags & ISCSI_FLAG_CMD_FINAL)); if (ret == DATAOUT_CANNOT_RECOVER) return ret; @@ -678,14 +685,15 @@ static int iscsit_dataout_post_crc_failed( } recover: - return iscsit_recover_dataout_sequence(cmd, hdr->offset, payload_length); + return iscsit_recover_dataout_sequence(cmd, be32_to_cpu(hdr->offset), + payload_length); } /* * Called from iscsit_handle_data_out() before DataOUT Payload is received * and CRC computed. */ -extern int iscsit_check_pre_dataout( +int iscsit_check_pre_dataout( struct iscsi_cmd *cmd, unsigned char *buf) { @@ -789,7 +797,7 @@ static void iscsit_handle_time2retain_timeout(unsigned long data) target_put_session(sess->se_sess); } -extern void iscsit_start_time2retain_handler(struct iscsi_session *sess) +void iscsit_start_time2retain_handler(struct iscsi_session *sess) { int tpg_active; /* @@ -822,7 +830,7 @@ extern void iscsit_start_time2retain_handler(struct iscsi_session *sess) /* * Called with spin_lock_bh(&struct se_portal_group->session_lock) held */ -extern int iscsit_stop_time2retain_timer(struct iscsi_session *sess) +int iscsit_stop_time2retain_timer(struct iscsi_session *sess) { struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess); struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; @@ -926,7 +934,7 @@ static void iscsit_handle_connection_cleanup(struct iscsi_conn *conn) } } -extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) +void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) { spin_lock_bh(&conn->state_lock); if (atomic_read(&conn->connection_exit)) { diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index 3df8a2cef86f..21f29d91a8cb 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c @@ -466,7 +466,7 @@ static int iscsit_handle_recovery_datain( int iscsit_handle_recovery_datain_or_r2t( struct iscsi_conn *conn, unsigned char *buf, - u32 init_task_tag, + itt_t init_task_tag, u32 targ_xfer_tag, u32 begrun, u32 runlength) @@ -498,7 +498,7 @@ int iscsit_handle_recovery_datain_or_r2t( /* #warning FIXME: Status SNACK needs to be dependent on OPCODE!!! */ int iscsit_handle_status_snack( struct iscsi_conn *conn, - u32 init_task_tag, + itt_t init_task_tag, u32 targ_xfer_tag, u32 begrun, u32 runlength) diff --git a/drivers/target/iscsi/iscsi_target_erl1.h b/drivers/target/iscsi/iscsi_target_erl1.h index 85e67e29de6b..2a3ebf118a34 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.h +++ b/drivers/target/iscsi/iscsi_target_erl1.h @@ -7,8 +7,8 @@ extern int iscsit_create_recovery_datain_values_datasequenceinorder_yes( extern int iscsit_create_recovery_datain_values_datasequenceinorder_no( struct iscsi_cmd *, struct iscsi_datain_req *); extern int iscsit_handle_recovery_datain_or_r2t(struct iscsi_conn *, unsigned char *, - u32, u32, u32, u32); -extern int iscsit_handle_status_snack(struct iscsi_conn *, u32, u32, + itt_t, u32, u32, u32); +extern int iscsit_handle_status_snack(struct iscsi_conn *, itt_t, u32, u32, u32); extern int iscsit_handle_data_ack(struct iscsi_conn *, u32, u32, u32); extern int iscsit_dataout_datapduinorder_no_fbit(struct iscsi_cmd *, struct iscsi_pdu *); diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index 65aac14fd831..17d8c20094fd 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c @@ -36,7 +36,7 @@ */ void iscsit_create_conn_recovery_datain_values( struct iscsi_cmd *cmd, - u32 exp_data_sn) + __be32 exp_data_sn) { u32 data_sn = 0; struct iscsi_conn *conn = cmd->conn; @@ -44,7 +44,7 @@ void iscsit_create_conn_recovery_datain_values( cmd->next_burst_len = 0; cmd->read_data_done = 0; - while (exp_data_sn > data_sn) { + while (be32_to_cpu(exp_data_sn) > data_sn) { if ((cmd->next_burst_len + conn->conn_ops->MaxRecvDataSegmentLength) < conn->sess->sess_ops->MaxBurstLength) { @@ -193,15 +193,13 @@ int iscsit_remove_active_connection_recovery_entry( return 0; } -int iscsit_remove_inactive_connection_recovery_entry( +static void iscsit_remove_inactive_connection_recovery_entry( struct iscsi_conn_recovery *cr, struct iscsi_session *sess) { spin_lock(&sess->cr_i_lock); list_del(&cr->cr_list); spin_unlock(&sess->cr_i_lock); - - return 0; } /* @@ -421,6 +419,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) cr->cid = conn->cid; cr->cmd_count = cmd_count; cr->maxrecvdatasegmentlength = conn->conn_ops->MaxRecvDataSegmentLength; + cr->maxxmitdatasegmentlength = conn->conn_ops->MaxXmitDataSegmentLength; cr->sess = conn->sess; iscsit_attach_inactive_connection_recovery_entry(conn->sess, cr); diff --git a/drivers/target/iscsi/iscsi_target_erl2.h b/drivers/target/iscsi/iscsi_target_erl2.h index 22f8d24780a6..63f2501f3fe0 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.h +++ b/drivers/target/iscsi/iscsi_target_erl2.h @@ -1,7 +1,7 @@ #ifndef ISCSI_TARGET_ERL2_H #define ISCSI_TARGET_ERL2_H -extern void iscsit_create_conn_recovery_datain_values(struct iscsi_cmd *, u32); +extern void iscsit_create_conn_recovery_datain_values(struct iscsi_cmd *, __be32); extern void iscsit_create_conn_recovery_dataout_values(struct iscsi_cmd *); extern struct iscsi_conn_recovery *iscsit_get_inactive_connection_recovery_entry( struct iscsi_session *, u16); diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 6aba4395e8d8..cdc8a10939c3 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -39,10 +39,6 @@ #include "iscsi_target.h" #include "iscsi_target_parameters.h" -extern struct idr sess_idr; -extern struct mutex auth_id_lock; -extern spinlock_t sess_idr_lock; - static int iscsi_login_init_conn(struct iscsi_conn *conn) { INIT_LIST_HEAD(&conn->conn_list); @@ -196,10 +192,10 @@ int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn) static void iscsi_login_set_conn_values( struct iscsi_session *sess, struct iscsi_conn *conn, - u16 cid) + __be16 cid) { conn->sess = sess; - conn->cid = cid; + conn->cid = be16_to_cpu(cid); /* * Generate a random Status sequence number (statsn) for the new * iSCSI connection. @@ -234,7 +230,7 @@ static int iscsi_login_zero_tsih_s1( iscsi_login_set_conn_values(sess, conn, pdu->cid); sess->init_task_tag = pdu->itt; memcpy(&sess->isid, pdu->isid, 6); - sess->exp_cmd_sn = pdu->cmdsn; + sess->exp_cmd_sn = be32_to_cpu(pdu->cmdsn); INIT_LIST_HEAD(&sess->sess_conn_list); INIT_LIST_HEAD(&sess->sess_ooo_cmdsn_list); INIT_LIST_HEAD(&sess->cr_active_list); @@ -275,7 +271,7 @@ static int iscsi_login_zero_tsih_s1( * The FFP CmdSN window values will be allocated from the TPG's * Initiator Node's ACL once the login has been successfully completed. */ - sess->max_cmd_sn = pdu->cmdsn; + sess->max_cmd_sn = be32_to_cpu(pdu->cmdsn); sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL); if (!sess->sess_ops) { @@ -453,7 +449,7 @@ static int iscsi_login_non_zero_tsih_s2( (sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED)) continue; if (!memcmp(sess_p->isid, pdu->isid, 6) && - (sess_p->tsih == pdu->tsih)) { + (sess_p->tsih == be16_to_cpu(pdu->tsih))) { iscsit_inc_session_usage_count(sess_p); iscsit_stop_time2retain_timer(sess_p); sess = sess_p; @@ -955,11 +951,7 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) } pdu = (struct iscsi_login_req *) buffer; - pdu->cid = be16_to_cpu(pdu->cid); - pdu->tsih = be16_to_cpu(pdu->tsih); - pdu->itt = be32_to_cpu(pdu->itt); - pdu->cmdsn = be32_to_cpu(pdu->cmdsn); - pdu->exp_statsn = be32_to_cpu(pdu->exp_statsn); + /* * Used by iscsit_tx_login_rsp() for Login Resonses PDUs * when Status-Class != 0. diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 2dba448cac19..e9053a04f24c 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c @@ -44,7 +44,7 @@ void convert_null_to_semi(char *buf, int len) buf[i] = ';'; } -int strlen_semi(char *buf) +static int strlen_semi(char *buf) { int i = 0; @@ -339,14 +339,14 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log hton24(login_rsp->dlength, login->rsp_length); memcpy(login_rsp->isid, login->isid, 6); login_rsp->tsih = cpu_to_be16(login->tsih); - login_rsp->itt = cpu_to_be32(login->init_task_tag); + login_rsp->itt = login->init_task_tag; login_rsp->statsn = cpu_to_be32(conn->stat_sn++); login_rsp->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); login_rsp->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x," " ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:" - " %u\n", login_rsp->flags, ntohl(login_rsp->itt), + " %u\n", login_rsp->flags, (__force u32)login_rsp->itt, ntohl(login_rsp->exp_cmdsn), ntohl(login_rsp->max_cmdsn), ntohl(login_rsp->statsn), login->rsp_length); @@ -360,12 +360,9 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log return -1; login->rsp_length = 0; - login_rsp->tsih = be16_to_cpu(login_rsp->tsih); - login_rsp->itt = be32_to_cpu(login_rsp->itt); - login_rsp->statsn = be32_to_cpu(login_rsp->statsn); mutex_lock(&sess->cmdsn_mutex); - login_rsp->exp_cmdsn = be32_to_cpu(sess->exp_cmd_sn); - login_rsp->max_cmdsn = be32_to_cpu(sess->max_cmd_sn); + login_rsp->exp_cmdsn = cpu_to_be32(sess->exp_cmd_sn); + login_rsp->max_cmdsn = cpu_to_be32(sess->max_cmd_sn); mutex_unlock(&sess->cmdsn_mutex); return 0; @@ -381,11 +378,6 @@ static int iscsi_target_do_rx_login_io(struct iscsi_conn *conn, struct iscsi_log login_req = (struct iscsi_login_req *) login->req; payload_length = ntoh24(login_req->dlength); - login_req->tsih = be16_to_cpu(login_req->tsih); - login_req->itt = be32_to_cpu(login_req->itt); - login_req->cid = be16_to_cpu(login_req->cid); - login_req->cmdsn = be32_to_cpu(login_req->cmdsn); - login_req->exp_statsn = be32_to_cpu(login_req->exp_statsn); pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x," " CmdSN: 0x%08x, ExpStatSN: 0x%08x, CID: %hu, Length: %u\n", @@ -550,7 +542,7 @@ static int iscsi_target_handle_csg_zero( SENDER_INITIATOR|SENDER_RECEIVER, login->req_buf, payload_length, - conn->param_list); + conn); if (ret < 0) return -1; @@ -627,7 +619,7 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_log SENDER_INITIATOR|SENDER_RECEIVER, login->req_buf, payload_length, - conn->param_list); + conn); if (ret < 0) return -1; @@ -762,11 +754,11 @@ static int iscsi_target_locate_portal( login->version_min = login_req->min_version; login->version_max = login_req->max_version; memcpy(login->isid, login_req->isid, 6); - login->cmd_sn = login_req->cmdsn; + login->cmd_sn = be32_to_cpu(login_req->cmdsn); login->init_task_tag = login_req->itt; - login->initial_exp_statsn = login_req->exp_statsn; - login->cid = login_req->cid; - login->tsih = login_req->tsih; + login->initial_exp_statsn = be32_to_cpu(login_req->exp_statsn); + login->cid = be16_to_cpu(login_req->cid); + login->tsih = be16_to_cpu(login_req->tsih); if (iscsi_target_get_initial_payload(conn, login) < 0) return -1; @@ -1000,7 +992,6 @@ struct iscsi_login *iscsi_target_init_negotiation( * Locates Target Portal from NP -> Target IQN */ if (iscsi_target_locate_portal(np, conn, login) < 0) { - pr_err("iSCSI Login negotiation failed.\n"); goto out; } diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index 1e5c5a8587ac..1bf7432bfcbc 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c @@ -334,6 +334,13 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr) if (!param) goto out; + param = iscsi_set_default_param(pl, MAXXMITDATASEGMENTLENGTH, + INITIAL_MAXXMITDATASEGMENTLENGTH, + PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, + TYPERANGE_512_TO_16777215, USE_ALL); + if (!param) + goto out; + param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH, INITIAL_MAXRECVDATASEGMENTLENGTH, PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, @@ -467,6 +474,8 @@ int iscsi_set_keys_to_negotiate( SET_PSTATE_NEGOTIATE(param); } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { SET_PSTATE_NEGOTIATE(param); + } else if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) { + continue; } else if (!strcmp(param->name, MAXBURSTLENGTH)) { SET_PSTATE_NEGOTIATE(param); } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) { @@ -1056,7 +1065,8 @@ out: return proposer_values; } -static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value) +static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value, + struct iscsi_conn *conn) { u8 acceptor_boolean_value = 0, proposer_boolean_value = 0; char *negoitated_value = NULL; @@ -1131,8 +1141,35 @@ static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value) return -1; } - if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) - SET_PSTATE_REPLY_OPTIONAL(param); + if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { + struct iscsi_param *param_mxdsl; + unsigned long long tmp; + int rc; + + rc = strict_strtoull(param->value, 0, &tmp); + if (rc < 0) + return -1; + + conn->conn_ops->MaxRecvDataSegmentLength = tmp; + pr_debug("Saving op->MaxRecvDataSegmentLength from" + " original initiator received value: %u\n", + conn->conn_ops->MaxRecvDataSegmentLength); + + param_mxdsl = iscsi_find_param_from_key( + MAXXMITDATASEGMENTLENGTH, + conn->param_list); + if (!param_mxdsl) + return -1; + + rc = iscsi_update_param_value(param, + param_mxdsl->value); + if (rc < 0) + return -1; + + pr_debug("Updated %s to target MXDSL value: %s\n", + param->name, param->value); + } + } else if (IS_TYPE_NUMBER_RANGE(param)) { negoitated_value = iscsi_get_value_from_number_range( param, value); @@ -1527,8 +1564,9 @@ int iscsi_decode_text_input( u8 sender, char *textbuf, u32 length, - struct iscsi_param_list *param_list) + struct iscsi_conn *conn) { + struct iscsi_param_list *param_list = conn->param_list; char *tmpbuf, *start = NULL, *end = NULL; tmpbuf = kzalloc(length + 1, GFP_KERNEL); @@ -1586,7 +1624,7 @@ int iscsi_decode_text_input( } SET_PSTATE_RESPONSE_GOT(param); } else { - if (iscsi_check_acceptor_state(param, value) < 0) { + if (iscsi_check_acceptor_state(param, value, conn) < 0) { kfree(tmpbuf); return -1; } @@ -1721,6 +1759,18 @@ void iscsi_set_connection_parameters( pr_debug("---------------------------------------------------" "---------------\n"); list_for_each_entry(param, ¶m_list->param_list, p_list) { + /* + * Special case to set MAXXMITDATASEGMENTLENGTH from the + * target requested MaxRecvDataSegmentLength, even though + * this key is not sent over the wire. + */ + if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) { + ops->MaxXmitDataSegmentLength = + simple_strtoul(param->value, &tmpptr, 0); + pr_debug("MaxXmitDataSegmentLength: %s\n", + param->value); + } + if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param)) continue; if (!strcmp(param->name, AUTHMETHOD)) { @@ -1735,10 +1785,13 @@ void iscsi_set_connection_parameters( pr_debug("DataDigest: %s\n", param->value); } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { - ops->MaxRecvDataSegmentLength = - simple_strtoul(param->value, &tmpptr, 0); - pr_debug("MaxRecvDataSegmentLength: %s\n", - param->value); + /* + * At this point iscsi_check_acceptor_state() will have + * set ops->MaxRecvDataSegmentLength from the original + * initiator provided value. + */ + pr_debug("MaxRecvDataSegmentLength: %u\n", + ops->MaxRecvDataSegmentLength); } else if (!strcmp(param->name, OFMARKER)) { ops->OFMarker = !strcmp(param->value, YES); pr_debug("OFMarker: %s\n", diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h index 6a37fd6f1285..1e1b7504a76b 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.h +++ b/drivers/target/iscsi/iscsi_target_parameters.h @@ -36,7 +36,7 @@ extern void iscsi_release_param_list(struct iscsi_param_list *); extern struct iscsi_param *iscsi_find_param_from_key(char *, struct iscsi_param_list *); extern int iscsi_extract_key_value(char *, char **, char **); extern int iscsi_update_param_value(struct iscsi_param *, char *); -extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_param_list *); +extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *); extern int iscsi_encode_text_output(u8, u8, char *, u32 *, struct iscsi_param_list *); extern int iscsi_check_negotiated_keys(struct iscsi_param_list *); @@ -70,6 +70,7 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *, #define INITIALR2T "InitialR2T" #define IMMEDIATEDATA "ImmediateData" #define MAXRECVDATASEGMENTLENGTH "MaxRecvDataSegmentLength" +#define MAXXMITDATASEGMENTLENGTH "MaxXmitDataSegmentLength" #define MAXBURSTLENGTH "MaxBurstLength" #define FIRSTBURSTLENGTH "FirstBurstLength" #define DEFAULTTIME2WAIT "DefaultTime2Wait" @@ -113,6 +114,10 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *, #define INITIAL_INITIALR2T YES #define INITIAL_IMMEDIATEDATA YES #define INITIAL_MAXRECVDATASEGMENTLENGTH "8192" +/* + * Match outgoing MXDSL default to incoming Open-iSCSI default + */ +#define INITIAL_MAXXMITDATASEGMENTLENGTH "262144" #define INITIAL_MAXBURSTLENGTH "262144" #define INITIAL_FIRSTBURSTLENGTH "65536" #define INITIAL_DEFAULTTIME2WAIT "2" diff --git a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c index 85a306e067ba..edb592a368ef 100644 --- a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c +++ b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c @@ -219,8 +219,14 @@ static void iscsit_determine_counts_for_list( int check_immediate = 0; u32 burstlength = 0, offset = 0; u32 unsolicited_data_length = 0; + u32 mdsl; struct iscsi_conn *conn = cmd->conn; + if (cmd->se_cmd.data_direction == DMA_TO_DEVICE) + mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength; + else + mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength; + if ((bl->type == PDULIST_IMMEDIATE) || (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED)) check_immediate = 1; @@ -243,14 +249,13 @@ static void iscsit_determine_counts_for_list( continue; } if (unsolicited_data_length > 0) { - if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) - >= cmd->se_cmd.data_length) { + if ((offset + mdsl) >= cmd->se_cmd.data_length) { unsolicited_data_length -= (cmd->se_cmd.data_length - offset); offset += (cmd->se_cmd.data_length - offset); continue; } - if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) + if ((offset + mdsl) >= conn->sess->sess_ops->FirstBurstLength) { unsolicited_data_length -= (conn->sess->sess_ops->FirstBurstLength - @@ -262,17 +267,15 @@ static void iscsit_determine_counts_for_list( continue; } - offset += conn->conn_ops->MaxRecvDataSegmentLength; - unsolicited_data_length -= - conn->conn_ops->MaxRecvDataSegmentLength; + offset += mdsl; + unsolicited_data_length -= mdsl; continue; } - if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >= - cmd->se_cmd.data_length) { + if ((offset + mdsl) >= cmd->se_cmd.data_length) { offset += (cmd->se_cmd.data_length - offset); continue; } - if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >= + if ((burstlength + mdsl) >= conn->sess->sess_ops->MaxBurstLength) { offset += (conn->sess->sess_ops->MaxBurstLength - burstlength); @@ -281,8 +284,8 @@ static void iscsit_determine_counts_for_list( continue; } - burstlength += conn->conn_ops->MaxRecvDataSegmentLength; - offset += conn->conn_ops->MaxRecvDataSegmentLength; + burstlength += mdsl; + offset += mdsl; } } @@ -296,12 +299,17 @@ static int iscsit_do_build_pdu_and_seq_lists( struct iscsi_build_list *bl) { int check_immediate = 0, datapduinorder, datasequenceinorder; - u32 burstlength = 0, offset = 0, i = 0; + u32 burstlength = 0, offset = 0, i = 0, mdsl; u32 pdu_count = 0, seq_no = 0, unsolicited_data_length = 0; struct iscsi_conn *conn = cmd->conn; struct iscsi_pdu *pdu = cmd->pdu_list; struct iscsi_seq *seq = cmd->seq_list; + if (cmd->se_cmd.data_direction == DMA_TO_DEVICE) + mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength; + else + mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength; + datapduinorder = conn->sess->sess_ops->DataPDUInOrder; datasequenceinorder = conn->sess->sess_ops->DataSequenceInOrder; @@ -348,9 +356,7 @@ static int iscsit_do_build_pdu_and_seq_lists( continue; } if (unsolicited_data_length > 0) { - if ((offset + - conn->conn_ops->MaxRecvDataSegmentLength) >= - cmd->se_cmd.data_length) { + if ((offset + mdsl) >= cmd->se_cmd.data_length) { if (!datapduinorder) { pdu[i].type = PDUTYPE_UNSOLICITED; pdu[i].length = @@ -367,8 +373,7 @@ static int iscsit_do_build_pdu_and_seq_lists( offset += (cmd->se_cmd.data_length - offset); continue; } - if ((offset + - conn->conn_ops->MaxRecvDataSegmentLength) >= + if ((offset + mdsl) >= conn->sess->sess_ops->FirstBurstLength) { if (!datapduinorder) { pdu[i].type = PDUTYPE_UNSOLICITED; @@ -396,17 +401,14 @@ static int iscsit_do_build_pdu_and_seq_lists( if (!datapduinorder) { pdu[i].type = PDUTYPE_UNSOLICITED; - pdu[i++].length = - conn->conn_ops->MaxRecvDataSegmentLength; + pdu[i++].length = mdsl; } - burstlength += conn->conn_ops->MaxRecvDataSegmentLength; - offset += conn->conn_ops->MaxRecvDataSegmentLength; - unsolicited_data_length -= - conn->conn_ops->MaxRecvDataSegmentLength; + burstlength += mdsl; + offset += mdsl; + unsolicited_data_length -= mdsl; continue; } - if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >= - cmd->se_cmd.data_length) { + if ((offset + mdsl) >= cmd->se_cmd.data_length) { if (!datapduinorder) { pdu[i].type = PDUTYPE_NORMAL; pdu[i].length = (cmd->se_cmd.data_length - offset); @@ -420,7 +422,7 @@ static int iscsit_do_build_pdu_and_seq_lists( offset += (cmd->se_cmd.data_length - offset); continue; } - if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >= + if ((burstlength + mdsl) >= conn->sess->sess_ops->MaxBurstLength) { if (!datapduinorder) { pdu[i].type = PDUTYPE_NORMAL; @@ -445,11 +447,10 @@ static int iscsit_do_build_pdu_and_seq_lists( if (!datapduinorder) { pdu[i].type = PDUTYPE_NORMAL; - pdu[i++].length = - conn->conn_ops->MaxRecvDataSegmentLength; + pdu[i++].length = mdsl; } - burstlength += conn->conn_ops->MaxRecvDataSegmentLength; - offset += conn->conn_ops->MaxRecvDataSegmentLength; + burstlength += mdsl; + offset += mdsl; } if (!datasequenceinorder) { diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c index f62fe123d902..4a99820d063b 100644 --- a/drivers/target/iscsi/iscsi_target_tmr.c +++ b/drivers/target/iscsi/iscsi_target_tmr.c @@ -50,21 +50,20 @@ u8 iscsit_tmr_abort_task( if (!ref_cmd) { pr_err("Unable to locate RefTaskTag: 0x%08x on CID:" " %hu.\n", hdr->rtt, conn->cid); - return ((hdr->refcmdsn >= conn->sess->exp_cmd_sn) && - (hdr->refcmdsn <= conn->sess->max_cmd_sn)) ? + return (be32_to_cpu(hdr->refcmdsn) >= conn->sess->exp_cmd_sn && + be32_to_cpu(hdr->refcmdsn) <= conn->sess->max_cmd_sn) ? ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK; } - if (ref_cmd->cmd_sn != hdr->refcmdsn) { + if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) { pr_err("RefCmdSN 0x%08x does not equal" " task's CmdSN 0x%08x. Rejecting ABORT_TASK.\n", hdr->refcmdsn, ref_cmd->cmd_sn); return ISCSI_TMF_RSP_REJECTED; } - se_tmr->ref_task_tag = hdr->rtt; + se_tmr->ref_task_tag = (__force u32)hdr->rtt; tmr_req->ref_cmd = ref_cmd; - tmr_req->ref_cmd_sn = hdr->refcmdsn; - tmr_req->exp_data_sn = hdr->exp_datasn; + tmr_req->exp_data_sn = be32_to_cpu(hdr->exp_datasn); return ISCSI_TMF_RSP_COMPLETE; } @@ -146,7 +145,7 @@ u8 iscsit_tmr_task_reassign( } /* * Temporary check to prevent connection recovery for - * connections with a differing MaxRecvDataSegmentLength. + * connections with a differing Max*DataSegmentLength. */ if (cr->maxrecvdatasegmentlength != conn->conn_ops->MaxRecvDataSegmentLength) { @@ -155,6 +154,13 @@ u8 iscsit_tmr_task_reassign( " TMR TASK_REASSIGN.\n"); return ISCSI_TMF_RSP_REJECTED; } + if (cr->maxxmitdatasegmentlength != + conn->conn_ops->MaxXmitDataSegmentLength) { + pr_err("Unable to perform connection recovery for" + " differing MaxXmitDataSegmentLength, rejecting" + " TMR TASK_REASSIGN.\n"); + return ISCSI_TMF_RSP_REJECTED; + } ref_lun = scsilun_to_int(&hdr->lun); if (ref_lun != ref_cmd->se_cmd.orig_fe_lun) { @@ -164,10 +170,9 @@ u8 iscsit_tmr_task_reassign( return ISCSI_TMF_RSP_REJECTED; } - se_tmr->ref_task_tag = hdr->rtt; + se_tmr->ref_task_tag = (__force u32)hdr->rtt; tmr_req->ref_cmd = ref_cmd; - tmr_req->ref_cmd_sn = hdr->refcmdsn; - tmr_req->exp_data_sn = hdr->exp_datasn; + tmr_req->exp_data_sn = be32_to_cpu(hdr->exp_datasn); tmr_req->conn_recovery = cr; tmr_req->task_reassign = 1; /* @@ -455,7 +460,7 @@ static int iscsit_task_reassign_complete( * Right now the only one that its really needed for is * connection recovery releated TASK_REASSIGN. */ -extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn) +int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn) { struct iscsi_tmr_req *tmr_req = cmd->tmr_req; struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req; @@ -470,7 +475,7 @@ extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *con /* * Nothing to do here, but leave it for good measure. :-) */ -int iscsit_task_reassign_prepare_read( +static int iscsit_task_reassign_prepare_read( struct iscsi_tmr_req *tmr_req, struct iscsi_conn *conn) { @@ -545,7 +550,7 @@ static void iscsit_task_reassign_prepare_unsolicited_dataout( } } -int iscsit_task_reassign_prepare_write( +static int iscsit_task_reassign_prepare_write( struct iscsi_tmr_req *tmr_req, struct iscsi_conn *conn) { diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index a38a3f8ab0d9..de9ea32b6104 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -677,6 +677,12 @@ int iscsit_ta_generate_node_acls( pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n", tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled"); + if (flag == 1 && a->cache_dynamic_acls == 0) { + pr_debug("Explicitly setting cache_dynamic_acls=1 when " + "generate_node_acls=1\n"); + a->cache_dynamic_acls = 1; + } + return 0; } @@ -716,6 +722,12 @@ int iscsit_ta_cache_dynamic_acls( return -EINVAL; } + if (a->generate_node_acls == 1 && flag == 0) { + pr_debug("Skipping cache_dynamic_acls=0 when" + " generate_node_acls=1\n"); + return 0; + } + a->cache_dynamic_acls = flag; pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group" " ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ? diff --git a/drivers/target/iscsi/iscsi_target_tq.c b/drivers/target/iscsi/iscsi_target_tq.c index 977e1cf90e83..9d881a000e42 100644 --- a/drivers/target/iscsi/iscsi_target_tq.c +++ b/drivers/target/iscsi/iscsi_target_tq.c @@ -40,7 +40,7 @@ static void iscsi_add_ts_to_active_list(struct iscsi_thread_set *ts) spin_unlock(&active_ts_lock); } -extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts) +static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts) { spin_lock(&inactive_ts_lock); list_add_tail(&ts->ts_list, &inactive_ts_list); @@ -76,7 +76,7 @@ static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) return ts; } -extern int iscsi_allocate_thread_sets(u32 thread_pair_count) +int iscsi_allocate_thread_sets(u32 thread_pair_count) { int allocated_thread_pair_count = 0, i, thread_id; struct iscsi_thread_set *ts = NULL; @@ -140,7 +140,7 @@ extern int iscsi_allocate_thread_sets(u32 thread_pair_count) return allocated_thread_pair_count; } -extern void iscsi_deallocate_thread_sets(void) +void iscsi_deallocate_thread_sets(void) { u32 released_count = 0; struct iscsi_thread_set *ts = NULL; diff --git a/drivers/target/iscsi/iscsi_target_tq.h b/drivers/target/iscsi/iscsi_target_tq.h index 26e6a95ec203..547d11831282 100644 --- a/drivers/target/iscsi/iscsi_target_tq.h +++ b/drivers/target/iscsi/iscsi_target_tq.h @@ -5,7 +5,6 @@ * Defines for thread sets. */ extern int iscsi_thread_set_force_reinstatement(struct iscsi_conn *); -extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *); extern int iscsi_allocate_thread_sets(u32); extern void iscsi_deallocate_thread_sets(void); extern void iscsi_activate_thread_set(struct iscsi_conn *, struct iscsi_thread_set *); diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index b42cdeb153df..afd98ccd40ae 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -274,14 +274,14 @@ static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cm int iscsit_sequence_cmd( struct iscsi_conn *conn, struct iscsi_cmd *cmd, - u32 cmdsn) + __be32 cmdsn) { int ret; int cmdsn_ret; mutex_lock(&conn->sess->cmdsn_mutex); - cmdsn_ret = iscsit_check_received_cmdsn(conn->sess, cmdsn); + cmdsn_ret = iscsit_check_received_cmdsn(conn->sess, be32_to_cpu(cmdsn)); switch (cmdsn_ret) { case CMDSN_NORMAL_OPERATION: ret = iscsit_execute_cmd(cmd, 0); @@ -289,7 +289,7 @@ int iscsit_sequence_cmd( iscsit_execute_ooo_cmdsns(conn->sess); break; case CMDSN_HIGHER_THAN_EXP: - ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, cmdsn); + ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, be32_to_cpu(cmdsn)); break; case CMDSN_LOWER_THAN_EXP: cmd->i_state = ISTATE_REMOVE; @@ -351,7 +351,7 @@ int iscsit_check_unsolicited_dataout(struct iscsi_cmd *cmd, unsigned char *buf) struct iscsi_cmd *iscsit_find_cmd_from_itt( struct iscsi_conn *conn, - u32 init_task_tag) + itt_t init_task_tag) { struct iscsi_cmd *cmd; @@ -371,7 +371,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt( struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump( struct iscsi_conn *conn, - u32 init_task_tag, + itt_t init_task_tag, u32 length) { struct iscsi_cmd *cmd; @@ -417,7 +417,7 @@ int iscsit_find_cmd_for_recovery( struct iscsi_session *sess, struct iscsi_cmd **cmd_ptr, struct iscsi_conn_recovery **cr_ptr, - u32 init_task_tag) + itt_t init_task_tag) { struct iscsi_cmd *cmd = NULL; struct iscsi_conn_recovery *cr; @@ -855,7 +855,7 @@ static int iscsit_add_nopin(struct iscsi_conn *conn, int want_response) cmd->iscsi_opcode = ISCSI_OP_NOOP_IN; state = (want_response) ? ISTATE_SEND_NOPIN_WANT_RESPONSE : ISTATE_SEND_NOPIN_NO_RESPONSE; - cmd->init_task_tag = 0xFFFFFFFF; + cmd->init_task_tag = RESERVED_ITT; spin_lock_bh(&conn->sess->ttt_lock); cmd->targ_xfer_tag = (want_response) ? conn->sess->targ_xfer_tag++ : 0xFFFFFFFF; @@ -1222,7 +1222,7 @@ int iscsit_tx_login_rsp(struct iscsi_conn *conn, u8 status_class, u8 status_deta hdr->opcode = ISCSI_OP_LOGIN_RSP; hdr->status_class = status_class; hdr->status_detail = status_detail; - hdr->itt = cpu_to_be32(conn->login_itt); + hdr->itt = conn->login_itt; iov.iov_base = &iscsi_hdr; iov.iov_len = ISCSI_HDR_LEN; diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index e1c729b8a1c5..44054bd35437 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h @@ -12,14 +12,14 @@ extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t); extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32); extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *); extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32); -int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, u32 cmdsn); +int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, __be32 cmdsn); extern int iscsit_check_unsolicited_dataout(struct iscsi_cmd *, unsigned char *); -extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, u32); +extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t); extern struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *, - u32, u32); + itt_t, u32); extern struct iscsi_cmd *iscsit_find_cmd_from_ttt(struct iscsi_conn *, u32); extern int iscsit_find_cmd_for_recovery(struct iscsi_session *, struct iscsi_cmd **, - struct iscsi_conn_recovery **, u32); + struct iscsi_conn_recovery **, itt_t); extern void iscsit_add_cmd_to_immediate_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *); extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); |