diff options
21 files changed, 266 insertions, 140 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: |
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index 4866499bdeeb..e5e6ff98f0fa 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h | |||
| @@ -59,7 +59,7 @@ int transport_set_vpd_ident_type(struct t10_vpd *, unsigned char *); | |||
| 59 | int transport_set_vpd_ident(struct t10_vpd *, unsigned char *); | 59 | int transport_set_vpd_ident(struct t10_vpd *, unsigned char *); |
| 60 | 60 | ||
| 61 | /* core helpers also used by command snooping in pscsi */ | 61 | /* core helpers also used by command snooping in pscsi */ |
| 62 | void *transport_kmap_first_data_page(struct se_cmd *); | 62 | void *transport_kmap_data_sg(struct se_cmd *); |
| 63 | void transport_kunmap_first_data_page(struct se_cmd *); | 63 | void transport_kunmap_data_sg(struct se_cmd *); |
| 64 | 64 | ||
| 65 | #endif /* TARGET_CORE_BACKEND_H */ | 65 | #endif /* TARGET_CORE_BACKEND_H */ |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index daf532bc721a..dc4e345a0163 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
| @@ -582,6 +582,7 @@ struct se_cmd { | |||
| 582 | 582 | ||
| 583 | struct scatterlist *t_data_sg; | 583 | struct scatterlist *t_data_sg; |
| 584 | unsigned int t_data_nents; | 584 | unsigned int t_data_nents; |
| 585 | void *t_data_vmap; | ||
| 585 | struct scatterlist *t_bidi_data_sg; | 586 | struct scatterlist *t_bidi_data_sg; |
| 586 | unsigned int t_bidi_data_nents; | 587 | unsigned int t_bidi_data_nents; |
| 587 | 588 | ||
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 523e8bc104d4..d36fad317e78 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h | |||
| @@ -114,7 +114,7 @@ void transport_init_se_cmd(struct se_cmd *, struct target_core_fabric_ops *, | |||
| 114 | struct se_session *, u32, int, int, unsigned char *); | 114 | struct se_session *, u32, int, int, unsigned char *); |
| 115 | int transport_lookup_cmd_lun(struct se_cmd *, u32); | 115 | int transport_lookup_cmd_lun(struct se_cmd *, u32); |
| 116 | int transport_generic_allocate_tasks(struct se_cmd *, unsigned char *); | 116 | int transport_generic_allocate_tasks(struct se_cmd *, unsigned char *); |
| 117 | int target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, | 117 | void target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, |
| 118 | unsigned char *, u32, u32, int, int, int); | 118 | unsigned char *, u32, u32, int, int, int); |
| 119 | int transport_handle_cdb_direct(struct se_cmd *); | 119 | int transport_handle_cdb_direct(struct se_cmd *); |
| 120 | int transport_generic_handle_cdb_map(struct se_cmd *); | 120 | int transport_generic_handle_cdb_map(struct se_cmd *); |
