diff options
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 39 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_configfs.c | 1 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_core.h | 6 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_erl1.c | 4 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_login.c | 39 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 11 | ||||
-rw-r--r-- | drivers/target/target_core_alua.c | 8 | ||||
-rw-r--r-- | drivers/target/target_core_cdb.c | 51 | ||||
-rw-r--r-- | drivers/target/target_core_configfs.c | 12 | ||||
-rw-r--r-- | drivers/target/target_core_device.c | 28 | ||||
-rw-r--r-- | drivers/target/target_core_fabric_configfs.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_iblock.c | 11 | ||||
-rw-r--r-- | drivers/target/target_core_internal.h | 2 | ||||
-rw-r--r-- | drivers/target/target_core_pr.c | 43 | ||||
-rw-r--r-- | drivers/target/target_core_pscsi.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_tpg.c | 3 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 124 | ||||
-rw-r--r-- | drivers/target/tcm_fc/tfc_cmd.c | 9 |
18 files changed, 262 insertions, 137 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index ac44af165b27..44262908def5 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -1061,7 +1061,7 @@ attach_cmd: | |||
1061 | if (ret < 0) | 1061 | if (ret < 0) |
1062 | return iscsit_add_reject_from_cmd( | 1062 | return iscsit_add_reject_from_cmd( |
1063 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1063 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
1064 | 1, 1, buf, cmd); | 1064 | 1, 0, buf, cmd); |
1065 | /* | 1065 | /* |
1066 | * Check the CmdSN against ExpCmdSN/MaxCmdSN here if | 1066 | * Check the CmdSN against ExpCmdSN/MaxCmdSN here if |
1067 | * the Immediate Bit is not set, and no Immediate | 1067 | * the Immediate Bit is not set, and no Immediate |
@@ -3164,6 +3164,30 @@ static int iscsit_send_task_mgt_rsp( | |||
3164 | return 0; | 3164 | return 0; |
3165 | } | 3165 | } |
3166 | 3166 | ||
3167 | static bool iscsit_check_inaddr_any(struct iscsi_np *np) | ||
3168 | { | ||
3169 | bool ret = false; | ||
3170 | |||
3171 | if (np->np_sockaddr.ss_family == AF_INET6) { | ||
3172 | const struct sockaddr_in6 sin6 = { | ||
3173 | .sin6_addr = IN6ADDR_ANY_INIT }; | ||
3174 | struct sockaddr_in6 *sock_in6 = | ||
3175 | (struct sockaddr_in6 *)&np->np_sockaddr; | ||
3176 | |||
3177 | if (!memcmp(sock_in6->sin6_addr.s6_addr, | ||
3178 | sin6.sin6_addr.s6_addr, 16)) | ||
3179 | ret = true; | ||
3180 | } else { | ||
3181 | struct sockaddr_in * sock_in = | ||
3182 | (struct sockaddr_in *)&np->np_sockaddr; | ||
3183 | |||
3184 | if (sock_in->sin_addr.s_addr == INADDR_ANY) | ||
3185 | ret = true; | ||
3186 | } | ||
3187 | |||
3188 | return ret; | ||
3189 | } | ||
3190 | |||
3167 | static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) | 3191 | static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) |
3168 | { | 3192 | { |
3169 | char *payload = NULL; | 3193 | char *payload = NULL; |
@@ -3213,12 +3237,17 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) | |||
3213 | spin_lock(&tpg->tpg_np_lock); | 3237 | spin_lock(&tpg->tpg_np_lock); |
3214 | list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, | 3238 | list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, |
3215 | tpg_np_list) { | 3239 | tpg_np_list) { |
3240 | struct iscsi_np *np = tpg_np->tpg_np; | ||
3241 | bool inaddr_any = iscsit_check_inaddr_any(np); | ||
3242 | |||
3216 | len = sprintf(buf, "TargetAddress=" | 3243 | len = sprintf(buf, "TargetAddress=" |
3217 | "%s%s%s:%hu,%hu", | 3244 | "%s%s%s:%hu,%hu", |
3218 | (tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ? | 3245 | (np->np_sockaddr.ss_family == AF_INET6) ? |
3219 | "[" : "", tpg_np->tpg_np->np_ip, | 3246 | "[" : "", (inaddr_any == false) ? |
3220 | (tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ? | 3247 | np->np_ip : conn->local_ip, |
3221 | "]" : "", tpg_np->tpg_np->np_port, | 3248 | (np->np_sockaddr.ss_family == AF_INET6) ? |
3249 | "]" : "", (inaddr_any == false) ? | ||
3250 | np->np_port : conn->local_port, | ||
3222 | tpg->tpgt); | 3251 | tpg->tpgt); |
3223 | len += 1; | 3252 | len += 1; |
3224 | 3253 | ||
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 3468caab47a2..6b35b37988ed 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <linux/configfs.h> | 22 | #include <linux/configfs.h> |
23 | #include <linux/export.h> | 23 | #include <linux/export.h> |
24 | #include <linux/inet.h> | ||
24 | #include <target/target_core_base.h> | 25 | #include <target/target_core_base.h> |
25 | #include <target/target_core_fabric.h> | 26 | #include <target/target_core_fabric.h> |
26 | #include <target/target_core_fabric_configfs.h> | 27 | #include <target/target_core_fabric_configfs.h> |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index f1a02dad05a0..0ec3b77a0c27 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -508,6 +508,7 @@ struct iscsi_conn { | |||
508 | u16 cid; | 508 | u16 cid; |
509 | /* Remote TCP Port */ | 509 | /* Remote TCP Port */ |
510 | u16 login_port; | 510 | u16 login_port; |
511 | u16 local_port; | ||
511 | int net_size; | 512 | int net_size; |
512 | u32 auth_id; | 513 | u32 auth_id; |
513 | #define CONNFLAG_SCTP_STRUCT_FILE 0x01 | 514 | #define CONNFLAG_SCTP_STRUCT_FILE 0x01 |
@@ -527,6 +528,7 @@ struct iscsi_conn { | |||
527 | unsigned char bad_hdr[ISCSI_HDR_LEN]; | 528 | unsigned char bad_hdr[ISCSI_HDR_LEN]; |
528 | #define IPV6_ADDRESS_SPACE 48 | 529 | #define IPV6_ADDRESS_SPACE 48 |
529 | unsigned char login_ip[IPV6_ADDRESS_SPACE]; | 530 | unsigned char login_ip[IPV6_ADDRESS_SPACE]; |
531 | unsigned char local_ip[IPV6_ADDRESS_SPACE]; | ||
530 | int conn_usage_count; | 532 | int conn_usage_count; |
531 | int conn_waiting_on_uc; | 533 | int conn_waiting_on_uc; |
532 | atomic_t check_immediate_queue; | 534 | atomic_t check_immediate_queue; |
@@ -561,8 +563,8 @@ struct iscsi_conn { | |||
561 | struct hash_desc conn_tx_hash; | 563 | struct hash_desc conn_tx_hash; |
562 | /* Used for scheduling TX and RX connection kthreads */ | 564 | /* Used for scheduling TX and RX connection kthreads */ |
563 | cpumask_var_t conn_cpumask; | 565 | cpumask_var_t conn_cpumask; |
564 | int conn_rx_reset_cpumask:1; | 566 | unsigned int conn_rx_reset_cpumask:1; |
565 | int conn_tx_reset_cpumask:1; | 567 | unsigned int conn_tx_reset_cpumask:1; |
566 | /* list_head of struct iscsi_cmd for this connection */ | 568 | /* list_head of struct iscsi_cmd for this connection */ |
567 | struct list_head conn_cmd_list; | 569 | struct list_head conn_cmd_list; |
568 | struct list_head immed_queue_list; | 570 | struct list_head immed_queue_list; |
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index 255c0d67e898..27901e37c125 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c | |||
@@ -1238,7 +1238,7 @@ void iscsit_mod_dataout_timer(struct iscsi_cmd *cmd) | |||
1238 | { | 1238 | { |
1239 | struct iscsi_conn *conn = cmd->conn; | 1239 | struct iscsi_conn *conn = cmd->conn; |
1240 | struct iscsi_session *sess = conn->sess; | 1240 | struct iscsi_session *sess = conn->sess; |
1241 | struct iscsi_node_attrib *na = na = iscsit_tpg_get_node_attrib(sess); | 1241 | struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess); |
1242 | 1242 | ||
1243 | spin_lock_bh(&cmd->dataout_timeout_lock); | 1243 | spin_lock_bh(&cmd->dataout_timeout_lock); |
1244 | if (!(cmd->dataout_timer_flags & ISCSI_TF_RUNNING)) { | 1244 | if (!(cmd->dataout_timer_flags & ISCSI_TF_RUNNING)) { |
@@ -1261,7 +1261,7 @@ void iscsit_start_dataout_timer( | |||
1261 | struct iscsi_conn *conn) | 1261 | struct iscsi_conn *conn) |
1262 | { | 1262 | { |
1263 | struct iscsi_session *sess = conn->sess; | 1263 | struct iscsi_session *sess = conn->sess; |
1264 | struct iscsi_node_attrib *na = na = iscsit_tpg_get_node_attrib(sess); | 1264 | struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess); |
1265 | 1265 | ||
1266 | if (cmd->dataout_timer_flags & ISCSI_TF_RUNNING) | 1266 | if (cmd->dataout_timer_flags & ISCSI_TF_RUNNING) |
1267 | return; | 1267 | return; |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 373b0cc6abd8..38cb7ce8469e 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -615,8 +615,8 @@ static int iscsi_post_login_handler( | |||
615 | } | 615 | } |
616 | 616 | ||
617 | pr_debug("iSCSI Login successful on CID: %hu from %s to" | 617 | pr_debug("iSCSI Login successful on CID: %hu from %s to" |
618 | " %s:%hu,%hu\n", conn->cid, conn->login_ip, np->np_ip, | 618 | " %s:%hu,%hu\n", conn->cid, conn->login_ip, |
619 | np->np_port, tpg->tpgt); | 619 | conn->local_ip, conn->local_port, tpg->tpgt); |
620 | 620 | ||
621 | list_add_tail(&conn->conn_list, &sess->sess_conn_list); | 621 | list_add_tail(&conn->conn_list, &sess->sess_conn_list); |
622 | atomic_inc(&sess->nconn); | 622 | atomic_inc(&sess->nconn); |
@@ -658,7 +658,8 @@ static int iscsi_post_login_handler( | |||
658 | sess->session_state = TARG_SESS_STATE_LOGGED_IN; | 658 | sess->session_state = TARG_SESS_STATE_LOGGED_IN; |
659 | 659 | ||
660 | pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n", | 660 | pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n", |
661 | conn->cid, conn->login_ip, np->np_ip, np->np_port, tpg->tpgt); | 661 | conn->cid, conn->login_ip, conn->local_ip, conn->local_port, |
662 | tpg->tpgt); | ||
662 | 663 | ||
663 | spin_lock_bh(&sess->conn_lock); | 664 | spin_lock_bh(&sess->conn_lock); |
664 | list_add_tail(&conn->conn_list, &sess->sess_conn_list); | 665 | list_add_tail(&conn->conn_list, &sess->sess_conn_list); |
@@ -841,6 +842,14 @@ int iscsi_target_setup_login_socket( | |||
841 | goto fail; | 842 | goto fail; |
842 | } | 843 | } |
843 | 844 | ||
845 | ret = kernel_setsockopt(sock, IPPROTO_IP, IP_FREEBIND, | ||
846 | (char *)&opt, sizeof(opt)); | ||
847 | if (ret < 0) { | ||
848 | pr_err("kernel_setsockopt() for IP_FREEBIND" | ||
849 | " failed\n"); | ||
850 | goto fail; | ||
851 | } | ||
852 | |||
844 | ret = kernel_bind(sock, (struct sockaddr *)&np->np_sockaddr, len); | 853 | ret = kernel_bind(sock, (struct sockaddr *)&np->np_sockaddr, len); |
845 | if (ret < 0) { | 854 | if (ret < 0) { |
846 | pr_err("kernel_bind() failed: %d\n", ret); | 855 | pr_err("kernel_bind() failed: %d\n", ret); |
@@ -1020,6 +1029,18 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) | |||
1020 | snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c", | 1029 | snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c", |
1021 | &sock_in6.sin6_addr.in6_u); | 1030 | &sock_in6.sin6_addr.in6_u); |
1022 | conn->login_port = ntohs(sock_in6.sin6_port); | 1031 | conn->login_port = ntohs(sock_in6.sin6_port); |
1032 | |||
1033 | if (conn->sock->ops->getname(conn->sock, | ||
1034 | (struct sockaddr *)&sock_in6, &err, 0) < 0) { | ||
1035 | pr_err("sock_ops->getname() failed.\n"); | ||
1036 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
1037 | ISCSI_LOGIN_STATUS_TARGET_ERROR); | ||
1038 | goto new_sess_out; | ||
1039 | } | ||
1040 | snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI6c", | ||
1041 | &sock_in6.sin6_addr.in6_u); | ||
1042 | conn->local_port = ntohs(sock_in6.sin6_port); | ||
1043 | |||
1023 | } else { | 1044 | } else { |
1024 | memset(&sock_in, 0, sizeof(struct sockaddr_in)); | 1045 | memset(&sock_in, 0, sizeof(struct sockaddr_in)); |
1025 | 1046 | ||
@@ -1032,6 +1053,16 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) | |||
1032 | } | 1053 | } |
1033 | sprintf(conn->login_ip, "%pI4", &sock_in.sin_addr.s_addr); | 1054 | sprintf(conn->login_ip, "%pI4", &sock_in.sin_addr.s_addr); |
1034 | conn->login_port = ntohs(sock_in.sin_port); | 1055 | conn->login_port = ntohs(sock_in.sin_port); |
1056 | |||
1057 | if (conn->sock->ops->getname(conn->sock, | ||
1058 | (struct sockaddr *)&sock_in, &err, 0) < 0) { | ||
1059 | pr_err("sock_ops->getname() failed.\n"); | ||
1060 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
1061 | ISCSI_LOGIN_STATUS_TARGET_ERROR); | ||
1062 | goto new_sess_out; | ||
1063 | } | ||
1064 | sprintf(conn->local_ip, "%pI4", &sock_in.sin_addr.s_addr); | ||
1065 | conn->local_port = ntohs(sock_in.sin_port); | ||
1035 | } | 1066 | } |
1036 | 1067 | ||
1037 | conn->network_transport = np->np_network_transport; | 1068 | conn->network_transport = np->np_network_transport; |
@@ -1039,7 +1070,7 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) | |||
1039 | pr_debug("Received iSCSI login request from %s on %s Network" | 1070 | pr_debug("Received iSCSI login request from %s on %s Network" |
1040 | " Portal %s:%hu\n", conn->login_ip, | 1071 | " Portal %s:%hu\n", conn->login_ip, |
1041 | (conn->network_transport == ISCSI_TCP) ? "TCP" : "SCTP", | 1072 | (conn->network_transport == ISCSI_TCP) ? "TCP" : "SCTP", |
1042 | np->np_ip, np->np_port); | 1073 | conn->local_ip, conn->local_port); |
1043 | 1074 | ||
1044 | pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n"); | 1075 | pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n"); |
1045 | conn->conn_state = TARG_CONN_STATE_IN_LOGIN; | 1076 | conn->conn_state = TARG_CONN_STATE_IN_LOGIN; |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index a05ca1c4f01c..11287e1ece13 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -849,6 +849,17 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd) | |||
849 | case ISCSI_OP_SCSI_TMFUNC: | 849 | case ISCSI_OP_SCSI_TMFUNC: |
850 | transport_generic_free_cmd(&cmd->se_cmd, 1); | 850 | transport_generic_free_cmd(&cmd->se_cmd, 1); |
851 | break; | 851 | break; |
852 | case ISCSI_OP_REJECT: | ||
853 | /* | ||
854 | * Handle special case for REJECT when iscsi_add_reject*() has | ||
855 | * overwritten the original iscsi_opcode assignment, and the | ||
856 | * associated cmd->se_cmd needs to be released. | ||
857 | */ | ||
858 | if (cmd->se_cmd.se_tfo != NULL) { | ||
859 | transport_generic_free_cmd(&cmd->se_cmd, 1); | ||
860 | break; | ||
861 | } | ||
862 | /* Fall-through */ | ||
852 | default: | 863 | default: |
853 | iscsit_release_cmd(cmd); | 864 | iscsit_release_cmd(cmd); |
854 | break; | 865 | break; |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 1b1edd14f4bf..01a2691dfb47 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -78,7 +78,7 @@ int target_emulate_report_target_port_groups(struct se_task *task) | |||
78 | return -EINVAL; | 78 | return -EINVAL; |
79 | } | 79 | } |
80 | 80 | ||
81 | buf = transport_kmap_first_data_page(cmd); | 81 | buf = transport_kmap_data_sg(cmd); |
82 | 82 | ||
83 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 83 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); |
84 | list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list, | 84 | list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list, |
@@ -163,7 +163,7 @@ int target_emulate_report_target_port_groups(struct se_task *task) | |||
163 | buf[2] = ((rd_len >> 8) & 0xff); | 163 | buf[2] = ((rd_len >> 8) & 0xff); |
164 | buf[3] = (rd_len & 0xff); | 164 | buf[3] = (rd_len & 0xff); |
165 | 165 | ||
166 | transport_kunmap_first_data_page(cmd); | 166 | transport_kunmap_data_sg(cmd); |
167 | 167 | ||
168 | task->task_scsi_status = GOOD; | 168 | task->task_scsi_status = GOOD; |
169 | transport_complete_task(task, 1); | 169 | transport_complete_task(task, 1); |
@@ -194,7 +194,7 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
194 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 194 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
195 | return -EINVAL; | 195 | return -EINVAL; |
196 | } | 196 | } |
197 | buf = transport_kmap_first_data_page(cmd); | 197 | buf = transport_kmap_data_sg(cmd); |
198 | 198 | ||
199 | /* | 199 | /* |
200 | * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed | 200 | * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed |
@@ -351,7 +351,7 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
351 | } | 351 | } |
352 | 352 | ||
353 | out: | 353 | out: |
354 | transport_kunmap_first_data_page(cmd); | 354 | transport_kunmap_data_sg(cmd); |
355 | task->task_scsi_status = GOOD; | 355 | task->task_scsi_status = GOOD; |
356 | transport_complete_task(task, 1); | 356 | transport_complete_task(task, 1); |
357 | return 0; | 357 | return 0; |
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 2f2235edefff..f3d71fa88a28 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c | |||
@@ -83,7 +83,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd) | |||
83 | return -EINVAL; | 83 | return -EINVAL; |
84 | } | 84 | } |
85 | 85 | ||
86 | buf = transport_kmap_first_data_page(cmd); | 86 | buf = transport_kmap_data_sg(cmd); |
87 | 87 | ||
88 | if (dev == tpg->tpg_virt_lun0.lun_se_dev) { | 88 | if (dev == tpg->tpg_virt_lun0.lun_se_dev) { |
89 | buf[0] = 0x3f; /* Not connected */ | 89 | buf[0] = 0x3f; /* Not connected */ |
@@ -134,7 +134,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd) | |||
134 | buf[4] = 31; /* Set additional length to 31 */ | 134 | buf[4] = 31; /* Set additional length to 31 */ |
135 | 135 | ||
136 | out: | 136 | out: |
137 | transport_kunmap_first_data_page(cmd); | 137 | transport_kunmap_data_sg(cmd); |
138 | return 0; | 138 | return 0; |
139 | } | 139 | } |
140 | 140 | ||
@@ -698,6 +698,13 @@ int target_emulate_inquiry(struct se_task *task) | |||
698 | int p, ret; | 698 | int p, ret; |
699 | 699 | ||
700 | if (!(cdb[1] & 0x1)) { | 700 | if (!(cdb[1] & 0x1)) { |
701 | if (cdb[2]) { | ||
702 | pr_err("INQUIRY with EVPD==0 but PAGE CODE=%02x\n", | ||
703 | cdb[2]); | ||
704 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
705 | return -EINVAL; | ||
706 | } | ||
707 | |||
701 | ret = target_emulate_inquiry_std(cmd); | 708 | ret = target_emulate_inquiry_std(cmd); |
702 | goto out; | 709 | goto out; |
703 | } | 710 | } |
@@ -716,7 +723,7 @@ int target_emulate_inquiry(struct se_task *task) | |||
716 | return -EINVAL; | 723 | return -EINVAL; |
717 | } | 724 | } |
718 | 725 | ||
719 | buf = transport_kmap_first_data_page(cmd); | 726 | buf = transport_kmap_data_sg(cmd); |
720 | 727 | ||
721 | buf[0] = dev->transport->get_device_type(dev); | 728 | buf[0] = dev->transport->get_device_type(dev); |
722 | 729 | ||
@@ -729,11 +736,11 @@ int target_emulate_inquiry(struct se_task *task) | |||
729 | } | 736 | } |
730 | 737 | ||
731 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); | 738 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); |
732 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 739 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
733 | ret = -EINVAL; | 740 | ret = -EINVAL; |
734 | 741 | ||
735 | out_unmap: | 742 | out_unmap: |
736 | transport_kunmap_first_data_page(cmd); | 743 | transport_kunmap_data_sg(cmd); |
737 | out: | 744 | out: |
738 | if (!ret) { | 745 | if (!ret) { |
739 | task->task_scsi_status = GOOD; | 746 | task->task_scsi_status = GOOD; |
@@ -755,7 +762,7 @@ int target_emulate_readcapacity(struct se_task *task) | |||
755 | else | 762 | else |
756 | blocks = (u32)blocks_long; | 763 | blocks = (u32)blocks_long; |
757 | 764 | ||
758 | buf = transport_kmap_first_data_page(cmd); | 765 | buf = transport_kmap_data_sg(cmd); |
759 | 766 | ||
760 | buf[0] = (blocks >> 24) & 0xff; | 767 | buf[0] = (blocks >> 24) & 0xff; |
761 | buf[1] = (blocks >> 16) & 0xff; | 768 | buf[1] = (blocks >> 16) & 0xff; |
@@ -771,7 +778,7 @@ int target_emulate_readcapacity(struct se_task *task) | |||
771 | if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) | 778 | if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) |
772 | put_unaligned_be32(0xFFFFFFFF, &buf[0]); | 779 | put_unaligned_be32(0xFFFFFFFF, &buf[0]); |
773 | 780 | ||
774 | transport_kunmap_first_data_page(cmd); | 781 | transport_kunmap_data_sg(cmd); |
775 | 782 | ||
776 | task->task_scsi_status = GOOD; | 783 | task->task_scsi_status = GOOD; |
777 | transport_complete_task(task, 1); | 784 | transport_complete_task(task, 1); |
@@ -785,7 +792,7 @@ int target_emulate_readcapacity_16(struct se_task *task) | |||
785 | unsigned char *buf; | 792 | unsigned char *buf; |
786 | unsigned long long blocks = dev->transport->get_blocks(dev); | 793 | unsigned long long blocks = dev->transport->get_blocks(dev); |
787 | 794 | ||
788 | buf = transport_kmap_first_data_page(cmd); | 795 | buf = transport_kmap_data_sg(cmd); |
789 | 796 | ||
790 | buf[0] = (blocks >> 56) & 0xff; | 797 | buf[0] = (blocks >> 56) & 0xff; |
791 | buf[1] = (blocks >> 48) & 0xff; | 798 | buf[1] = (blocks >> 48) & 0xff; |
@@ -806,7 +813,7 @@ int target_emulate_readcapacity_16(struct se_task *task) | |||
806 | if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) | 813 | if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) |
807 | buf[14] = 0x80; | 814 | buf[14] = 0x80; |
808 | 815 | ||
809 | transport_kunmap_first_data_page(cmd); | 816 | transport_kunmap_data_sg(cmd); |
810 | 817 | ||
811 | task->task_scsi_status = GOOD; | 818 | task->task_scsi_status = GOOD; |
812 | transport_complete_task(task, 1); | 819 | transport_complete_task(task, 1); |
@@ -1019,9 +1026,9 @@ int target_emulate_modesense(struct se_task *task) | |||
1019 | offset = cmd->data_length; | 1026 | offset = cmd->data_length; |
1020 | } | 1027 | } |
1021 | 1028 | ||
1022 | rbuf = transport_kmap_first_data_page(cmd); | 1029 | rbuf = transport_kmap_data_sg(cmd); |
1023 | memcpy(rbuf, buf, offset); | 1030 | memcpy(rbuf, buf, offset); |
1024 | transport_kunmap_first_data_page(cmd); | 1031 | transport_kunmap_data_sg(cmd); |
1025 | 1032 | ||
1026 | task->task_scsi_status = GOOD; | 1033 | task->task_scsi_status = GOOD; |
1027 | transport_complete_task(task, 1); | 1034 | transport_complete_task(task, 1); |
@@ -1043,7 +1050,7 @@ int target_emulate_request_sense(struct se_task *task) | |||
1043 | return -ENOSYS; | 1050 | return -ENOSYS; |
1044 | } | 1051 | } |
1045 | 1052 | ||
1046 | buf = transport_kmap_first_data_page(cmd); | 1053 | buf = transport_kmap_data_sg(cmd); |
1047 | 1054 | ||
1048 | if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { | 1055 | if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { |
1049 | /* | 1056 | /* |
@@ -1051,11 +1058,8 @@ int target_emulate_request_sense(struct se_task *task) | |||
1051 | */ | 1058 | */ |
1052 | buf[0] = 0x70; | 1059 | buf[0] = 0x70; |
1053 | buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; | 1060 | buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; |
1054 | /* | 1061 | |
1055 | * Make sure request data length is enough for additional | 1062 | if (cmd->data_length < 18) { |
1056 | * sense data. | ||
1057 | */ | ||
1058 | if (cmd->data_length <= 18) { | ||
1059 | buf[7] = 0x00; | 1063 | buf[7] = 0x00; |
1060 | err = -EINVAL; | 1064 | err = -EINVAL; |
1061 | goto end; | 1065 | goto end; |
@@ -1072,11 +1076,8 @@ int target_emulate_request_sense(struct se_task *task) | |||
1072 | */ | 1076 | */ |
1073 | buf[0] = 0x70; | 1077 | buf[0] = 0x70; |
1074 | buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; | 1078 | buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; |
1075 | /* | 1079 | |
1076 | * Make sure request data length is enough for additional | 1080 | if (cmd->data_length < 18) { |
1077 | * sense data. | ||
1078 | */ | ||
1079 | if (cmd->data_length <= 18) { | ||
1080 | buf[7] = 0x00; | 1081 | buf[7] = 0x00; |
1081 | err = -EINVAL; | 1082 | err = -EINVAL; |
1082 | goto end; | 1083 | goto end; |
@@ -1089,7 +1090,7 @@ int target_emulate_request_sense(struct se_task *task) | |||
1089 | } | 1090 | } |
1090 | 1091 | ||
1091 | end: | 1092 | end: |
1092 | transport_kunmap_first_data_page(cmd); | 1093 | transport_kunmap_data_sg(cmd); |
1093 | task->task_scsi_status = GOOD; | 1094 | task->task_scsi_status = GOOD; |
1094 | transport_complete_task(task, 1); | 1095 | transport_complete_task(task, 1); |
1095 | return 0; | 1096 | return 0; |
@@ -1123,7 +1124,7 @@ int target_emulate_unmap(struct se_task *task) | |||
1123 | dl = get_unaligned_be16(&cdb[0]); | 1124 | dl = get_unaligned_be16(&cdb[0]); |
1124 | bd_dl = get_unaligned_be16(&cdb[2]); | 1125 | bd_dl = get_unaligned_be16(&cdb[2]); |
1125 | 1126 | ||
1126 | buf = transport_kmap_first_data_page(cmd); | 1127 | buf = transport_kmap_data_sg(cmd); |
1127 | 1128 | ||
1128 | ptr = &buf[offset]; | 1129 | ptr = &buf[offset]; |
1129 | pr_debug("UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu" | 1130 | pr_debug("UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu" |
@@ -1147,7 +1148,7 @@ int target_emulate_unmap(struct se_task *task) | |||
1147 | } | 1148 | } |
1148 | 1149 | ||
1149 | err: | 1150 | err: |
1150 | transport_kunmap_first_data_page(cmd); | 1151 | transport_kunmap_data_sg(cmd); |
1151 | if (!ret) { | 1152 | if (!ret) { |
1152 | task->task_scsi_status = GOOD; | 1153 | task->task_scsi_status = GOOD; |
1153 | transport_complete_task(task, 1); | 1154 | transport_complete_task(task, 1); |
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 0955bb8979fb..6e043eeb1db9 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -1704,13 +1704,15 @@ static ssize_t target_core_store_dev_alias( | |||
1704 | return -EINVAL; | 1704 | return -EINVAL; |
1705 | } | 1705 | } |
1706 | 1706 | ||
1707 | se_dev->su_dev_flags |= SDF_USING_ALIAS; | ||
1708 | read_bytes = snprintf(&se_dev->se_dev_alias[0], SE_DEV_ALIAS_LEN, | 1707 | read_bytes = snprintf(&se_dev->se_dev_alias[0], SE_DEV_ALIAS_LEN, |
1709 | "%s", page); | 1708 | "%s", page); |
1710 | 1709 | if (!read_bytes) | |
1710 | return -EINVAL; | ||
1711 | if (se_dev->se_dev_alias[read_bytes - 1] == '\n') | 1711 | if (se_dev->se_dev_alias[read_bytes - 1] == '\n') |
1712 | se_dev->se_dev_alias[read_bytes - 1] = '\0'; | 1712 | se_dev->se_dev_alias[read_bytes - 1] = '\0'; |
1713 | 1713 | ||
1714 | se_dev->su_dev_flags |= SDF_USING_ALIAS; | ||
1715 | |||
1714 | pr_debug("Target_Core_ConfigFS: %s/%s set alias: %s\n", | 1716 | pr_debug("Target_Core_ConfigFS: %s/%s set alias: %s\n", |
1715 | config_item_name(&hba->hba_group.cg_item), | 1717 | config_item_name(&hba->hba_group.cg_item), |
1716 | config_item_name(&se_dev->se_dev_group.cg_item), | 1718 | config_item_name(&se_dev->se_dev_group.cg_item), |
@@ -1753,13 +1755,15 @@ static ssize_t target_core_store_dev_udev_path( | |||
1753 | return -EINVAL; | 1755 | return -EINVAL; |
1754 | } | 1756 | } |
1755 | 1757 | ||
1756 | se_dev->su_dev_flags |= SDF_USING_UDEV_PATH; | ||
1757 | read_bytes = snprintf(&se_dev->se_dev_udev_path[0], SE_UDEV_PATH_LEN, | 1758 | read_bytes = snprintf(&se_dev->se_dev_udev_path[0], SE_UDEV_PATH_LEN, |
1758 | "%s", page); | 1759 | "%s", page); |
1759 | 1760 | if (!read_bytes) | |
1761 | return -EINVAL; | ||
1760 | if (se_dev->se_dev_udev_path[read_bytes - 1] == '\n') | 1762 | if (se_dev->se_dev_udev_path[read_bytes - 1] == '\n') |
1761 | se_dev->se_dev_udev_path[read_bytes - 1] = '\0'; | 1763 | se_dev->se_dev_udev_path[read_bytes - 1] = '\0'; |
1762 | 1764 | ||
1765 | se_dev->su_dev_flags |= SDF_USING_UDEV_PATH; | ||
1766 | |||
1763 | pr_debug("Target_Core_ConfigFS: %s/%s set udev_path: %s\n", | 1767 | pr_debug("Target_Core_ConfigFS: %s/%s set udev_path: %s\n", |
1764 | config_item_name(&hba->hba_group.cg_item), | 1768 | config_item_name(&hba->hba_group.cg_item), |
1765 | config_item_name(&se_dev->se_dev_group.cg_item), | 1769 | config_item_name(&se_dev->se_dev_group.cg_item), |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 0c5992f0d946..edbcabbf85f7 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -320,11 +320,12 @@ int core_free_device_list_for_node( | |||
320 | void core_dec_lacl_count(struct se_node_acl *se_nacl, struct se_cmd *se_cmd) | 320 | void core_dec_lacl_count(struct se_node_acl *se_nacl, struct se_cmd *se_cmd) |
321 | { | 321 | { |
322 | struct se_dev_entry *deve; | 322 | struct se_dev_entry *deve; |
323 | unsigned long flags; | ||
323 | 324 | ||
324 | spin_lock_irq(&se_nacl->device_list_lock); | 325 | spin_lock_irqsave(&se_nacl->device_list_lock, flags); |
325 | deve = &se_nacl->device_list[se_cmd->orig_fe_lun]; | 326 | deve = &se_nacl->device_list[se_cmd->orig_fe_lun]; |
326 | deve->deve_cmds--; | 327 | deve->deve_cmds--; |
327 | spin_unlock_irq(&se_nacl->device_list_lock); | 328 | spin_unlock_irqrestore(&se_nacl->device_list_lock, flags); |
328 | } | 329 | } |
329 | 330 | ||
330 | void core_update_device_list_access( | 331 | void core_update_device_list_access( |
@@ -656,7 +657,7 @@ int target_report_luns(struct se_task *se_task) | |||
656 | unsigned char *buf; | 657 | unsigned char *buf; |
657 | u32 cdb_offset = 0, lun_count = 0, offset = 8, i; | 658 | u32 cdb_offset = 0, lun_count = 0, offset = 8, i; |
658 | 659 | ||
659 | buf = transport_kmap_first_data_page(se_cmd); | 660 | buf = (unsigned char *) transport_kmap_data_sg(se_cmd); |
660 | 661 | ||
661 | /* | 662 | /* |
662 | * If no struct se_session pointer is present, this struct se_cmd is | 663 | * If no struct se_session pointer is present, this struct se_cmd is |
@@ -694,7 +695,7 @@ int target_report_luns(struct se_task *se_task) | |||
694 | * See SPC3 r07, page 159. | 695 | * See SPC3 r07, page 159. |
695 | */ | 696 | */ |
696 | done: | 697 | done: |
697 | transport_kunmap_first_data_page(se_cmd); | 698 | transport_kunmap_data_sg(se_cmd); |
698 | lun_count *= 8; | 699 | lun_count *= 8; |
699 | buf[0] = ((lun_count >> 24) & 0xff); | 700 | buf[0] = ((lun_count >> 24) & 0xff); |
700 | buf[1] = ((lun_count >> 16) & 0xff); | 701 | buf[1] = ((lun_count >> 16) & 0xff); |
@@ -1294,24 +1295,26 @@ struct se_lun *core_dev_add_lun( | |||
1294 | { | 1295 | { |
1295 | struct se_lun *lun_p; | 1296 | struct se_lun *lun_p; |
1296 | u32 lun_access = 0; | 1297 | u32 lun_access = 0; |
1298 | int rc; | ||
1297 | 1299 | ||
1298 | if (atomic_read(&dev->dev_access_obj.obj_access_count) != 0) { | 1300 | if (atomic_read(&dev->dev_access_obj.obj_access_count) != 0) { |
1299 | pr_err("Unable to export struct se_device while dev_access_obj: %d\n", | 1301 | pr_err("Unable to export struct se_device while dev_access_obj: %d\n", |
1300 | atomic_read(&dev->dev_access_obj.obj_access_count)); | 1302 | atomic_read(&dev->dev_access_obj.obj_access_count)); |
1301 | return NULL; | 1303 | return ERR_PTR(-EACCES); |
1302 | } | 1304 | } |
1303 | 1305 | ||
1304 | lun_p = core_tpg_pre_addlun(tpg, lun); | 1306 | lun_p = core_tpg_pre_addlun(tpg, lun); |
1305 | if ((IS_ERR(lun_p)) || !lun_p) | 1307 | if (IS_ERR(lun_p)) |
1306 | return NULL; | 1308 | return lun_p; |
1307 | 1309 | ||
1308 | if (dev->dev_flags & DF_READ_ONLY) | 1310 | if (dev->dev_flags & DF_READ_ONLY) |
1309 | lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; | 1311 | lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; |
1310 | else | 1312 | else |
1311 | lun_access = TRANSPORT_LUNFLAGS_READ_WRITE; | 1313 | lun_access = TRANSPORT_LUNFLAGS_READ_WRITE; |
1312 | 1314 | ||
1313 | if (core_tpg_post_addlun(tpg, lun_p, lun_access, dev) < 0) | 1315 | rc = core_tpg_post_addlun(tpg, lun_p, lun_access, dev); |
1314 | return NULL; | 1316 | if (rc < 0) |
1317 | return ERR_PTR(rc); | ||
1315 | 1318 | ||
1316 | pr_debug("%s_TPG[%u]_LUN[%u] - Activated %s Logical Unit from" | 1319 | pr_debug("%s_TPG[%u]_LUN[%u] - Activated %s Logical Unit from" |
1317 | " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(), | 1320 | " CORE HBA: %u\n", tpg->se_tpg_tfo->get_fabric_name(), |
@@ -1348,11 +1351,10 @@ int core_dev_del_lun( | |||
1348 | u32 unpacked_lun) | 1351 | u32 unpacked_lun) |
1349 | { | 1352 | { |
1350 | struct se_lun *lun; | 1353 | struct se_lun *lun; |
1351 | int ret = 0; | ||
1352 | 1354 | ||
1353 | lun = core_tpg_pre_dellun(tpg, unpacked_lun, &ret); | 1355 | lun = core_tpg_pre_dellun(tpg, unpacked_lun); |
1354 | if (!lun) | 1356 | if (IS_ERR(lun)) |
1355 | return ret; | 1357 | return PTR_ERR(lun); |
1356 | 1358 | ||
1357 | core_tpg_post_dellun(tpg, lun); | 1359 | core_tpg_post_dellun(tpg, lun); |
1358 | 1360 | ||
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 4f77cce22646..9a2ce11e1a6e 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c | |||
@@ -766,9 +766,9 @@ static int target_fabric_port_link( | |||
766 | 766 | ||
767 | lun_p = core_dev_add_lun(se_tpg, dev->se_hba, dev, | 767 | lun_p = core_dev_add_lun(se_tpg, dev->se_hba, dev, |
768 | lun->unpacked_lun); | 768 | lun->unpacked_lun); |
769 | if (IS_ERR(lun_p) || !lun_p) { | 769 | if (IS_ERR(lun_p)) { |
770 | pr_err("core_dev_add_lun() failed\n"); | 770 | pr_err("core_dev_add_lun() failed\n"); |
771 | ret = -EINVAL; | 771 | ret = PTR_ERR(lun_p); |
772 | goto out; | 772 | goto out; |
773 | } | 773 | } |
774 | 774 | ||
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index cc8e6b58ef20..8572eae62da7 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -129,7 +129,7 @@ static struct se_device *iblock_create_virtdevice( | |||
129 | /* | 129 | /* |
130 | * These settings need to be made tunable.. | 130 | * These settings need to be made tunable.. |
131 | */ | 131 | */ |
132 | ib_dev->ibd_bio_set = bioset_create(32, 64); | 132 | ib_dev->ibd_bio_set = bioset_create(32, 0); |
133 | if (!ib_dev->ibd_bio_set) { | 133 | if (!ib_dev->ibd_bio_set) { |
134 | pr_err("IBLOCK: Unable to create bioset()\n"); | 134 | pr_err("IBLOCK: Unable to create bioset()\n"); |
135 | return ERR_PTR(-ENOMEM); | 135 | return ERR_PTR(-ENOMEM); |
@@ -181,7 +181,7 @@ static struct se_device *iblock_create_virtdevice( | |||
181 | */ | 181 | */ |
182 | dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count = 1; | 182 | dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count = 1; |
183 | dev->se_sub_dev->se_dev_attrib.unmap_granularity = | 183 | dev->se_sub_dev->se_dev_attrib.unmap_granularity = |
184 | q->limits.discard_granularity; | 184 | q->limits.discard_granularity >> 9; |
185 | dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment = | 185 | dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment = |
186 | q->limits.discard_alignment; | 186 | q->limits.discard_alignment; |
187 | 187 | ||
@@ -488,6 +488,13 @@ iblock_get_bio(struct se_task *task, sector_t lba, u32 sg_num) | |||
488 | struct iblock_req *ib_req = IBLOCK_REQ(task); | 488 | struct iblock_req *ib_req = IBLOCK_REQ(task); |
489 | struct bio *bio; | 489 | struct bio *bio; |
490 | 490 | ||
491 | /* | ||
492 | * Only allocate as many vector entries as the bio code allows us to, | ||
493 | * we'll loop later on until we have handled the whole request. | ||
494 | */ | ||
495 | if (sg_num > BIO_MAX_PAGES) | ||
496 | sg_num = BIO_MAX_PAGES; | ||
497 | |||
491 | bio = bio_alloc_bioset(GFP_NOIO, sg_num, ib_dev->ibd_bio_set); | 498 | bio = bio_alloc_bioset(GFP_NOIO, sg_num, ib_dev->ibd_bio_set); |
492 | if (!bio) { | 499 | if (!bio) { |
493 | pr_err("Unable to allocate memory for bio\n"); | 500 | pr_err("Unable to allocate memory for bio\n"); |
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 26f135e94f6e..45001364788a 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h | |||
@@ -90,7 +90,7 @@ void core_tpg_wait_for_nacl_pr_ref(struct se_node_acl *); | |||
90 | struct se_lun *core_tpg_pre_addlun(struct se_portal_group *, u32); | 90 | struct se_lun *core_tpg_pre_addlun(struct se_portal_group *, u32); |
91 | int core_tpg_post_addlun(struct se_portal_group *, struct se_lun *, | 91 | int core_tpg_post_addlun(struct se_portal_group *, struct se_lun *, |
92 | u32, void *); | 92 | u32, void *); |
93 | struct se_lun *core_tpg_pre_dellun(struct se_portal_group *, u32, int *); | 93 | struct se_lun *core_tpg_pre_dellun(struct se_portal_group *, u32 unpacked_lun); |
94 | int core_tpg_post_dellun(struct se_portal_group *, struct se_lun *); | 94 | int core_tpg_post_dellun(struct se_portal_group *, struct se_lun *); |
95 | 95 | ||
96 | /* target_core_transport.c */ | 96 | /* target_core_transport.c */ |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 429ad7291664..b7c779389eea 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -478,6 +478,7 @@ static int core_scsi3_pr_seq_non_holder( | |||
478 | case READ_MEDIA_SERIAL_NUMBER: | 478 | case READ_MEDIA_SERIAL_NUMBER: |
479 | case REPORT_LUNS: | 479 | case REPORT_LUNS: |
480 | case REQUEST_SENSE: | 480 | case REQUEST_SENSE: |
481 | case PERSISTENT_RESERVE_IN: | ||
481 | ret = 0; /*/ Allowed CDBs */ | 482 | ret = 0; /*/ Allowed CDBs */ |
482 | break; | 483 | break; |
483 | default: | 484 | default: |
@@ -1534,7 +1535,7 @@ static int core_scsi3_decode_spec_i_port( | |||
1534 | tidh_new->dest_local_nexus = 1; | 1535 | tidh_new->dest_local_nexus = 1; |
1535 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); | 1536 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); |
1536 | 1537 | ||
1537 | buf = transport_kmap_first_data_page(cmd); | 1538 | buf = transport_kmap_data_sg(cmd); |
1538 | /* | 1539 | /* |
1539 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, | 1540 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, |
1540 | * first extract TransportID Parameter Data Length, and make sure | 1541 | * first extract TransportID Parameter Data Length, and make sure |
@@ -1785,7 +1786,7 @@ static int core_scsi3_decode_spec_i_port( | |||
1785 | 1786 | ||
1786 | } | 1787 | } |
1787 | 1788 | ||
1788 | transport_kunmap_first_data_page(cmd); | 1789 | transport_kunmap_data_sg(cmd); |
1789 | 1790 | ||
1790 | /* | 1791 | /* |
1791 | * Go ahead and create a registrations from tid_dest_list for the | 1792 | * Go ahead and create a registrations from tid_dest_list for the |
@@ -1833,7 +1834,7 @@ static int core_scsi3_decode_spec_i_port( | |||
1833 | 1834 | ||
1834 | return 0; | 1835 | return 0; |
1835 | out: | 1836 | out: |
1836 | transport_kunmap_first_data_page(cmd); | 1837 | transport_kunmap_data_sg(cmd); |
1837 | /* | 1838 | /* |
1838 | * For the failure case, release everything from tid_dest_list | 1839 | * For the failure case, release everything from tid_dest_list |
1839 | * including *dest_pr_reg and the configfs dependances.. | 1840 | * including *dest_pr_reg and the configfs dependances.. |
@@ -3120,7 +3121,7 @@ static int core_scsi3_pro_preempt( | |||
3120 | if (!calling_it_nexus) | 3121 | if (!calling_it_nexus) |
3121 | core_scsi3_ua_allocate(pr_reg_nacl, | 3122 | core_scsi3_ua_allocate(pr_reg_nacl, |
3122 | pr_res_mapped_lun, 0x2A, | 3123 | pr_res_mapped_lun, 0x2A, |
3123 | ASCQ_2AH_RESERVATIONS_PREEMPTED); | 3124 | ASCQ_2AH_REGISTRATIONS_PREEMPTED); |
3124 | } | 3125 | } |
3125 | spin_unlock(&pr_tmpl->registration_lock); | 3126 | spin_unlock(&pr_tmpl->registration_lock); |
3126 | /* | 3127 | /* |
@@ -3233,7 +3234,7 @@ static int core_scsi3_pro_preempt( | |||
3233 | * additional sense code set to REGISTRATIONS PREEMPTED; | 3234 | * additional sense code set to REGISTRATIONS PREEMPTED; |
3234 | */ | 3235 | */ |
3235 | core_scsi3_ua_allocate(pr_reg_nacl, pr_res_mapped_lun, 0x2A, | 3236 | core_scsi3_ua_allocate(pr_reg_nacl, pr_res_mapped_lun, 0x2A, |
3236 | ASCQ_2AH_RESERVATIONS_PREEMPTED); | 3237 | ASCQ_2AH_REGISTRATIONS_PREEMPTED); |
3237 | } | 3238 | } |
3238 | spin_unlock(&pr_tmpl->registration_lock); | 3239 | spin_unlock(&pr_tmpl->registration_lock); |
3239 | /* | 3240 | /* |
@@ -3410,14 +3411,14 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3410 | * will be moved to for the TransportID containing SCSI initiator WWN | 3411 | * will be moved to for the TransportID containing SCSI initiator WWN |
3411 | * information. | 3412 | * information. |
3412 | */ | 3413 | */ |
3413 | buf = transport_kmap_first_data_page(cmd); | 3414 | buf = transport_kmap_data_sg(cmd); |
3414 | rtpi = (buf[18] & 0xff) << 8; | 3415 | rtpi = (buf[18] & 0xff) << 8; |
3415 | rtpi |= buf[19] & 0xff; | 3416 | rtpi |= buf[19] & 0xff; |
3416 | tid_len = (buf[20] & 0xff) << 24; | 3417 | tid_len = (buf[20] & 0xff) << 24; |
3417 | tid_len |= (buf[21] & 0xff) << 16; | 3418 | tid_len |= (buf[21] & 0xff) << 16; |
3418 | tid_len |= (buf[22] & 0xff) << 8; | 3419 | tid_len |= (buf[22] & 0xff) << 8; |
3419 | tid_len |= buf[23] & 0xff; | 3420 | tid_len |= buf[23] & 0xff; |
3420 | transport_kunmap_first_data_page(cmd); | 3421 | transport_kunmap_data_sg(cmd); |
3421 | buf = NULL; | 3422 | buf = NULL; |
3422 | 3423 | ||
3423 | if ((tid_len + 24) != cmd->data_length) { | 3424 | if ((tid_len + 24) != cmd->data_length) { |
@@ -3469,7 +3470,7 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3469 | return -EINVAL; | 3470 | return -EINVAL; |
3470 | } | 3471 | } |
3471 | 3472 | ||
3472 | buf = transport_kmap_first_data_page(cmd); | 3473 | buf = transport_kmap_data_sg(cmd); |
3473 | proto_ident = (buf[24] & 0x0f); | 3474 | proto_ident = (buf[24] & 0x0f); |
3474 | #if 0 | 3475 | #if 0 |
3475 | pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:" | 3476 | pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:" |
@@ -3503,7 +3504,7 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3503 | goto out; | 3504 | goto out; |
3504 | } | 3505 | } |
3505 | 3506 | ||
3506 | transport_kunmap_first_data_page(cmd); | 3507 | transport_kunmap_data_sg(cmd); |
3507 | buf = NULL; | 3508 | buf = NULL; |
3508 | 3509 | ||
3509 | pr_debug("SPC-3 PR [%s] Extracted initiator %s identifier: %s" | 3510 | pr_debug("SPC-3 PR [%s] Extracted initiator %s identifier: %s" |
@@ -3768,13 +3769,13 @@ after_iport_check: | |||
3768 | " REGISTER_AND_MOVE\n"); | 3769 | " REGISTER_AND_MOVE\n"); |
3769 | } | 3770 | } |
3770 | 3771 | ||
3771 | transport_kunmap_first_data_page(cmd); | 3772 | transport_kunmap_data_sg(cmd); |
3772 | 3773 | ||
3773 | core_scsi3_put_pr_reg(dest_pr_reg); | 3774 | core_scsi3_put_pr_reg(dest_pr_reg); |
3774 | return 0; | 3775 | return 0; |
3775 | out: | 3776 | out: |
3776 | if (buf) | 3777 | if (buf) |
3777 | transport_kunmap_first_data_page(cmd); | 3778 | transport_kunmap_data_sg(cmd); |
3778 | if (dest_se_deve) | 3779 | if (dest_se_deve) |
3779 | core_scsi3_lunacl_undepend_item(dest_se_deve); | 3780 | core_scsi3_lunacl_undepend_item(dest_se_deve); |
3780 | if (dest_node_acl) | 3781 | if (dest_node_acl) |
@@ -3848,7 +3849,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3848 | scope = (cdb[2] & 0xf0); | 3849 | scope = (cdb[2] & 0xf0); |
3849 | type = (cdb[2] & 0x0f); | 3850 | type = (cdb[2] & 0x0f); |
3850 | 3851 | ||
3851 | buf = transport_kmap_first_data_page(cmd); | 3852 | buf = transport_kmap_data_sg(cmd); |
3852 | /* | 3853 | /* |
3853 | * From PERSISTENT_RESERVE_OUT parameter list (payload) | 3854 | * From PERSISTENT_RESERVE_OUT parameter list (payload) |
3854 | */ | 3855 | */ |
@@ -3866,7 +3867,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3866 | aptpl = (buf[17] & 0x01); | 3867 | aptpl = (buf[17] & 0x01); |
3867 | unreg = (buf[17] & 0x02); | 3868 | unreg = (buf[17] & 0x02); |
3868 | } | 3869 | } |
3869 | transport_kunmap_first_data_page(cmd); | 3870 | transport_kunmap_data_sg(cmd); |
3870 | buf = NULL; | 3871 | buf = NULL; |
3871 | 3872 | ||
3872 | /* | 3873 | /* |
@@ -3966,7 +3967,7 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd) | |||
3966 | return -EINVAL; | 3967 | return -EINVAL; |
3967 | } | 3968 | } |
3968 | 3969 | ||
3969 | buf = transport_kmap_first_data_page(cmd); | 3970 | buf = transport_kmap_data_sg(cmd); |
3970 | buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff); | 3971 | buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff); |
3971 | buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff); | 3972 | buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff); |
3972 | buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff); | 3973 | buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff); |
@@ -4000,7 +4001,7 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd) | |||
4000 | buf[6] = ((add_len >> 8) & 0xff); | 4001 | buf[6] = ((add_len >> 8) & 0xff); |
4001 | buf[7] = (add_len & 0xff); | 4002 | buf[7] = (add_len & 0xff); |
4002 | 4003 | ||
4003 | transport_kunmap_first_data_page(cmd); | 4004 | transport_kunmap_data_sg(cmd); |
4004 | 4005 | ||
4005 | return 0; | 4006 | return 0; |
4006 | } | 4007 | } |
@@ -4026,7 +4027,7 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) | |||
4026 | return -EINVAL; | 4027 | return -EINVAL; |
4027 | } | 4028 | } |
4028 | 4029 | ||
4029 | buf = transport_kmap_first_data_page(cmd); | 4030 | buf = transport_kmap_data_sg(cmd); |
4030 | buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff); | 4031 | buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff); |
4031 | buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff); | 4032 | buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff); |
4032 | buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff); | 4033 | buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff); |
@@ -4085,7 +4086,7 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) | |||
4085 | 4086 | ||
4086 | err: | 4087 | err: |
4087 | spin_unlock(&se_dev->dev_reservation_lock); | 4088 | spin_unlock(&se_dev->dev_reservation_lock); |
4088 | transport_kunmap_first_data_page(cmd); | 4089 | transport_kunmap_data_sg(cmd); |
4089 | 4090 | ||
4090 | return 0; | 4091 | return 0; |
4091 | } | 4092 | } |
@@ -4109,7 +4110,7 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) | |||
4109 | return -EINVAL; | 4110 | return -EINVAL; |
4110 | } | 4111 | } |
4111 | 4112 | ||
4112 | buf = transport_kmap_first_data_page(cmd); | 4113 | buf = transport_kmap_data_sg(cmd); |
4113 | 4114 | ||
4114 | buf[0] = ((add_len << 8) & 0xff); | 4115 | buf[0] = ((add_len << 8) & 0xff); |
4115 | buf[1] = (add_len & 0xff); | 4116 | buf[1] = (add_len & 0xff); |
@@ -4141,7 +4142,7 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) | |||
4141 | buf[4] |= 0x02; /* PR_TYPE_WRITE_EXCLUSIVE */ | 4142 | buf[4] |= 0x02; /* PR_TYPE_WRITE_EXCLUSIVE */ |
4142 | buf[5] |= 0x01; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */ | 4143 | buf[5] |= 0x01; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */ |
4143 | 4144 | ||
4144 | transport_kunmap_first_data_page(cmd); | 4145 | transport_kunmap_data_sg(cmd); |
4145 | 4146 | ||
4146 | return 0; | 4147 | return 0; |
4147 | } | 4148 | } |
@@ -4171,7 +4172,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | |||
4171 | return -EINVAL; | 4172 | return -EINVAL; |
4172 | } | 4173 | } |
4173 | 4174 | ||
4174 | buf = transport_kmap_first_data_page(cmd); | 4175 | buf = transport_kmap_data_sg(cmd); |
4175 | 4176 | ||
4176 | buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff); | 4177 | buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff); |
4177 | buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff); | 4178 | buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff); |
@@ -4292,7 +4293,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | |||
4292 | buf[6] = ((add_len >> 8) & 0xff); | 4293 | buf[6] = ((add_len >> 8) & 0xff); |
4293 | buf[7] = (add_len & 0xff); | 4294 | buf[7] = (add_len & 0xff); |
4294 | 4295 | ||
4295 | transport_kunmap_first_data_page(cmd); | 4296 | transport_kunmap_data_sg(cmd); |
4296 | 4297 | ||
4297 | return 0; | 4298 | return 0; |
4298 | } | 4299 | } |
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index d35467d42e12..8d4def30e9e8 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -693,7 +693,7 @@ static int pscsi_transport_complete(struct se_task *task) | |||
693 | 693 | ||
694 | if (task->task_se_cmd->se_deve->lun_flags & | 694 | if (task->task_se_cmd->se_deve->lun_flags & |
695 | TRANSPORT_LUNFLAGS_READ_ONLY) { | 695 | TRANSPORT_LUNFLAGS_READ_ONLY) { |
696 | unsigned char *buf = transport_kmap_first_data_page(task->task_se_cmd); | 696 | unsigned char *buf = transport_kmap_data_sg(task->task_se_cmd); |
697 | 697 | ||
698 | if (cdb[0] == MODE_SENSE_10) { | 698 | if (cdb[0] == MODE_SENSE_10) { |
699 | if (!(buf[3] & 0x80)) | 699 | if (!(buf[3] & 0x80)) |
@@ -703,7 +703,7 @@ static int pscsi_transport_complete(struct se_task *task) | |||
703 | buf[2] |= 0x80; | 703 | buf[2] |= 0x80; |
704 | } | 704 | } |
705 | 705 | ||
706 | transport_kunmap_first_data_page(task->task_se_cmd); | 706 | transport_kunmap_data_sg(task->task_se_cmd); |
707 | } | 707 | } |
708 | } | 708 | } |
709 | after_mode_sense: | 709 | after_mode_sense: |
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index b7668029bb31..06336ecd872d 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c | |||
@@ -807,8 +807,7 @@ static void core_tpg_shutdown_lun( | |||
807 | 807 | ||
808 | struct se_lun *core_tpg_pre_dellun( | 808 | struct se_lun *core_tpg_pre_dellun( |
809 | struct se_portal_group *tpg, | 809 | struct se_portal_group *tpg, |
810 | u32 unpacked_lun, | 810 | u32 unpacked_lun) |
811 | int *ret) | ||
812 | { | 811 | { |
813 | struct se_lun *lun; | 812 | struct se_lun *lun; |
814 | 813 | ||
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index d3ddd1361949..58cea07b12fb 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -1255,32 +1255,34 @@ static void core_setup_task_attr_emulation(struct se_device *dev) | |||
1255 | static void scsi_dump_inquiry(struct se_device *dev) | 1255 | static void scsi_dump_inquiry(struct se_device *dev) |
1256 | { | 1256 | { |
1257 | struct t10_wwn *wwn = &dev->se_sub_dev->t10_wwn; | 1257 | struct t10_wwn *wwn = &dev->se_sub_dev->t10_wwn; |
1258 | char buf[17]; | ||
1258 | int i, device_type; | 1259 | int i, device_type; |
1259 | /* | 1260 | /* |
1260 | * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer | 1261 | * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer |
1261 | */ | 1262 | */ |
1262 | pr_debug(" Vendor: "); | ||
1263 | for (i = 0; i < 8; i++) | 1263 | for (i = 0; i < 8; i++) |
1264 | if (wwn->vendor[i] >= 0x20) | 1264 | if (wwn->vendor[i] >= 0x20) |
1265 | pr_debug("%c", wwn->vendor[i]); | 1265 | buf[i] = wwn->vendor[i]; |
1266 | else | 1266 | else |
1267 | pr_debug(" "); | 1267 | buf[i] = ' '; |
1268 | buf[i] = '\0'; | ||
1269 | pr_debug(" Vendor: %s\n", buf); | ||
1268 | 1270 | ||
1269 | pr_debug(" Model: "); | ||
1270 | for (i = 0; i < 16; i++) | 1271 | for (i = 0; i < 16; i++) |
1271 | if (wwn->model[i] >= 0x20) | 1272 | if (wwn->model[i] >= 0x20) |
1272 | pr_debug("%c", wwn->model[i]); | 1273 | buf[i] = wwn->model[i]; |
1273 | else | 1274 | else |
1274 | pr_debug(" "); | 1275 | buf[i] = ' '; |
1276 | buf[i] = '\0'; | ||
1277 | pr_debug(" Model: %s\n", buf); | ||
1275 | 1278 | ||
1276 | pr_debug(" Revision: "); | ||
1277 | for (i = 0; i < 4; i++) | 1279 | for (i = 0; i < 4; i++) |
1278 | if (wwn->revision[i] >= 0x20) | 1280 | if (wwn->revision[i] >= 0x20) |
1279 | pr_debug("%c", wwn->revision[i]); | 1281 | buf[i] = wwn->revision[i]; |
1280 | else | 1282 | else |
1281 | pr_debug(" "); | 1283 | buf[i] = ' '; |
1282 | 1284 | buf[i] = '\0'; | |
1283 | pr_debug("\n"); | 1285 | pr_debug(" Revision: %s\n", buf); |
1284 | 1286 | ||
1285 | device_type = dev->transport->get_device_type(dev); | 1287 | device_type = dev->transport->get_device_type(dev); |
1286 | pr_debug(" Type: %s ", scsi_device_type(device_type)); | 1288 | pr_debug(" Type: %s ", scsi_device_type(device_type)); |
@@ -1655,7 +1657,7 @@ EXPORT_SYMBOL(transport_handle_cdb_direct); | |||
1655 | * This may only be called from process context, and also currently | 1657 | * This may only be called from process context, and also currently |
1656 | * assumes internal allocation of fabric payload buffer by target-core. | 1658 | * assumes internal allocation of fabric payload buffer by target-core. |
1657 | **/ | 1659 | **/ |
1658 | int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, | 1660 | void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, |
1659 | unsigned char *cdb, unsigned char *sense, u32 unpacked_lun, | 1661 | unsigned char *cdb, unsigned char *sense, u32 unpacked_lun, |
1660 | u32 data_length, int task_attr, int data_dir, int flags) | 1662 | u32 data_length, int task_attr, int data_dir, int flags) |
1661 | { | 1663 | { |
@@ -1688,15 +1690,21 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, | |||
1688 | /* | 1690 | /* |
1689 | * Locate se_lun pointer and attach it to struct se_cmd | 1691 | * Locate se_lun pointer and attach it to struct se_cmd |
1690 | */ | 1692 | */ |
1691 | if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0) | 1693 | if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0) { |
1692 | goto out_check_cond; | 1694 | transport_send_check_condition_and_sense(se_cmd, |
1695 | se_cmd->scsi_sense_reason, 0); | ||
1696 | target_put_sess_cmd(se_sess, se_cmd); | ||
1697 | return; | ||
1698 | } | ||
1693 | /* | 1699 | /* |
1694 | * Sanitize CDBs via transport_generic_cmd_sequencer() and | 1700 | * Sanitize CDBs via transport_generic_cmd_sequencer() and |
1695 | * allocate the necessary tasks to complete the received CDB+data | 1701 | * allocate the necessary tasks to complete the received CDB+data |
1696 | */ | 1702 | */ |
1697 | rc = transport_generic_allocate_tasks(se_cmd, cdb); | 1703 | rc = transport_generic_allocate_tasks(se_cmd, cdb); |
1698 | if (rc != 0) | 1704 | if (rc != 0) { |
1699 | goto out_check_cond; | 1705 | transport_generic_request_failure(se_cmd); |
1706 | return; | ||
1707 | } | ||
1700 | /* | 1708 | /* |
1701 | * Dispatch se_cmd descriptor to se_lun->lun_se_dev backend | 1709 | * Dispatch se_cmd descriptor to se_lun->lun_se_dev backend |
1702 | * for immediate execution of READs, otherwise wait for | 1710 | * for immediate execution of READs, otherwise wait for |
@@ -1704,12 +1712,7 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, | |||
1704 | * when fabric has filled the incoming buffer. | 1712 | * when fabric has filled the incoming buffer. |
1705 | */ | 1713 | */ |
1706 | transport_handle_cdb_direct(se_cmd); | 1714 | transport_handle_cdb_direct(se_cmd); |
1707 | return 0; | 1715 | return; |
1708 | |||
1709 | out_check_cond: | ||
1710 | transport_send_check_condition_and_sense(se_cmd, | ||
1711 | se_cmd->scsi_sense_reason, 0); | ||
1712 | return 0; | ||
1713 | } | 1716 | } |
1714 | EXPORT_SYMBOL(target_submit_cmd); | 1717 | EXPORT_SYMBOL(target_submit_cmd); |
1715 | 1718 | ||
@@ -2694,7 +2697,7 @@ static int transport_generic_cmd_sequencer( | |||
2694 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; | 2697 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; |
2695 | 2698 | ||
2696 | if (target_check_write_same_discard(&cdb[10], dev) < 0) | 2699 | if (target_check_write_same_discard(&cdb[10], dev) < 0) |
2697 | goto out_invalid_cdb_field; | 2700 | goto out_unsupported_cdb; |
2698 | if (!passthrough) | 2701 | if (!passthrough) |
2699 | cmd->execute_task = target_emulate_write_same; | 2702 | cmd->execute_task = target_emulate_write_same; |
2700 | break; | 2703 | break; |
@@ -2977,7 +2980,7 @@ static int transport_generic_cmd_sequencer( | |||
2977 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; | 2980 | cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB; |
2978 | 2981 | ||
2979 | if (target_check_write_same_discard(&cdb[1], dev) < 0) | 2982 | if (target_check_write_same_discard(&cdb[1], dev) < 0) |
2980 | goto out_invalid_cdb_field; | 2983 | goto out_unsupported_cdb; |
2981 | if (!passthrough) | 2984 | if (!passthrough) |
2982 | cmd->execute_task = target_emulate_write_same; | 2985 | cmd->execute_task = target_emulate_write_same; |
2983 | break; | 2986 | break; |
@@ -3000,7 +3003,7 @@ static int transport_generic_cmd_sequencer( | |||
3000 | * of byte 1 bit 3 UNMAP instead of original reserved field | 3003 | * of byte 1 bit 3 UNMAP instead of original reserved field |
3001 | */ | 3004 | */ |
3002 | if (target_check_write_same_discard(&cdb[1], dev) < 0) | 3005 | if (target_check_write_same_discard(&cdb[1], dev) < 0) |
3003 | goto out_invalid_cdb_field; | 3006 | goto out_unsupported_cdb; |
3004 | if (!passthrough) | 3007 | if (!passthrough) |
3005 | cmd->execute_task = target_emulate_write_same; | 3008 | cmd->execute_task = target_emulate_write_same; |
3006 | break; | 3009 | break; |
@@ -3082,11 +3085,6 @@ static int transport_generic_cmd_sequencer( | |||
3082 | (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB))) | 3085 | (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB))) |
3083 | goto out_unsupported_cdb; | 3086 | goto out_unsupported_cdb; |
3084 | 3087 | ||
3085 | /* Let's limit control cdbs to a page, for simplicity's sake. */ | ||
3086 | if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) && | ||
3087 | size > PAGE_SIZE) | ||
3088 | goto out_invalid_cdb_field; | ||
3089 | |||
3090 | transport_set_supported_SAM_opcode(cmd); | 3088 | transport_set_supported_SAM_opcode(cmd); |
3091 | return ret; | 3089 | return ret; |
3092 | 3090 | ||
@@ -3490,9 +3488,11 @@ int transport_generic_map_mem_to_cmd( | |||
3490 | } | 3488 | } |
3491 | EXPORT_SYMBOL(transport_generic_map_mem_to_cmd); | 3489 | EXPORT_SYMBOL(transport_generic_map_mem_to_cmd); |
3492 | 3490 | ||
3493 | void *transport_kmap_first_data_page(struct se_cmd *cmd) | 3491 | void *transport_kmap_data_sg(struct se_cmd *cmd) |
3494 | { | 3492 | { |
3495 | struct scatterlist *sg = cmd->t_data_sg; | 3493 | struct scatterlist *sg = cmd->t_data_sg; |
3494 | struct page **pages; | ||
3495 | int i; | ||
3496 | 3496 | ||
3497 | BUG_ON(!sg); | 3497 | BUG_ON(!sg); |
3498 | /* | 3498 | /* |
@@ -3500,15 +3500,41 @@ void *transport_kmap_first_data_page(struct se_cmd *cmd) | |||
3500 | * tcm_loop who may be using a contig buffer from the SCSI midlayer for | 3500 | * tcm_loop who may be using a contig buffer from the SCSI midlayer for |
3501 | * control CDBs passed as SGLs via transport_generic_map_mem_to_cmd() | 3501 | * control CDBs passed as SGLs via transport_generic_map_mem_to_cmd() |
3502 | */ | 3502 | */ |
3503 | return kmap(sg_page(sg)) + sg->offset; | 3503 | if (!cmd->t_data_nents) |
3504 | return NULL; | ||
3505 | else if (cmd->t_data_nents == 1) | ||
3506 | return kmap(sg_page(sg)) + sg->offset; | ||
3507 | |||
3508 | /* >1 page. use vmap */ | ||
3509 | pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); | ||
3510 | if (!pages) | ||
3511 | return NULL; | ||
3512 | |||
3513 | /* convert sg[] to pages[] */ | ||
3514 | for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { | ||
3515 | pages[i] = sg_page(sg); | ||
3516 | } | ||
3517 | |||
3518 | cmd->t_data_vmap = vmap(pages, cmd->t_data_nents, VM_MAP, PAGE_KERNEL); | ||
3519 | kfree(pages); | ||
3520 | if (!cmd->t_data_vmap) | ||
3521 | return NULL; | ||
3522 | |||
3523 | return cmd->t_data_vmap + cmd->t_data_sg[0].offset; | ||
3504 | } | 3524 | } |
3505 | EXPORT_SYMBOL(transport_kmap_first_data_page); | 3525 | EXPORT_SYMBOL(transport_kmap_data_sg); |
3506 | 3526 | ||
3507 | void transport_kunmap_first_data_page(struct se_cmd *cmd) | 3527 | void transport_kunmap_data_sg(struct se_cmd *cmd) |
3508 | { | 3528 | { |
3509 | kunmap(sg_page(cmd->t_data_sg)); | 3529 | if (!cmd->t_data_nents) |
3530 | return; | ||
3531 | else if (cmd->t_data_nents == 1) | ||
3532 | kunmap(sg_page(cmd->t_data_sg)); | ||
3533 | |||
3534 | vunmap(cmd->t_data_vmap); | ||
3535 | cmd->t_data_vmap = NULL; | ||
3510 | } | 3536 | } |
3511 | EXPORT_SYMBOL(transport_kunmap_first_data_page); | 3537 | EXPORT_SYMBOL(transport_kunmap_data_sg); |
3512 | 3538 | ||
3513 | static int | 3539 | static int |
3514 | transport_generic_get_mem(struct se_cmd *cmd) | 3540 | transport_generic_get_mem(struct se_cmd *cmd) |
@@ -3516,6 +3542,7 @@ transport_generic_get_mem(struct se_cmd *cmd) | |||
3516 | u32 length = cmd->data_length; | 3542 | u32 length = cmd->data_length; |
3517 | unsigned int nents; | 3543 | unsigned int nents; |
3518 | struct page *page; | 3544 | struct page *page; |
3545 | gfp_t zero_flag; | ||
3519 | int i = 0; | 3546 | int i = 0; |
3520 | 3547 | ||
3521 | nents = DIV_ROUND_UP(length, PAGE_SIZE); | 3548 | nents = DIV_ROUND_UP(length, PAGE_SIZE); |
@@ -3526,9 +3553,11 @@ transport_generic_get_mem(struct se_cmd *cmd) | |||
3526 | cmd->t_data_nents = nents; | 3553 | cmd->t_data_nents = nents; |
3527 | sg_init_table(cmd->t_data_sg, nents); | 3554 | sg_init_table(cmd->t_data_sg, nents); |
3528 | 3555 | ||
3556 | zero_flag = cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB ? 0 : __GFP_ZERO; | ||
3557 | |||
3529 | while (length) { | 3558 | while (length) { |
3530 | u32 page_len = min_t(u32, length, PAGE_SIZE); | 3559 | u32 page_len = min_t(u32, length, PAGE_SIZE); |
3531 | page = alloc_page(GFP_KERNEL | __GFP_ZERO); | 3560 | page = alloc_page(GFP_KERNEL | zero_flag); |
3532 | if (!page) | 3561 | if (!page) |
3533 | goto out; | 3562 | goto out; |
3534 | 3563 | ||
@@ -3756,6 +3785,11 @@ transport_allocate_control_task(struct se_cmd *cmd) | |||
3756 | struct se_task *task; | 3785 | struct se_task *task; |
3757 | unsigned long flags; | 3786 | unsigned long flags; |
3758 | 3787 | ||
3788 | /* Workaround for handling zero-length control CDBs */ | ||
3789 | if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) && | ||
3790 | !cmd->data_length) | ||
3791 | return 0; | ||
3792 | |||
3759 | task = transport_generic_get_task(cmd, cmd->data_direction); | 3793 | task = transport_generic_get_task(cmd, cmd->data_direction); |
3760 | if (!task) | 3794 | if (!task) |
3761 | return -ENOMEM; | 3795 | return -ENOMEM; |
@@ -3827,6 +3861,14 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
3827 | else if (!task_cdbs && (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)) { | 3861 | else if (!task_cdbs && (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)) { |
3828 | cmd->t_state = TRANSPORT_COMPLETE; | 3862 | cmd->t_state = TRANSPORT_COMPLETE; |
3829 | atomic_set(&cmd->t_transport_active, 1); | 3863 | atomic_set(&cmd->t_transport_active, 1); |
3864 | |||
3865 | if (cmd->t_task_cdb[0] == REQUEST_SENSE) { | ||
3866 | u8 ua_asc = 0, ua_ascq = 0; | ||
3867 | |||
3868 | core_scsi3_ua_clear_for_request_sense(cmd, | ||
3869 | &ua_asc, &ua_ascq); | ||
3870 | } | ||
3871 | |||
3830 | INIT_WORK(&cmd->work, target_complete_ok_work); | 3872 | INIT_WORK(&cmd->work, target_complete_ok_work); |
3831 | queue_work(target_completion_wq, &cmd->work); | 3873 | queue_work(target_completion_wq, &cmd->work); |
3832 | return 0; | 3874 | return 0; |
@@ -4448,8 +4490,8 @@ int transport_send_check_condition_and_sense( | |||
4448 | /* CURRENT ERROR */ | 4490 | /* CURRENT ERROR */ |
4449 | buffer[offset] = 0x70; | 4491 | buffer[offset] = 0x70; |
4450 | buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; | 4492 | buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; |
4451 | /* ABORTED COMMAND */ | 4493 | /* ILLEGAL REQUEST */ |
4452 | buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; | 4494 | buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; |
4453 | /* INVALID FIELD IN CDB */ | 4495 | /* INVALID FIELD IN CDB */ |
4454 | buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24; | 4496 | buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24; |
4455 | break; | 4497 | break; |
@@ -4457,8 +4499,8 @@ int transport_send_check_condition_and_sense( | |||
4457 | /* CURRENT ERROR */ | 4499 | /* CURRENT ERROR */ |
4458 | buffer[offset] = 0x70; | 4500 | buffer[offset] = 0x70; |
4459 | buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; | 4501 | buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; |
4460 | /* ABORTED COMMAND */ | 4502 | /* ILLEGAL REQUEST */ |
4461 | buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; | 4503 | buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; |
4462 | /* INVALID FIELD IN PARAMETER LIST */ | 4504 | /* INVALID FIELD IN PARAMETER LIST */ |
4463 | buffer[offset+SPC_ASC_KEY_OFFSET] = 0x26; | 4505 | buffer[offset+SPC_ASC_KEY_OFFSET] = 0x26; |
4464 | break; | 4506 | break; |
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index addc18f727ea..9e7e26c74c79 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c | |||
@@ -540,7 +540,6 @@ static void ft_send_work(struct work_struct *work) | |||
540 | int data_dir = 0; | 540 | int data_dir = 0; |
541 | u32 data_len; | 541 | u32 data_len; |
542 | int task_attr; | 542 | int task_attr; |
543 | int ret; | ||
544 | 543 | ||
545 | fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp)); | 544 | fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp)); |
546 | if (!fcp) | 545 | if (!fcp) |
@@ -603,14 +602,10 @@ static void ft_send_work(struct work_struct *work) | |||
603 | * Use a single se_cmd->cmd_kref as we expect to release se_cmd | 602 | * Use a single se_cmd->cmd_kref as we expect to release se_cmd |
604 | * directly from ft_check_stop_free callback in response path. | 603 | * directly from ft_check_stop_free callback in response path. |
605 | */ | 604 | */ |
606 | ret = target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, cmd->cdb, | 605 | target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, cmd->cdb, |
607 | &cmd->ft_sense_buffer[0], cmd->lun, data_len, | 606 | &cmd->ft_sense_buffer[0], cmd->lun, data_len, |
608 | task_attr, data_dir, 0); | 607 | task_attr, data_dir, 0); |
609 | pr_debug("r_ctl %x alloc target_submit_cmd %d\n", fh->fh_r_ctl, ret); | 608 | pr_debug("r_ctl %x alloc target_submit_cmd\n", fh->fh_r_ctl); |
610 | if (ret < 0) { | ||
611 | ft_dump_cmd(cmd, __func__); | ||
612 | return; | ||
613 | } | ||
614 | return; | 609 | return; |
615 | 610 | ||
616 | err: | 611 | err: |