diff options
Diffstat (limited to 'drivers/target/iscsi/iscsi_target.c')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 83 |
1 files changed, 50 insertions, 33 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index ac44af165b2..8b1d5e62ed4 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -23,6 +23,7 @@ #include <linux/crypto.h> #include <linux/completion.h> #include <linux/module.h> +#include <linux/idr.h> #include <asm/unaligned.h> #include <scsi/scsi_device.h> #include <scsi/iscsi_proto.h> @@ -780,7 +781,7 @@ static int iscsit_alloc_buffs(struct iscsi_cmd *cmd) struct scatterlist *sgl; u32 length = cmd->se_cmd.data_length; int nents = DIV_ROUND_UP(length, PAGE_SIZE); - int i = 0, ret; + int i = 0, j = 0, ret; /* * If no SCSI payload is present, allocate the default iovecs used for * iSCSI PDU Header @@ -821,17 +822,15 @@ static int iscsit_alloc_buffs(struct iscsi_cmd *cmd) */ ret = iscsit_allocate_iovecs(cmd); if (ret < 0) - goto page_alloc_failed; + return -ENOMEM; return 0; page_alloc_failed: - while (i >= 0) { - __free_page(sg_page(&sgl[i])); - i--; - } - kfree(cmd->t_mem_sg); - cmd->t_mem_sg = NULL; + while (j < i) + __free_page(sg_page(&sgl[j++])); + + kfree(sgl); return -ENOMEM; } @@ -1006,8 +1005,8 @@ done: /* * The CDB is going to an se_device_t. */ - ret = iscsit_get_lun_for_cmd(cmd, hdr->cdb, - get_unaligned_le64(&hdr->lun)); + ret = transport_lookup_cmd_lun(&cmd->se_cmd, + scsilun_to_int(&hdr->lun)); if (ret < 0) { if (cmd->se_cmd.scsi_sense_reason == TCM_NON_EXISTENT_LUN) { pr_debug("Responding to non-acl'ed," @@ -1028,7 +1027,7 @@ done: return iscsit_add_reject_from_cmd( ISCSI_REASON_BOOKMARK_NO_RESOURCES, 1, 1, buf, cmd); - } else if (transport_ret == -EINVAL) { + } else if (transport_ret < 0) { /* * Unsupported SAM Opcode. CHECK_CONDITION will be sent * in iscsit_execute_cmd() during the CmdSN OOO Execution @@ -1061,7 +1060,7 @@ attach_cmd: if (ret < 0) return iscsit_add_reject_from_cmd( ISCSI_REASON_BOOKMARK_NO_RESOURCES, - 1, 1, buf, cmd); + 1, 0, buf, cmd); /* * Check the CmdSN against ExpCmdSN/MaxCmdSN here if * the Immediate Bit is not set, and no Immediate @@ -1363,7 +1362,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) * outstanding_r2ts reaches zero, go ahead and send the delayed * TASK_ABORTED status. */ - if (atomic_read(&se_cmd->t_transport_aborted) != 0) { + if (se_cmd->transport_state & CMD_T_ABORTED) { if (hdr->flags & ISCSI_FLAG_CMD_FINAL) if (--cmd->outstanding_r2ts < 1) { iscsit_stop_dataout_timer(cmd); @@ -1471,14 +1470,12 @@ static int iscsit_handle_nop_out( unsigned char *ping_data = NULL; int cmdsn_ret, niov = 0, ret = 0, rx_got, rx_size; u32 checksum, data_crc, padding = 0, payload_length; - u64 lun; struct iscsi_cmd *cmd = NULL; struct kvec *iov = NULL; struct iscsi_nopout *hdr; hdr = (struct iscsi_nopout *) buf; payload_length = ntoh24(hdr->dlength); - lun = get_unaligned_le64(&hdr->lun); hdr->itt = be32_to_cpu(hdr->itt); hdr->ttt = be32_to_cpu(hdr->ttt); hdr->cmdsn = be32_to_cpu(hdr->cmdsn); @@ -1688,13 +1685,11 @@ static int iscsit_handle_task_mgt_cmd( struct se_tmr_req *se_tmr; struct iscsi_tmr_req *tmr_req; struct iscsi_tm *hdr; - u32 payload_length; int out_of_order_cmdsn = 0; int ret; u8 function; hdr = (struct iscsi_tm *) buf; - payload_length = ntoh24(hdr->dlength); hdr->itt = be32_to_cpu(hdr->itt); hdr->rtt = be32_to_cpu(hdr->rtt); hdr->cmdsn = be32_to_cpu(hdr->cmdsn); @@ -1746,8 +1741,8 @@ static int iscsit_handle_task_mgt_cmd( * Locate the struct se_lun for all TMRs not related to ERL=2 TASK_REASSIGN */ if (function != ISCSI_TM_FUNC_TASK_REASSIGN) { - ret = iscsit_get_lun_for_tmr(cmd, - get_unaligned_le64(&hdr->lun)); + ret = transport_lookup_tmr_lun(&cmd->se_cmd, + scsilun_to_int(&hdr->lun)); if (ret < 0) { cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; se_tmr->response = ISCSI_TMF_RSP_NO_LUN; @@ -2206,14 +2201,10 @@ static int iscsit_handle_snack( struct iscsi_conn *conn, unsigned char *buf) { - u32 unpacked_lun; - u64 lun; struct iscsi_snack *hdr; hdr = (struct iscsi_snack *) buf; hdr->flags &= ~ISCSI_FLAG_CMD_FINAL; - lun = get_unaligned_le64(&hdr->lun); - unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); hdr->itt = be32_to_cpu(hdr->itt); hdr->ttt = be32_to_cpu(hdr->ttt); hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); @@ -3164,6 +3155,30 @@ static int iscsit_send_task_mgt_rsp( return 0; } +static bool iscsit_check_inaddr_any(struct iscsi_np *np) +{ + bool ret = false; + + if (np->np_sockaddr.ss_family == AF_INET6) { + const struct sockaddr_in6 sin6 = { + .sin6_addr = IN6ADDR_ANY_INIT }; + struct sockaddr_in6 *sock_in6 = + (struct sockaddr_in6 *)&np->np_sockaddr; + + if (!memcmp(sock_in6->sin6_addr.s6_addr, + sin6.sin6_addr.s6_addr, 16)) + ret = true; + } else { + struct sockaddr_in * sock_in = + (struct sockaddr_in *)&np->np_sockaddr; + + if (sock_in->sin_addr.s_addr == INADDR_ANY) + ret = true; + } + + return ret; +} + static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) { char *payload = NULL; @@ -3213,12 +3228,17 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) spin_lock(&tpg->tpg_np_lock); list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) { + struct iscsi_np *np = tpg_np->tpg_np; + bool inaddr_any = iscsit_check_inaddr_any(np); + len = sprintf(buf, "TargetAddress=" "%s%s%s:%hu,%hu", - (tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ? - "[" : "", tpg_np->tpg_np->np_ip, - (tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ? - "]" : "", tpg_np->tpg_np->np_port, + (np->np_sockaddr.ss_family == AF_INET6) ? + "[" : "", (inaddr_any == false) ? + np->np_ip : conn->local_ip, + (np->np_sockaddr.ss_family == AF_INET6) ? + "]" : "", (inaddr_any == false) ? + np->np_port : conn->local_port, tpg->tpgt); len += 1; @@ -3484,7 +3504,6 @@ int iscsi_target_tx_thread(void *arg) struct iscsi_cmd *cmd = NULL; struct iscsi_conn *conn; struct iscsi_queue_req *qr = NULL; - struct se_cmd *se_cmd; struct iscsi_thread_set *ts = arg; /* * Allow ourselves to be interrupted by SIGINT so that a @@ -3667,8 +3686,6 @@ check_rsp_state: goto transport_err; } - se_cmd = &cmd->se_cmd; - if (map_sg && !conn->conn_ops->IFMarker) { if (iscsit_fe_sendpage_sg(cmd, conn) < 0) { conn->tx_response_queue = 0; @@ -4141,7 +4158,7 @@ int iscsit_close_connection( if (!atomic_read(&sess->session_reinstatement) && atomic_read(&sess->session_fall_back_to_erl0)) { spin_unlock_bh(&sess->conn_lock); - iscsit_close_session(sess); + target_put_session(sess->se_sess); return 0; } else if (atomic_read(&sess->session_logout)) { @@ -4262,7 +4279,7 @@ static void iscsit_logout_post_handler_closesession( iscsit_dec_conn_usage_count(conn); iscsit_stop_session(sess, 1, 1); iscsit_dec_session_usage_count(sess); - iscsit_close_session(sess); + target_put_session(sess->se_sess); } static void iscsit_logout_post_handler_samecid( @@ -4428,7 +4445,7 @@ int iscsit_free_session(struct iscsi_session *sess) } else spin_unlock_bh(&sess->conn_lock); - iscsit_close_session(sess); + target_put_session(sess->se_sess); return 0; } |