diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-10 19:52:19 +0900 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-10 19:52:19 +0900 |
commit | a188e7e93a36627fb3f0013f41857ab54f076d04 (patch) | |
tree | 7686a0e870decdab3971db709fb0edf04241c07e /drivers | |
parent | e1b28147f684af67bfac989756c27c19859d3d4e (diff) | |
parent | cf0eb28d3ba60098865bf7dbcbfdd6b1cc483e3b (diff) | |
download | op-kernel-dev-a188e7e93a36627fb3f0013f41857ab54f076d04.zip op-kernel-dev-a188e7e93a36627fb3f0013f41857ab54f076d04.tar.gz |
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull scsi target updates from Nicholas Bellinger:
"Things have been calm for the most part with no new fabric drivers in
flight for v3.7 (we're up to eight now !), so this update is primarily
focused on addressing a few long-standing items within target-core and
iscsi-target fabric code.
The highlights include:
- target: Simplify fabric sense data length handling (roland)
- qla2xxx: Fix endianness of task management response code (roland)
- target: fix truncation of mode data, support zero allocation length
(paolo)
- target: Properly support zero-length commands in normal processing
path (paolo)
- iscsi-target: Correctly set 0xffffffff field within ISCSI_OP_REJECT
PDU (ronnie + nab)
- iscsi-target: Add explicit set of cache_dynamic_acls=1 for TPG
demo-mode (ronnie + nab)
- target/file: Re-enable optional fd_buffered_io=1 operation (nab +
hch)
- iscsi-target: Add MaxXmitDataSegmenthLength forr target ->
initiator MDRSL declaration (nab)
- target: Add target_submit_cmd_map_sgls for SGL fabric memory
passthrough (nab + hch)
- tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls (hch +
nab)
- tcm_vhost: Convert I/O path to use target_submit_cmd_map_sgls (nab
+ hch)
The last series for adding a new target_submit_cmd_map_sgls() fabric
caller (as requested by hch) that accepts pre-allocated SGL memory
(using existing logic), along with converting tcm_loop + tcm_vhost has
only been in -next for the last days, but has gotten enough review
+testing and is clear enough a mechanical change that I think it's
reasonable to merge for -rc1 code.
Thanks again to everyone who contributed this round! Extra special
thanks to Roland (PureStorage) for tracking down the qla2xxx target
TMR response code endian issue, and to Paolo (Redhat) for resolving
the long standing zero-length CDB issues within target-core between
virtual and pSCSI backends."
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (44 commits)
iscsi-target: Bump defaults for nopin_timeout + nopin_response_timeout values
iscsit: proper endianess conversions
iscsit: use the itt_t abstract type
iscsit: add missing endianess conversion in iscsit_check_inaddr_any
iscsit: remove incorrect unlock in iscsit_build_sendtargets_resp
iscsit: mark various functions static
target/iscsi: precedence bug in iscsit_set_dataout_sequence_values()
target/usb-gadget: strlen() doesn't count the terminator
target/usb-gadget: remove duplicate initialization
tcm_vhost: Convert I/O path to use target_submit_cmd_map_sgls
target: Add control CDB READ payload zero work-around
tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls
target: Add target_submit_cmd_map_sgls for SGL fabric memory passthrough
iscsi-target: Add explicit set of cache_dynamic_acls=1 for TPG demo-mode
iscsi-target: Change iscsi_target_seq_pdu_list.c to honor MaxXmitDataSegmentLength
iscsi-target: Add MaxXmitDataSegmentLength connection recovery check
iscsi-target: Convert incoming PDU payload checks to MaxXmitDataSegmentLength
iscsi-target: Enable MaxXmitDataSegmentLength operation in login path
iscsi-target: Add base MaxXmitDataSegmentLength code
target/file: Re-enable optional fd_buffered_io=1 operation
...
Diffstat (limited to 'drivers')
47 files changed, 637 insertions, 714 deletions
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 9e1449f..cf23c46 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3564,16 +3564,6 @@ static int srpt_get_tcm_cmd_state(struct se_cmd *se_cmd) return srpt_get_cmd_state(ioctx); } -static u16 srpt_set_fabric_sense_len(struct se_cmd *cmd, u32 sense_length) -{ - return 0; -} - -static u16 srpt_get_fabric_sense_len(void) -{ - return 0; -} - /** * srpt_parse_i_port_id() - Parse an initiator port ID. * @name: ASCII representation of a 128-bit initiator port ID. @@ -3953,8 +3943,6 @@ static struct target_core_fabric_ops srpt_template = { .queue_data_in = srpt_queue_response, .queue_status = srpt_queue_status, .queue_tm_rsp = srpt_queue_response, - .get_fabric_sense_len = srpt_get_fabric_sense_len, - .set_fabric_sense_len = srpt_set_fabric_sense_len, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index bddc97c..0e09d8f 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1403,7 +1403,7 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha, ctio->u.status1.scsi_status = __constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID); ctio->u.status1.response_len = __constant_cpu_to_le16(8); - ((uint32_t *)ctio->u.status1.sense_data)[0] = cpu_to_be32(resp_code); + ctio->u.status1.sense_data[0] = resp_code; qla2x00_start_iocbs(ha, ha->req); } diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 4752f65..2358c16 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -735,17 +735,6 @@ static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) return 0; } -static u16 tcm_qla2xxx_get_fabric_sense_len(void) -{ - return 0; -} - -static u16 tcm_qla2xxx_set_fabric_sense_len(struct se_cmd *se_cmd, - u32 sense_length) -{ - return 0; -} - /* Local pointer to allocated TCM configfs fabric module */ struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs; struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs; @@ -1691,8 +1680,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = { .queue_data_in = tcm_qla2xxx_queue_data_in, .queue_status = tcm_qla2xxx_queue_status, .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, - .get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len, - .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c @@ -1740,8 +1727,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { .queue_data_in = tcm_qla2xxx_queue_data_in, .queue_status = tcm_qla2xxx_queue_status, .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, - .get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len, - .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 97c0f78..d6ce218 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 12abb4c..f1e4f31 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 a7b25e78..ff6fd4f 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 8a908b2..2ba9f9b 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 1a02016..8aacf61 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 3df8a2c..21f29d9 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 85e67e2..2a3ebf1 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 65aac14..17d8c20 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 22f8d24..63f2501 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 6aba439..cdc8a10 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 2dba448..e9053a0 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 240f7aa..90b7400 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); @@ -1526,8 +1563,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); @@ -1585,7 +1623,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; } @@ -1720,6 +1758,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)) { @@ -1734,10 +1784,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 6a37fd6..1e1b750 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 85a306e..edb592a 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 f62fe12..4a99820 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 a38a3f8..de9ea32 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 977e1cf..9d881a0 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 26e6a95..547d118 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 b42cdeb..afd98cc 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 e1c729b..44054bd3 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); diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 5491c63..2d444b1 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -166,7 +166,7 @@ static void tcm_loop_submission_work(struct work_struct *work) struct tcm_loop_tpg *tl_tpg; struct scatterlist *sgl_bidi = NULL; u32 sgl_bidi_count = 0; - int ret; + int rc; tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; @@ -187,12 +187,6 @@ static void tcm_loop_submission_work(struct work_struct *work) set_host_byte(sc, DID_ERROR); goto out_done; } - - transport_init_se_cmd(se_cmd, tl_tpg->tl_se_tpg.se_tpg_tfo, - tl_nexus->se_sess, - scsi_bufflen(sc), sc->sc_data_direction, - tcm_loop_sam_attr(sc), &tl_cmd->tl_sense_buf[0]); - if (scsi_bidi_cmnd(sc)) { struct scsi_data_buffer *sdb = scsi_in(sc); @@ -201,56 +195,16 @@ static void tcm_loop_submission_work(struct work_struct *work) se_cmd->se_cmd_flags |= SCF_BIDI; } - - if (transport_lookup_cmd_lun(se_cmd, tl_cmd->sc->device->lun) < 0) { - kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); + rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd, + &tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun, + scsi_bufflen(sc), tcm_loop_sam_attr(sc), + sc->sc_data_direction, 0, + scsi_sglist(sc), scsi_sg_count(sc), + sgl_bidi, sgl_bidi_count); + if (rc < 0) { set_host_byte(sc, DID_NO_CONNECT); goto out_done; } - - /* - * Because some userspace code via scsi-generic do not memset their - * associated read buffers, go ahead and do that here for type - * non-data CDBs. Also note that this is currently guaranteed to be a - * single SGL for this case by target core in - * target_setup_cmd_from_cdb() -> transport_generic_cmd_sequencer(). - */ - if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && - se_cmd->data_direction == DMA_FROM_DEVICE) { - struct scatterlist *sg = scsi_sglist(sc); - unsigned char *buf = kmap(sg_page(sg)) + sg->offset; - - if (buf != NULL) { - memset(buf, 0, sg->length); - kunmap(sg_page(sg)); - } - } - - ret = target_setup_cmd_from_cdb(se_cmd, sc->cmnd); - if (ret == -ENOMEM) { - transport_send_check_condition_and_sense(se_cmd, - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } else if (ret < 0) { - if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) - tcm_loop_queue_status(se_cmd); - else - transport_send_check_condition_and_sense(se_cmd, - se_cmd->scsi_sense_reason, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } - - ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), - scsi_sg_count(sc), sgl_bidi, sgl_bidi_count); - if (ret) { - transport_send_check_condition_and_sense(se_cmd, - se_cmd->scsi_sense_reason, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } - transport_handle_cdb_direct(se_cmd); return; out_done: @@ -846,16 +800,6 @@ static int tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd) return 0; } -static u16 tcm_loop_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) -{ - return 0; -} - -static u16 tcm_loop_get_fabric_sense_len(void) -{ - return 0; -} - static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba) { switch (tl_hba->tl_proto_id) { @@ -1373,8 +1317,6 @@ static int tcm_loop_register_configfs(void) fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in; fabric->tf_ops.queue_status = &tcm_loop_queue_status; fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp; - fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len; - fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len; /* * Setup function pointers for generic logic in target_core_fabric_configfs.c diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 39ddba5..0d6d7c1 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -660,8 +660,7 @@ static void session_reconnect_expired(struct sbp_session *sess) spin_lock_bh(&sess->lock); list_for_each_entry_safe(login, temp, &sess->login_list, link) { login->sess = NULL; - list_del(&login->link); - list_add_tail(&login->link, &login_list); + list_move_tail(&login->link, &login_list); } spin_unlock_bh(&sess->lock); @@ -1847,16 +1846,6 @@ static int sbp_queue_tm_rsp(struct se_cmd *se_cmd) return 0; } -static u16 sbp_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) -{ - return 0; -} - -static u16 sbp_get_fabric_sense_len(void) -{ - return 0; -} - static int sbp_check_stop_free(struct se_cmd *se_cmd) { struct sbp_target_request *req = container_of(se_cmd, @@ -2068,7 +2057,7 @@ static int sbp_update_unit_directory(struct sbp_tport *tport) return ret; } -static ssize_t sbp_parse_wwn(const char *name, u64 *wwn, int strict) +static ssize_t sbp_parse_wwn(const char *name, u64 *wwn) { const char *cp; char c, nibble; @@ -2088,7 +2077,7 @@ static ssize_t sbp_parse_wwn(const char *name, u64 *wwn, int strict) err = 3; if (isdigit(c)) nibble = c - '0'; - else if (isxdigit(c) && (islower(c) || !strict)) + else if (isxdigit(c)) nibble = tolower(c) - 'a' + 10; else goto fail; @@ -2117,7 +2106,7 @@ static struct se_node_acl *sbp_make_nodeacl( u64 guid = 0; u32 nexus_depth = 1; - if (sbp_parse_wwn(name, &guid, 1) < 0) + if (sbp_parse_wwn(name, &guid) < 0) return ERR_PTR(-EINVAL); se_nacl_new = sbp_alloc_fabric_acl(se_tpg); @@ -2253,7 +2242,7 @@ static struct se_wwn *sbp_make_tport( struct sbp_tport *tport; u64 guid = 0; - if (sbp_parse_wwn(name, &guid, 1) < 0) + if (sbp_parse_wwn(name, &guid) < 0) return ERR_PTR(-EINVAL); tport = kzalloc(sizeof(*tport), GFP_KERNEL); @@ -2534,8 +2523,6 @@ static struct target_core_fabric_ops sbp_ops = { .queue_data_in = sbp_queue_data_in, .queue_status = sbp_queue_status, .queue_tm_rsp = sbp_queue_tm_rsp, - .get_fabric_sense_len = sbp_get_fabric_sense_len, - .set_fabric_sense_len = sbp_set_fabric_sense_len, .check_stop_free = sbp_check_stop_free, .fabric_make_wwn = sbp_make_tport, @@ -2556,9 +2543,9 @@ static int sbp_register_configfs(void) int ret; fabric = target_fabric_configfs_init(THIS_MODULE, "sbp"); - if (!fabric) { + if (IS_ERR(fabric)) { pr_err("target_fabric_configfs_init() failed\n"); - return -ENOMEM; + return PTR_ERR(fabric); } fabric->tf_ops = sbp_ops; diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 41641ba..9a5f9a7 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -344,7 +344,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) */ rtpi = get_unaligned_be16(ptr + 2); /* - * Locate the matching relative target port identifer + * Locate the matching relative target port identifier * for the struct se_device storage object. */ spin_lock(&dev->se_port_lock); diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 801efa8..015f5be 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -457,14 +457,6 @@ static int target_fabric_tf_ops_check( pr_err("Missing tfo->queue_tm_rsp()\n"); return -EINVAL; } - if (!tfo->set_fabric_sense_len) { - pr_err("Missing tfo->set_fabric_sense_len()\n"); - return -EINVAL; - } - if (!tfo->get_fabric_sense_len) { - pr_err("Missing tfo->get_fabric_sense_len()\n"); - return -EINVAL; - } /* * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn() * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in @@ -1208,7 +1200,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port( " Target Node Endpoint: %s\n", tfo->get_fabric_name(), tfo->tpg_get_wwn(se_tpg)); len += sprintf(page+len, "SPC-3 Reservation: Relative Port" - " Identifer Tag: %hu %s Portal Group Tag: %hu" + " Identifier Tag: %hu %s Portal Group Tag: %hu" " %s Logical Unit: %u\n", lun->lun_sep->sep_rtpi, tfo->get_fabric_name(), tfo->tpg_get_tag(se_tpg), tfo->get_fabric_name(), lun->unpacked_lun); @@ -3132,6 +3124,7 @@ static int __init target_core_init_configfs(void) GFP_KERNEL); if (!target_cg->default_groups) { pr_err("Unable to allocate target_cg->default_groups\n"); + ret = -ENOMEM; goto out_global; } @@ -3147,6 +3140,7 @@ static int __init target_core_init_configfs(void) GFP_KERNEL); if (!hba_cg->default_groups) { pr_err("Unable to allocate hba_cg->default_groups\n"); + ret = -ENOMEM; goto out_global; } config_group_init_type_name(&alua_group, @@ -3162,6 +3156,7 @@ static int __init target_core_init_configfs(void) GFP_KERNEL); if (!alua_cg->default_groups) { pr_err("Unable to allocate alua_cg->default_groups\n"); + ret = -ENOMEM; goto out_global; } @@ -3173,14 +3168,17 @@ static int __init target_core_init_configfs(void) * Add core/alua/lu_gps/default_lu_gp */ lu_gp = core_alua_allocate_lu_gp("default_lu_gp", 1); - if (IS_ERR(lu_gp)) + if (IS_ERR(lu_gp)) { + ret = -ENOMEM; goto out_global; + } lu_gp_cg = &alua_lu_gps_group; lu_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2, GFP_KERNEL); if (!lu_gp_cg->default_groups) { pr_err("Unable to allocate lu_gp_cg->default_groups\n"); + ret = -ENOMEM; goto out_global; } diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 9fc9a60..8d774da 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -531,7 +531,7 @@ static struct se_port *core_alloc_port(struct se_device *dev) } again: /* - * Allocate the next RELATIVE TARGET PORT IDENTIFER for this struct se_device + * Allocate the next RELATIVE TARGET PORT IDENTIFIER for this struct se_device * Here is the table from spc4r17 section 7.7.3.8. * * Table 473 -- RELATIVE TARGET PORT IDENTIFIER field @@ -548,7 +548,7 @@ again: list_for_each_entry(port_tmp, &dev->dev_sep_list, sep_list) { /* - * Make sure RELATIVE TARGET PORT IDENTIFER is unique + * Make sure RELATIVE TARGET PORT IDENTIFIER is unique * for 16-bit wrap.. */ if (port->sep_rtpi == port_tmp->sep_rtpi) @@ -595,7 +595,7 @@ static void core_export_port( } dev->dev_port_count++; - port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFER */ + port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFIER */ } /* @@ -988,8 +988,9 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) return -EINVAL; } - if (flag && dev->transport->fua_write_emulated == 0) { - pr_err("fua_write_emulated not supported\n"); + if (flag && + dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { + pr_err("emulate_fua_write not supported for pSCSI\n"); return -EINVAL; } dev->se_sub_dev->se_dev_attrib.emulate_fua_write = flag; @@ -1019,8 +1020,9 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) pr_err("Illegal value %d\n", flag); return -EINVAL; } - if (flag && dev->transport->write_cache_emulated == 0) { - pr_err("write_cache_emulated not supported\n"); + if (flag && + dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { + pr_err("emulate_write_cache not supported for pSCSI\n"); return -EINVAL; } dev->se_sub_dev->se_dev_attrib.emulate_write_cache = flag; diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index ea479e5..bca737b 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -22,7 +22,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> -#include <generated/utsrelease.h> #include <linux/utsname.h> #include <linux/init.h> #include <linux/fs.h> diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c index 283a36e..e460d62 100644 --- a/drivers/target/target_core_fabric_lib.c +++ b/drivers/target/target_core_fabric_lib.c @@ -338,7 +338,7 @@ u32 iscsi_get_pr_transport_id_len( * 00b: iSCSI Initiator device TransportID format */ if (pr_reg->isid_present_at_reg) { - len += 5; /* For ",i,0x" ASCII seperator */ + len += 5; /* For ",i,0x" ASCII separator */ len += 7; /* For iSCSI Initiator Session ID + Null terminator */ *format_code = 1; } else @@ -415,20 +415,20 @@ char *iscsi_parse_pr_out_transport_id( *out_tid_len = (add_len + 4); } /* - * Check for ',i,0x' seperator between iSCSI Name and iSCSI Initiator + * Check for ',i,0x' separator between iSCSI Name and iSCSI Initiator * Session ID as defined in Table 390 - iSCSI initiator port TransportID * format. */ if (format_code == 0x40) { p = strstr(&buf[4], ",i,0x"); if (!p) { - pr_err("Unable to locate \",i,0x\" seperator" + pr_err("Unable to locate \",i,0x\" separator" " for Initiator port identifier: %s\n", &buf[4]); return NULL; } *p = '\0'; /* Terminate iSCSI Name */ - p += 5; /* Skip over ",i,0x" seperator */ + p += 5; /* Skip over ",i,0x" separator */ *port_nexus_ptr = p; /* diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index cbb5aaf..0360383 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -125,6 +125,19 @@ static struct se_device *fd_create_virtdevice( * of pure timestamp updates. */ flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC; + /* + * Optionally allow fd_buffered_io=1 to be enabled for people + * who want use the fs buffer cache as an WriteCache mechanism. + * + * This means that in event of a hard failure, there is a risk + * of silent data-loss if the SCSI client has *not* performed a + * forced unit access (FUA) write, or issued SYNCHRONIZE_CACHE + * to write-out the entire device cache. + */ + if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { + pr_debug("FILEIO: Disabling O_DSYNC, using buffered FILEIO\n"); + flags &= ~O_DSYNC; + } file = filp_open(fd_dev->fd_dev_name, flags, 0600); if (IS_ERR(file)) { @@ -188,6 +201,12 @@ static struct se_device *fd_create_virtdevice( if (!dev) goto fail; + if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { + pr_debug("FILEIO: Forcing setting of emulate_write_cache=1" + " with FDBD_HAS_BUFFERED_IO_WCE\n"); + dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1; + } + fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++; fd_dev->fd_queue_depth = dev->queue_depth; @@ -407,6 +426,7 @@ enum { static match_table_t tokens = { {Opt_fd_dev_name, "fd_dev_name=%s"}, {Opt_fd_dev_size, "fd_dev_size=%s"}, + {Opt_fd_buffered_io, "fd_buffered_io=%d"}, {Opt_err, NULL} }; @@ -418,7 +438,7 @@ static ssize_t fd_set_configfs_dev_params( struct fd_dev *fd_dev = se_dev->se_dev_su_ptr; char *orig, *ptr, *arg_p, *opts; substring_t args[MAX_OPT_ARGS]; - int ret = 0, token; + int ret = 0, arg, token; opts = kstrdup(page, GFP_KERNEL); if (!opts) @@ -459,6 +479,19 @@ static ssize_t fd_set_configfs_dev_params( " bytes\n", fd_dev->fd_dev_size); fd_dev->fbd_flags |= FBDF_HAS_SIZE; break; + case Opt_fd_buffered_io: + match_int(args, &arg); + if (arg != 1) { + pr_err("bogus fd_buffered_io=%d value\n", arg); + ret = -EINVAL; + goto out; + } + + pr_debug("FILEIO: Using buffered I/O" + " operations for struct fd_dev\n"); + + fd_dev->fbd_flags |= FDBD_HAS_BUFFERED_IO_WCE; + break; default: break; } @@ -490,8 +523,10 @@ static ssize_t fd_show_configfs_dev_params( ssize_t bl = 0; bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id); - bl += sprintf(b + bl, " File: %s Size: %llu Mode: O_DSYNC\n", - fd_dev->fd_dev_name, fd_dev->fd_dev_size); + bl += sprintf(b + bl, " File: %s Size: %llu Mode: %s\n", + fd_dev->fd_dev_name, fd_dev->fd_dev_size, + (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) ? + "Buffered-WCE" : "O_DSYNC"); return bl; } @@ -546,8 +581,6 @@ static struct se_subsystem_api fileio_template = { .name = "fileio", .owner = THIS_MODULE, .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, - .write_cache_emulated = 1, - .fua_write_emulated = 1, .attach_hba = fd_attach_hba, .detach_hba = fd_detach_hba, .allocate_virtdevice = fd_allocate_virtdevice, diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h index 70ce7fd..876ae53 100644 --- a/drivers/target/target_core_file.h +++ b/drivers/target/target_core_file.h @@ -14,6 +14,7 @@ #define FBDF_HAS_PATH 0x01 #define FBDF_HAS_SIZE 0x02 +#define FDBD_HAS_BUFFERED_IO_WCE 0x04 struct fd_dev { u32 fbd_flags; diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 9ba4954..29408d4 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -454,14 +454,11 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba, ret = -EEXIST; goto out; } - arg_p = match_strdup(&args[0]); - if (!arg_p) { - ret = -ENOMEM; + if (match_strlcpy(ib_dev->ibd_udev_path, &args[0], + SE_UDEV_PATH_LEN) == 0) { + ret = -EINVAL; break; } - snprintf(ib_dev->ibd_udev_path, SE_UDEV_PATH_LEN, - "%s", arg_p); - kfree(arg_p); pr_debug("IBLOCK: Referencing UDEV path: %s\n", ib_dev->ibd_udev_path); ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH; @@ -657,6 +654,12 @@ static int iblock_execute_rw(struct se_cmd *cmd) goto fail; cmd->priv = ibr; + if (!sgl_nents) { + atomic_set(&ibr->pending, 1); + iblock_complete_cmd(cmd); + return 0; + } + bio = iblock_get_bio(cmd, block_lba, sgl_nents); if (!bio) goto fail_free_ibr; @@ -769,8 +772,6 @@ static struct se_subsystem_api iblock_template = { .name = "iblock", .owner = THIS_MODULE, .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, - .write_cache_emulated = 1, - .fua_write_emulated = 1, .attach_hba = iblock_attach_hba, .detach_hba = iblock_detach_hba, .allocate_virtdevice = iblock_allocate_virtdevice, diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 956c84c..8c323a9 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -197,10 +197,10 @@ int target_scsi2_reservation_release(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; struct se_session *sess = cmd->se_sess; - struct se_portal_group *tpg = sess->se_tpg; + struct se_portal_group *tpg; int ret = 0, rc; - if (!sess || !tpg) + if (!sess || !sess->se_tpg) goto out; rc = target_check_scsi2_reservation_conflict(cmd); if (rc == 1) @@ -228,6 +228,7 @@ int target_scsi2_reservation_release(struct se_cmd *cmd) dev->dev_res_bin_isid = 0; dev->dev_flags &= ~DF_SPC2_RESERVATIONS_WITH_ISID; } + tpg = sess->se_tpg; pr_debug("SCSI-2 Released reservation for %s LUN: %u ->" " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(), cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, @@ -245,7 +246,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; struct se_session *sess = cmd->se_sess; - struct se_portal_group *tpg = sess->se_tpg; + struct se_portal_group *tpg; int ret = 0, rc; if ((cmd->t_task_cdb[1] & 0x01) && @@ -260,7 +261,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd) * This is currently the case for target_core_mod passthrough struct se_cmd * ops */ - if (!sess || !tpg) + if (!sess || !sess->se_tpg) goto out; rc = target_check_scsi2_reservation_conflict(cmd); if (rc == 1) @@ -272,6 +273,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd) } ret = 0; + tpg = sess->se_tpg; spin_lock(&dev->dev_reservation_lock); if (dev->dev_reserved_node_acl && (dev->dev_reserved_node_acl != sess->se_node_acl)) { @@ -1620,7 +1622,7 @@ static int core_scsi3_decode_spec_i_port( goto out; } /* - * Locate the desination initiator ACL to be registered + * Locate the destination initiator ACL to be registered * from the decoded fabric module specific TransportID * at *i_str. */ @@ -4257,7 +4259,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) buf[off++] = ((port->sep_rtpi >> 8) & 0xff); buf[off++] = (port->sep_rtpi & 0xff); } else - off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFER */ + off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFIER */ /* * Now, have the $FABRIC_MOD fill in the protocol identifier diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 9d7ce3d..617c086 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -264,7 +264,7 @@ pscsi_get_inquiry_vpd_device_ident(struct scsi_device *sdev, " length zero!\n"); break; } - pr_debug("T10 VPD Identifer Length: %d\n", ident_len); + pr_debug("T10 VPD Identifier Length: %d\n", ident_len); vpd = kzalloc(sizeof(struct t10_vpd), GFP_KERNEL); if (!vpd) { diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index a9dd946..868f8aa 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -40,8 +40,9 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; - unsigned char *buf; unsigned long long blocks_long = dev->transport->get_blocks(dev); + unsigned char *rbuf; + unsigned char buf[8]; u32 blocks; if (blocks_long >= 0x00000000ffffffff) @@ -49,8 +50,6 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) else blocks = (u32)blocks_long; - buf = transport_kmap_data_sg(cmd); - buf[0] = (blocks >> 24) & 0xff; buf[1] = (blocks >> 16) & 0xff; buf[2] = (blocks >> 8) & 0xff; @@ -60,7 +59,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; - transport_kunmap_data_sg(cmd); + rbuf = transport_kmap_data_sg(cmd); + if (rbuf) { + memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); + transport_kunmap_data_sg(cmd); + } target_complete_cmd(cmd, GOOD); return 0; @@ -69,11 +72,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; - unsigned char *buf; + unsigned char *rbuf; + unsigned char buf[32]; unsigned long long blocks = dev->transport->get_blocks(dev); - buf = transport_kmap_data_sg(cmd); - + memset(buf, 0, sizeof(buf)); buf[0] = (blocks >> 56) & 0xff; buf[1] = (blocks >> 48) & 0xff; buf[2] = (blocks >> 40) & 0xff; @@ -93,7 +96,11 @@ static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) buf[14] = 0x80; - transport_kunmap_data_sg(cmd); + rbuf = transport_kmap_data_sg(cmd); + if (rbuf) { + memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); + transport_kunmap_data_sg(cmd); + } target_complete_cmd(cmd, GOOD); return 0; diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 388a922..9229bd9 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -600,30 +600,11 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg; - unsigned char *buf, *map_buf; + unsigned char *rbuf; unsigned char *cdb = cmd->t_task_cdb; + unsigned char buf[SE_INQUIRY_BUF]; int p, ret; - map_buf = transport_kmap_data_sg(cmd); - /* - * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we - * know we actually allocated a full page. Otherwise, if the - * data buffer is too small, allocate a temporary buffer so we - * don't have to worry about overruns in all our INQUIRY - * emulation handling. - */ - if (cmd->data_length < SE_INQUIRY_BUF && - (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) { - buf = kzalloc(SE_INQUIRY_BUF, GFP_KERNEL); - if (!buf) { - transport_kunmap_data_sg(cmd); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -ENOMEM; - } - } else { - buf = map_buf; - } - if (dev == tpg->tpg_virt_lun0.lun_se_dev) buf[0] = 0x3f; /* Not connected */ else @@ -655,11 +636,11 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) ret = -EINVAL; out: - if (buf != map_buf) { - memcpy(map_buf, buf, cmd->data_length); - kfree(buf); + rbuf = transport_kmap_data_sg(cmd); + if (rbuf) { + memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); + transport_kunmap_data_sg(cmd); } - transport_kunmap_data_sg(cmd); if (!ret) target_complete_cmd(cmd, GOOD); @@ -803,7 +784,7 @@ static int spc_emulate_modesense(struct se_cmd *cmd) unsigned char *rbuf; int type = dev->transport->get_device_type(dev); int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10); - int offset = ten ? 8 : 4; + u32 offset = ten ? 8 : 4; int length = 0; unsigned char buf[SE_MODE_PAGE_BUF]; @@ -836,6 +817,7 @@ static int spc_emulate_modesense(struct se_cmd *cmd) offset -= 2; buf[0] = (offset >> 8) & 0xff; buf[1] = offset & 0xff; + offset += 2; if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || (cmd->se_deve && @@ -845,13 +827,10 @@ static int spc_emulate_modesense(struct se_cmd *cmd) if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) && (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0)) spc_modesense_dpofua(&buf[3], type); - - if ((offset + 2) > cmd->data_length) - offset = cmd->data_length; - } else { offset -= 1; buf[0] = offset & 0xff; + offset += 1; if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || (cmd->se_deve && @@ -861,14 +840,13 @@ static int spc_emulate_modesense(struct se_cmd *cmd) if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) && (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0)) spc_modesense_dpofua(&buf[2], type); - - if ((offset + 1) > cmd->data_length) - offset = cmd->data_length; } rbuf = transport_kmap_data_sg(cmd); - memcpy(rbuf, buf, offset); - transport_kunmap_data_sg(cmd); + if (rbuf) { + memcpy(rbuf, buf, min(offset, cmd->data_length)); + transport_kunmap_data_sg(cmd); + } target_complete_cmd(cmd, GOOD); return 0; diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c index 3d44beb..cb6b003 100644 --- a/drivers/target/target_core_stat.c +++ b/drivers/target/target_core_stat.c @@ -32,7 +32,6 @@ #include <linux/delay.h> #include <linux/timer.h> #include <linux/string.h> -#include <generated/utsrelease.h> #include <linux/utsname.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index b8628a5..a531fe2 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -303,7 +303,7 @@ struct se_node_acl *core_tpg_check_initiator_node_acl( } /* * Here we only create demo-mode MappedLUNs from the active - * TPG LUNs if the fabric is not explictly asking for + * TPG LUNs if the fabric is not explicitly asking for * tpg_check_demo_mode_login_only() == 1. */ if ((tpg->se_tpg_tfo->tpg_check_demo_mode_login_only == NULL) || diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 269f544..c33baff 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -55,8 +55,6 @@ #include "target_core_pr.h" #include "target_core_ua.h" -static int sub_api_initialized; - static struct workqueue_struct *target_completion_wq; static struct kmem_cache *se_sess_cache; struct kmem_cache *se_ua_cache; @@ -195,6 +193,7 @@ u32 scsi_get_new_index(scsi_index_t type) void transport_subsystem_check_init(void) { int ret; + static int sub_api_initialized; if (sub_api_initialized) return; @@ -211,12 +210,7 @@ void transport_subsystem_check_init(void) if (ret != 0) pr_err("Unable to load target_core_pscsi\n"); - ret = request_module("target_core_stgt"); - if (ret != 0) - pr_err("Unable to load target_core_stgt\n"); - sub_api_initialized = 1; - return; } struct se_session *transport_init_session(void) @@ -573,9 +567,7 @@ static void target_complete_failure_work(struct work_struct *work) */ static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd) { - unsigned char *buffer = cmd->sense_buffer; struct se_device *dev = cmd->se_dev; - u32 offset = 0; WARN_ON(!cmd->se_lun); @@ -585,14 +577,11 @@ static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd) if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) return NULL; - offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); - - /* Automatically padded */ - cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; + cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n", dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); - return &buffer[offset]; + return cmd->sense_buffer; } void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) @@ -969,7 +958,7 @@ int transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83) { static const char hex_str[] = "0123456789abcdef"; - int j = 0, i = 4; /* offset to start of the identifer */ + int j = 0, i = 4; /* offset to start of the identifier */ /* * The VPD Code Set (encoding) @@ -1466,8 +1455,9 @@ int transport_handle_cdb_direct( } EXPORT_SYMBOL(transport_handle_cdb_direct); -/** - * target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd +/* + * target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized + * se_cmd + use pre-allocated SGL memory. * * @se_cmd: command descriptor to submit * @se_sess: associated se_sess for endpoint @@ -1478,6 +1468,10 @@ EXPORT_SYMBOL(transport_handle_cdb_direct); * @task_addr: SAM task attribute * @data_dir: DMA data direction * @flags: flags for command submission from target_sc_flags_tables + * @sgl: struct scatterlist memory for unidirectional mapping + * @sgl_count: scatterlist count for unidirectional mapping + * @sgl_bidi: struct scatterlist memory for bidirectional READ mapping + * @sgl_bidi_count: scatterlist count for bidirectional READ mapping * * Returns non zero to signal active I/O shutdown failure. All other * setup exceptions will be returned as a SCSI CHECK_CONDITION response, @@ -1485,10 +1479,12 @@ EXPORT_SYMBOL(transport_handle_cdb_direct); * * This may only be called from process context, and also currently * assumes internal allocation of fabric payload buffer by target-core. - **/ -int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, + */ +int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *cdb, unsigned char *sense, u32 unpacked_lun, - u32 data_length, int task_attr, int data_dir, int flags) + u32 data_length, int task_attr, int data_dir, int flags, + struct scatterlist *sgl, u32 sgl_count, + struct scatterlist *sgl_bidi, u32 sgl_bidi_count) { struct se_portal_group *se_tpg; int rc; @@ -1535,7 +1531,42 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, transport_generic_request_failure(se_cmd); return 0; } + /* + * When a non zero sgl_count has been passed perform SGL passthrough + * mapping for pre-allocated fabric memory instead of having target + * core perform an internal SGL allocation.. + */ + if (sgl_count != 0) { + BUG_ON(!sgl); + + /* + * A work-around for tcm_loop as some userspace code via + * scsi-generic do not memset their associated read buffers, + * so go ahead and do that here for type non-data CDBs. Also + * note that this is currently guaranteed to be a single SGL + * for this case by target core in target_setup_cmd_from_cdb() + * -> transport_generic_cmd_sequencer(). + */ + if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && + se_cmd->data_direction == DMA_FROM_DEVICE) { + unsigned char *buf = NULL; + + if (sgl) + buf = kmap(sg_page(sgl)) + sgl->offset; + + if (buf) { + memset(buf, 0, sgl->length); + kunmap(sg_page(sgl)); + } + } + rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count, + sgl_bidi, sgl_bidi_count); + if (rc != 0) { + transport_generic_request_failure(se_cmd); + return 0; + } + } /* * Check if we need to delay processing because of ALUA * Active/NonOptimized primary access state.. @@ -1545,6 +1576,38 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, transport_handle_cdb_direct(se_cmd); return 0; } +EXPORT_SYMBOL(target_submit_cmd_map_sgls); + +/* + * target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd + * + * @se_cmd: command descriptor to submit + * @se_sess: associated se_sess for endpoint + * @cdb: pointer to SCSI CDB + * @sense: pointer to SCSI sense buffer + * @unpacked_lun: unpacked LUN to reference for struct se_lun + * @data_length: fabric expected data transfer length + * @task_addr: SAM task attribute + * @data_dir: DMA data direction + * @flags: flags for command submission from target_sc_flags_tables + * + * Returns non zero to signal active I/O shutdown failure. All other + * setup exceptions will be returned as a SCSI CHECK_CONDITION response, + * but still return zero here. + * + * This may only be called from process context, and also currently + * assumes internal allocation of fabric payload buffer by target-core. + * + * It also assumes interal target core SGL memory allocation. + */ +int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, + unsigned char *cdb, unsigned char *sense, u32 unpacked_lun, + u32 data_length, int task_attr, int data_dir, int flags) +{ + return target_submit_cmd_map_sgls(se_cmd, se_sess, cdb, sense, + unpacked_lun, data_length, task_attr, data_dir, + flags, NULL, 0, NULL, 0); +} EXPORT_SYMBOL(target_submit_cmd); static void target_complete_tmr_failure(struct work_struct *work) @@ -2300,23 +2363,6 @@ int transport_generic_new_cmd(struct se_cmd *cmd) if (ret < 0) goto out_fail; } - /* - * If this command doesn't have any payload and we don't have to call - * into the fabric for data transfers, go ahead and complete it right - * away. - */ - if (!cmd->data_length && - cmd->t_task_cdb[0] != REQUEST_SENSE && - cmd->se_dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { - spin_lock_irq(&cmd->t_state_lock); - cmd->t_state = TRANSPORT_COMPLETE; - cmd->transport_state |= CMD_T_ACTIVE; - spin_unlock_irq(&cmd->t_state_lock); - - INIT_WORK(&cmd->work, target_complete_ok_work); - queue_work(target_completion_wq, &cmd->work); - return 0; - } atomic_inc(&cmd->t_fe_count); @@ -2771,7 +2817,7 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) spin_lock_irqsave(&cmd->t_state_lock, flags); cmd->transport_state &= ~(CMD_T_ACTIVE | CMD_T_STOP); - pr_debug("wait_for_tasks: Stopped wait_for_compltion(" + pr_debug("wait_for_tasks: Stopped wait_for_completion(" "&cmd->t_transport_stop_comp) for ITT: 0x%08x\n", cmd->se_tfo->get_task_tag(cmd)); @@ -2810,7 +2856,6 @@ int transport_send_check_condition_and_sense( { unsigned char *buffer = cmd->sense_buffer; unsigned long flags; - int offset; u8 asc = 0, ascq = 0; spin_lock_irqsave(&cmd->t_state_lock, flags); @@ -2826,14 +2871,7 @@ int transport_send_check_condition_and_sense( if (!from_transport) cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE; - /* - * Data Segment and SenseLength of the fabric response PDU. - * - * TRANSPORT_SENSE_BUFFER is now set to SCSI_SENSE_BUFFERSIZE - * from include/scsi/scsi_cmnd.h - */ - offset = cmd->se_tfo->set_fabric_sense_len(cmd, - TRANSPORT_SENSE_BUFFER); + /* * Actual SENSE DATA, see SPC-3 7.23.2 SPC_SENSE_KEY_OFFSET uses * SENSE KEY values from include/scsi/scsi.h @@ -2841,151 +2879,151 @@ int transport_send_check_condition_and_sense( switch (reason) { case TCM_NON_EXISTENT_LUN: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* LOGICAL UNIT NOT SUPPORTED */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x25; + buffer[SPC_ASC_KEY_OFFSET] = 0x25; break; case TCM_UNSUPPORTED_SCSI_OPCODE: case TCM_SECTOR_COUNT_TOO_MANY: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* INVALID COMMAND OPERATION CODE */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x20; + buffer[SPC_ASC_KEY_OFFSET] = 0x20; break; case TCM_UNKNOWN_MODE_PAGE: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* INVALID FIELD IN CDB */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24; + buffer[SPC_ASC_KEY_OFFSET] = 0x24; break; case TCM_CHECK_CONDITION_ABORT_CMD: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; + buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* BUS DEVICE RESET FUNCTION OCCURRED */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x29; - buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x03; + buffer[SPC_ASC_KEY_OFFSET] = 0x29; + buffer[SPC_ASCQ_KEY_OFFSET] = 0x03; break; case TCM_INCORRECT_AMOUNT_OF_DATA: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; + buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* WRITE ERROR */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x0c; + buffer[SPC_ASC_KEY_OFFSET] = 0x0c; /* NOT ENOUGH UNSOLICITED DATA */ - buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x0d; + buffer[SPC_ASCQ_KEY_OFFSET] = 0x0d; break; case TCM_INVALID_CDB_FIELD: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* INVALID FIELD IN CDB */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24; + buffer[SPC_ASC_KEY_OFFSET] = 0x24; break; case TCM_INVALID_PARAMETER_LIST: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* INVALID FIELD IN PARAMETER LIST */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x26; + buffer[SPC_ASC_KEY_OFFSET] = 0x26; break; case TCM_UNEXPECTED_UNSOLICITED_DATA: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; + buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* WRITE ERROR */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x0c; + buffer[SPC_ASC_KEY_OFFSET] = 0x0c; /* UNEXPECTED_UNSOLICITED_DATA */ - buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x0c; + buffer[SPC_ASCQ_KEY_OFFSET] = 0x0c; break; case TCM_SERVICE_CRC_ERROR: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; + buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* PROTOCOL SERVICE CRC ERROR */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x47; + buffer[SPC_ASC_KEY_OFFSET] = 0x47; /* N/A */ - buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x05; + buffer[SPC_ASCQ_KEY_OFFSET] = 0x05; break; case TCM_SNACK_REJECTED: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; + buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* READ ERROR */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x11; + buffer[SPC_ASC_KEY_OFFSET] = 0x11; /* FAILED RETRANSMISSION REQUEST */ - buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x13; + buffer[SPC_ASCQ_KEY_OFFSET] = 0x13; break; case TCM_WRITE_PROTECTED: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* DATA PROTECT */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = DATA_PROTECT; + buffer[SPC_SENSE_KEY_OFFSET] = DATA_PROTECT; /* WRITE PROTECTED */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x27; + buffer[SPC_ASC_KEY_OFFSET] = 0x27; break; case TCM_ADDRESS_OUT_OF_RANGE: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* LOGICAL BLOCK ADDRESS OUT OF RANGE */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x21; + buffer[SPC_ASC_KEY_OFFSET] = 0x21; break; case TCM_CHECK_CONDITION_UNIT_ATTENTION: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* UNIT ATTENTION */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; + buffer[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; core_scsi3_ua_for_check_condition(cmd, &asc, &ascq); - buffer[offset+SPC_ASC_KEY_OFFSET] = asc; - buffer[offset+SPC_ASCQ_KEY_OFFSET] = ascq; + buffer[SPC_ASC_KEY_OFFSET] = asc; + buffer[SPC_ASCQ_KEY_OFFSET] = ascq; break; case TCM_CHECK_CONDITION_NOT_READY: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* Not Ready */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = NOT_READY; + buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY; transport_get_sense_codes(cmd, &asc, &ascq); - buffer[offset+SPC_ASC_KEY_OFFSET] = asc; - buffer[offset+SPC_ASCQ_KEY_OFFSET] = ascq; + buffer[SPC_ASC_KEY_OFFSET] = asc; + buffer[SPC_ASCQ_KEY_OFFSET] = ascq; break; case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE: default: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* LOGICAL UNIT COMMUNICATION FAILURE */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x80; + buffer[SPC_ASC_KEY_OFFSET] = 0x80; break; } /* @@ -2996,7 +3034,7 @@ int transport_send_check_condition_and_sense( * Automatically padded, this value is encoded in the fabric's * data_length response PDU containing the SCSI defined sense data. */ - cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; + cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; after_reason: return cmd->se_tfo->queue_status(cmd); diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 823e692..b406f17 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -19,7 +19,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> -#include <generated/utsrelease.h> #include <linux/utsname.h> #include <linux/init.h> #include <linux/slab.h> diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index 9501844..b74feb0 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -495,16 +495,6 @@ static void ft_set_default_node_attr(struct se_node_acl *se_nacl) { } -static u16 ft_get_fabric_sense_len(void) -{ - return 0; -} - -static u16 ft_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_len) -{ - return 0; -} - static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg) { struct ft_tpg *tpg = se_tpg->se_tpg_fabric_ptr; @@ -542,8 +532,6 @@ static struct target_core_fabric_ops ft_fabric_ops = { .queue_data_in = ft_queue_data_in, .queue_status = ft_queue_status, .queue_tm_rsp = ft_queue_tm_resp, - .get_fabric_sense_len = ft_get_fabric_sense_len, - .set_fabric_sense_len = ft_set_fabric_sense_len, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c index ad36ede1..b6fd4cf 100644 --- a/drivers/target/tcm_fc/tfc_io.c +++ b/drivers/target/tcm_fc/tfc_io.c @@ -28,7 +28,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> -#include <generated/utsrelease.h> #include <linux/utsname.h> #include <linux/init.h> #include <linux/slab.h> @@ -328,11 +327,12 @@ drop: */ void ft_invl_hw_context(struct ft_cmd *cmd) { - struct fc_seq *seq = cmd->seq; + struct fc_seq *seq; struct fc_exch *ep = NULL; struct fc_lport *lport = NULL; BUG_ON(!cmd); + seq = cmd->seq; /* Cleanup the DDP context in HW if DDP was setup */ if (cmd->was_ddp_setup && seq) { diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index 3c9e5b5..9585010 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -19,7 +19,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> -#include <generated/utsrelease.h> #include <linux/utsname.h> #include <linux/init.h> #include <linux/slab.h> diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index eaa1005..97e68b3 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -1472,16 +1472,6 @@ static int usbg_queue_tm_rsp(struct se_cmd *se_cmd) return 0; } -static u16 usbg_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) -{ - return 0; -} - -static u16 usbg_get_fabric_sense_len(void) -{ - return 0; -} - static const char *usbg_check_wwn(const char *name) { const char *n; @@ -1822,7 +1812,7 @@ static ssize_t tcm_usbg_tpg_store_nexus( ret = tcm_usbg_drop_nexus(tpg); return (!ret) ? count : ret; } - if (strlen(page) > USBG_NAMELEN) { + if (strlen(page) >= USBG_NAMELEN) { pr_err("Emulated NAA Sas Address: %s, exceeds" " max: %d\n", page, USBG_NAMELEN); return -EINVAL; @@ -1907,8 +1897,6 @@ static struct target_core_fabric_ops usbg_ops = { .queue_data_in = usbg_send_read_response, .queue_status = usbg_send_status_response, .queue_tm_rsp = usbg_queue_tm_rsp, - .get_fabric_sense_len = usbg_get_fabric_sense_len, - .set_fabric_sense_len = usbg_set_fabric_sense_len, .check_stop_free = usbg_check_stop_free, .fabric_make_wwn = usbg_make_tport, @@ -1968,7 +1956,6 @@ static void usbg_deregister_configfs(void) static struct usb_interface_descriptor bot_intf_desc = { .bLength = sizeof(bot_intf_desc), .bDescriptorType = USB_DT_INTERFACE, - .bAlternateSetting = 0, .bNumEndpoints = 2, .bAlternateSetting = USB_G_ALT_INT_BBB, .bInterfaceClass = USB_CLASS_MASS_STORAGE, diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index ed8e2e6..aa31692 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c @@ -330,17 +330,6 @@ static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd) return 0; } -static u16 tcm_vhost_set_fabric_sense_len(struct se_cmd *se_cmd, - u32 sense_length) -{ - return 0; -} - -static u16 tcm_vhost_get_fabric_sense_len(void) -{ - return 0; -} - static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd) { struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; @@ -426,10 +415,7 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( { struct tcm_vhost_cmd *tv_cmd; struct tcm_vhost_nexus *tv_nexus; - struct se_portal_group *se_tpg = &tv_tpg->se_tpg; struct se_session *se_sess; - struct se_cmd *se_cmd; - int sam_task_attr; tv_nexus = tv_tpg->tpg_nexus; if (!tv_nexus) { @@ -445,23 +431,11 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( } INIT_LIST_HEAD(&tv_cmd->tvc_completion_list); tv_cmd->tvc_tag = v_req->tag; + tv_cmd->tvc_task_attr = v_req->task_attr; + tv_cmd->tvc_exp_data_len = exp_data_len; + tv_cmd->tvc_data_direction = data_direction; + tv_cmd->tvc_nexus = tv_nexus; - se_cmd = &tv_cmd->tvc_se_cmd; - /* - * Locate the SAM Task Attr from virtio_scsi_cmd_req - */ - sam_task_attr = v_req->task_attr; - /* - * Initialize struct se_cmd descriptor from TCM infrastructure - */ - transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, exp_data_len, - data_direction, sam_task_attr, - &tv_cmd->tvc_sense_buf[0]); - -#if 0 /* FIXME: vhost_scsi_allocate_cmd() BIDI operation */ - if (bidi) - se_cmd->se_cmd_flags |= SCF_BIDI; -#endif return tv_cmd; } @@ -560,37 +534,10 @@ static void tcm_vhost_submission_work(struct work_struct *work) { struct tcm_vhost_cmd *tv_cmd = container_of(work, struct tcm_vhost_cmd, work); + struct tcm_vhost_nexus *tv_nexus; struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL; int rc, sg_no_bidi = 0; - /* - * Locate the struct se_lun pointer based on v_req->lun, and - * attach it to struct se_cmd - */ - rc = transport_lookup_cmd_lun(&tv_cmd->tvc_se_cmd, tv_cmd->tvc_lun); - if (rc < 0) { - pr_err("Failed to look up lun: %d\n", tv_cmd->tvc_lun); - transport_send_check_condition_and_sense(&tv_cmd->tvc_se_cmd, - tv_cmd->tvc_se_cmd.scsi_sense_reason, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } - - rc = target_setup_cmd_from_cdb(se_cmd, tv_cmd->tvc_cdb); - if (rc == -ENOMEM) { - transport_send_check_condition_and_sense(se_cmd, - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } else if (rc < 0) { - if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) - tcm_vhost_queue_status(se_cmd); - else - transport_send_check_condition_and_sense(se_cmd, - se_cmd->scsi_sense_reason, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } if (tv_cmd->tvc_sgl_count) { sg_ptr = tv_cmd->tvc_sgl; @@ -608,17 +555,19 @@ static void tcm_vhost_submission_work(struct work_struct *work) } else { sg_ptr = NULL; } - - rc = transport_generic_map_mem_to_cmd(se_cmd, sg_ptr, - tv_cmd->tvc_sgl_count, sg_bidi_ptr, - sg_no_bidi); + tv_nexus = tv_cmd->tvc_nexus; + + rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess, + tv_cmd->tvc_cdb, &tv_cmd->tvc_sense_buf[0], + tv_cmd->tvc_lun, tv_cmd->tvc_exp_data_len, + tv_cmd->tvc_task_attr, tv_cmd->tvc_data_direction, + 0, sg_ptr, tv_cmd->tvc_sgl_count, + sg_bidi_ptr, sg_no_bidi); if (rc < 0) { transport_send_check_condition_and_sense(se_cmd, - se_cmd->scsi_sense_reason, 0); + TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); transport_generic_free_cmd(se_cmd, 0); - return; } - transport_handle_cdb_direct(se_cmd); } static void vhost_scsi_handle_vq(struct vhost_scsi *vs) @@ -1531,8 +1480,6 @@ static struct target_core_fabric_ops tcm_vhost_ops = { .queue_data_in = tcm_vhost_queue_data_in, .queue_status = tcm_vhost_queue_status, .queue_tm_rsp = tcm_vhost_queue_tm_rsp, - .get_fabric_sense_len = tcm_vhost_get_fabric_sense_len, - .set_fabric_sense_len = tcm_vhost_set_fabric_sense_len, /* * Setup callers for generic logic in target_core_fabric_configfs.c */ diff --git a/drivers/vhost/tcm_vhost.h b/drivers/vhost/tcm_vhost.h index d9e9355..7e87c63 100644 --- a/drivers/vhost/tcm_vhost.h +++ b/drivers/vhost/tcm_vhost.h @@ -5,6 +5,12 @@ struct tcm_vhost_cmd { /* Descriptor from vhost_get_vq_desc() for virt_queue segment */ int tvc_vq_desc; + /* virtio-scsi initiator task attribute */ + int tvc_task_attr; + /* virtio-scsi initiator data direction */ + enum dma_data_direction tvc_data_direction; + /* Expected data transfer length from virtio-scsi header */ + u32 tvc_exp_data_len; /* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */ u64 tvc_tag; /* The number of scatterlists associated with this cmd */ @@ -17,6 +23,8 @@ struct tcm_vhost_cmd { struct virtio_scsi_cmd_resp __user *tvc_resp; /* Pointer to vhost_scsi for our device */ struct vhost_scsi *tvc_vhost; + /* Pointer to vhost nexus memory */ + struct tcm_vhost_nexus *tvc_nexus; /* The TCM I/O descriptor that is accessed via container_of() */ struct se_cmd tvc_se_cmd; /* work item used for cmwq dispatch to tcm_vhost_submission_work() */ |