diff options
36 files changed, 1413 insertions, 1084 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 2693129055c1..3f62041222f2 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
@@ -388,6 +388,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
388 | init_waitqueue_head(&isert_conn->conn_wait_comp_err); | 388 | init_waitqueue_head(&isert_conn->conn_wait_comp_err); |
389 | kref_init(&isert_conn->conn_kref); | 389 | kref_init(&isert_conn->conn_kref); |
390 | kref_get(&isert_conn->conn_kref); | 390 | kref_get(&isert_conn->conn_kref); |
391 | mutex_init(&isert_conn->conn_mutex); | ||
391 | 392 | ||
392 | cma_id->context = isert_conn; | 393 | cma_id->context = isert_conn; |
393 | isert_conn->conn_cm_id = cma_id; | 394 | isert_conn->conn_cm_id = cma_id; |
@@ -540,15 +541,32 @@ isert_disconnect_work(struct work_struct *work) | |||
540 | struct isert_conn, conn_logout_work); | 541 | struct isert_conn, conn_logout_work); |
541 | 542 | ||
542 | pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); | 543 | pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); |
543 | 544 | mutex_lock(&isert_conn->conn_mutex); | |
544 | isert_conn->state = ISER_CONN_DOWN; | 545 | isert_conn->state = ISER_CONN_DOWN; |
545 | 546 | ||
546 | if (isert_conn->post_recv_buf_count == 0 && | 547 | if (isert_conn->post_recv_buf_count == 0 && |
547 | atomic_read(&isert_conn->post_send_buf_count) == 0) { | 548 | atomic_read(&isert_conn->post_send_buf_count) == 0) { |
548 | pr_debug("Calling wake_up(&isert_conn->conn_wait);\n"); | 549 | pr_debug("Calling wake_up(&isert_conn->conn_wait);\n"); |
549 | wake_up(&isert_conn->conn_wait); | 550 | mutex_unlock(&isert_conn->conn_mutex); |
551 | goto wake_up; | ||
552 | } | ||
553 | if (!isert_conn->conn_cm_id) { | ||
554 | mutex_unlock(&isert_conn->conn_mutex); | ||
555 | isert_put_conn(isert_conn); | ||
556 | return; | ||
550 | } | 557 | } |
558 | if (!isert_conn->logout_posted) { | ||
559 | pr_debug("Calling rdma_disconnect for !logout_posted from" | ||
560 | " isert_disconnect_work\n"); | ||
561 | rdma_disconnect(isert_conn->conn_cm_id); | ||
562 | mutex_unlock(&isert_conn->conn_mutex); | ||
563 | iscsit_cause_connection_reinstatement(isert_conn->conn, 0); | ||
564 | goto wake_up; | ||
565 | } | ||
566 | mutex_unlock(&isert_conn->conn_mutex); | ||
551 | 567 | ||
568 | wake_up: | ||
569 | wake_up(&isert_conn->conn_wait); | ||
552 | isert_put_conn(isert_conn); | 570 | isert_put_conn(isert_conn); |
553 | } | 571 | } |
554 | 572 | ||
@@ -934,16 +952,11 @@ isert_handle_scsi_cmd(struct isert_conn *isert_conn, | |||
934 | } | 952 | } |
935 | 953 | ||
936 | sequence_cmd: | 954 | sequence_cmd: |
937 | rc = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); | 955 | rc = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn); |
938 | 956 | ||
939 | if (!rc && dump_payload == false && unsol_data) | 957 | if (!rc && dump_payload == false && unsol_data) |
940 | iscsit_set_unsoliticed_dataout(cmd); | 958 | iscsit_set_unsoliticed_dataout(cmd); |
941 | 959 | ||
942 | if (rc == CMDSN_ERROR_CANNOT_RECOVER) | ||
943 | return iscsit_add_reject_from_cmd( | ||
944 | ISCSI_REASON_PROTOCOL_ERROR, | ||
945 | 1, 0, (unsigned char *)hdr, cmd); | ||
946 | |||
947 | return 0; | 960 | return 0; |
948 | } | 961 | } |
949 | 962 | ||
@@ -1001,17 +1014,71 @@ isert_handle_iscsi_dataout(struct isert_conn *isert_conn, | |||
1001 | } | 1014 | } |
1002 | 1015 | ||
1003 | static int | 1016 | static int |
1017 | isert_handle_nop_out(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd, | ||
1018 | struct iser_rx_desc *rx_desc, unsigned char *buf) | ||
1019 | { | ||
1020 | struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; | ||
1021 | struct iscsi_conn *conn = isert_conn->conn; | ||
1022 | struct iscsi_nopout *hdr = (struct iscsi_nopout *)buf; | ||
1023 | int rc; | ||
1024 | |||
1025 | rc = iscsit_setup_nop_out(conn, cmd, hdr); | ||
1026 | if (rc < 0) | ||
1027 | return rc; | ||
1028 | /* | ||
1029 | * FIXME: Add support for NOPOUT payload using unsolicited RDMA payload | ||
1030 | */ | ||
1031 | |||
1032 | return iscsit_process_nop_out(conn, cmd, hdr); | ||
1033 | } | ||
1034 | |||
1035 | static int | ||
1036 | isert_handle_text_cmd(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd, | ||
1037 | struct iser_rx_desc *rx_desc, struct iscsi_text *hdr) | ||
1038 | { | ||
1039 | struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; | ||
1040 | struct iscsi_conn *conn = isert_conn->conn; | ||
1041 | u32 payload_length = ntoh24(hdr->dlength); | ||
1042 | int rc; | ||
1043 | unsigned char *text_in; | ||
1044 | |||
1045 | rc = iscsit_setup_text_cmd(conn, cmd, hdr); | ||
1046 | if (rc < 0) | ||
1047 | return rc; | ||
1048 | |||
1049 | text_in = kzalloc(payload_length, GFP_KERNEL); | ||
1050 | if (!text_in) { | ||
1051 | pr_err("Unable to allocate text_in of payload_length: %u\n", | ||
1052 | payload_length); | ||
1053 | return -ENOMEM; | ||
1054 | } | ||
1055 | cmd->text_in_ptr = text_in; | ||
1056 | |||
1057 | memcpy(cmd->text_in_ptr, &rx_desc->data[0], payload_length); | ||
1058 | |||
1059 | return iscsit_process_text_cmd(conn, cmd, hdr); | ||
1060 | } | ||
1061 | |||
1062 | static int | ||
1004 | isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, | 1063 | isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, |
1005 | uint32_t read_stag, uint64_t read_va, | 1064 | uint32_t read_stag, uint64_t read_va, |
1006 | uint32_t write_stag, uint64_t write_va) | 1065 | uint32_t write_stag, uint64_t write_va) |
1007 | { | 1066 | { |
1008 | struct iscsi_hdr *hdr = &rx_desc->iscsi_header; | 1067 | struct iscsi_hdr *hdr = &rx_desc->iscsi_header; |
1009 | struct iscsi_conn *conn = isert_conn->conn; | 1068 | struct iscsi_conn *conn = isert_conn->conn; |
1069 | struct iscsi_session *sess = conn->sess; | ||
1010 | struct iscsi_cmd *cmd; | 1070 | struct iscsi_cmd *cmd; |
1011 | struct isert_cmd *isert_cmd; | 1071 | struct isert_cmd *isert_cmd; |
1012 | int ret = -EINVAL; | 1072 | int ret = -EINVAL; |
1013 | u8 opcode = (hdr->opcode & ISCSI_OPCODE_MASK); | 1073 | u8 opcode = (hdr->opcode & ISCSI_OPCODE_MASK); |
1014 | 1074 | ||
1075 | if (sess->sess_ops->SessionType && | ||
1076 | (!(opcode & ISCSI_OP_TEXT) || !(opcode & ISCSI_OP_LOGOUT))) { | ||
1077 | pr_err("Got illegal opcode: 0x%02x in SessionType=Discovery," | ||
1078 | " ignoring\n", opcode); | ||
1079 | return 0; | ||
1080 | } | ||
1081 | |||
1015 | switch (opcode) { | 1082 | switch (opcode) { |
1016 | case ISCSI_OP_SCSI_CMD: | 1083 | case ISCSI_OP_SCSI_CMD: |
1017 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 1084 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
@@ -1032,7 +1099,9 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, | |||
1032 | if (!cmd) | 1099 | if (!cmd) |
1033 | break; | 1100 | break; |
1034 | 1101 | ||
1035 | ret = iscsit_handle_nop_out(conn, cmd, (unsigned char *)hdr); | 1102 | isert_cmd = container_of(cmd, struct isert_cmd, iscsi_cmd); |
1103 | ret = isert_handle_nop_out(isert_conn, isert_cmd, | ||
1104 | rx_desc, (unsigned char *)hdr); | ||
1036 | break; | 1105 | break; |
1037 | case ISCSI_OP_SCSI_DATA_OUT: | 1106 | case ISCSI_OP_SCSI_DATA_OUT: |
1038 | ret = isert_handle_iscsi_dataout(isert_conn, rx_desc, | 1107 | ret = isert_handle_iscsi_dataout(isert_conn, rx_desc, |
@@ -1057,6 +1126,15 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, | |||
1057 | SECONDS_FOR_LOGOUT_COMP * | 1126 | SECONDS_FOR_LOGOUT_COMP * |
1058 | HZ); | 1127 | HZ); |
1059 | break; | 1128 | break; |
1129 | case ISCSI_OP_TEXT: | ||
1130 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | ||
1131 | if (!cmd) | ||
1132 | break; | ||
1133 | |||
1134 | isert_cmd = container_of(cmd, struct isert_cmd, iscsi_cmd); | ||
1135 | ret = isert_handle_text_cmd(isert_conn, isert_cmd, | ||
1136 | rx_desc, (struct iscsi_text *)hdr); | ||
1137 | break; | ||
1060 | default: | 1138 | default: |
1061 | pr_err("Got unknown iSCSI OpCode: 0x%02x\n", opcode); | 1139 | pr_err("Got unknown iSCSI OpCode: 0x%02x\n", opcode); |
1062 | dump_stack(); | 1140 | dump_stack(); |
@@ -1184,14 +1262,12 @@ isert_put_cmd(struct isert_cmd *isert_cmd) | |||
1184 | { | 1262 | { |
1185 | struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; | 1263 | struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; |
1186 | struct isert_conn *isert_conn = isert_cmd->conn; | 1264 | struct isert_conn *isert_conn = isert_cmd->conn; |
1187 | struct iscsi_conn *conn; | 1265 | struct iscsi_conn *conn = isert_conn->conn; |
1188 | 1266 | ||
1189 | pr_debug("Entering isert_put_cmd: %p\n", isert_cmd); | 1267 | pr_debug("Entering isert_put_cmd: %p\n", isert_cmd); |
1190 | 1268 | ||
1191 | switch (cmd->iscsi_opcode) { | 1269 | switch (cmd->iscsi_opcode) { |
1192 | case ISCSI_OP_SCSI_CMD: | 1270 | case ISCSI_OP_SCSI_CMD: |
1193 | conn = isert_conn->conn; | ||
1194 | |||
1195 | spin_lock_bh(&conn->cmd_lock); | 1271 | spin_lock_bh(&conn->cmd_lock); |
1196 | if (!list_empty(&cmd->i_conn_node)) | 1272 | if (!list_empty(&cmd->i_conn_node)) |
1197 | list_del(&cmd->i_conn_node); | 1273 | list_del(&cmd->i_conn_node); |
@@ -1201,16 +1277,19 @@ isert_put_cmd(struct isert_cmd *isert_cmd) | |||
1201 | iscsit_stop_dataout_timer(cmd); | 1277 | iscsit_stop_dataout_timer(cmd); |
1202 | 1278 | ||
1203 | isert_unmap_cmd(isert_cmd, isert_conn); | 1279 | isert_unmap_cmd(isert_cmd, isert_conn); |
1204 | /* | 1280 | transport_generic_free_cmd(&cmd->se_cmd, 0); |
1205 | * Fall-through | 1281 | break; |
1206 | */ | ||
1207 | case ISCSI_OP_SCSI_TMFUNC: | 1282 | case ISCSI_OP_SCSI_TMFUNC: |
1283 | spin_lock_bh(&conn->cmd_lock); | ||
1284 | if (!list_empty(&cmd->i_conn_node)) | ||
1285 | list_del(&cmd->i_conn_node); | ||
1286 | spin_unlock_bh(&conn->cmd_lock); | ||
1287 | |||
1208 | transport_generic_free_cmd(&cmd->se_cmd, 0); | 1288 | transport_generic_free_cmd(&cmd->se_cmd, 0); |
1209 | break; | 1289 | break; |
1210 | case ISCSI_OP_REJECT: | 1290 | case ISCSI_OP_REJECT: |
1211 | case ISCSI_OP_NOOP_OUT: | 1291 | case ISCSI_OP_NOOP_OUT: |
1212 | conn = isert_conn->conn; | 1292 | case ISCSI_OP_TEXT: |
1213 | |||
1214 | spin_lock_bh(&conn->cmd_lock); | 1293 | spin_lock_bh(&conn->cmd_lock); |
1215 | if (!list_empty(&cmd->i_conn_node)) | 1294 | if (!list_empty(&cmd->i_conn_node)) |
1216 | list_del(&cmd->i_conn_node); | 1295 | list_del(&cmd->i_conn_node); |
@@ -1222,6 +1301,9 @@ isert_put_cmd(struct isert_cmd *isert_cmd) | |||
1222 | * associated cmd->se_cmd needs to be released. | 1301 | * associated cmd->se_cmd needs to be released. |
1223 | */ | 1302 | */ |
1224 | if (cmd->se_cmd.se_tfo != NULL) { | 1303 | if (cmd->se_cmd.se_tfo != NULL) { |
1304 | pr_debug("Calling transport_generic_free_cmd from" | ||
1305 | " isert_put_cmd for 0x%02x\n", | ||
1306 | cmd->iscsi_opcode); | ||
1225 | transport_generic_free_cmd(&cmd->se_cmd, 0); | 1307 | transport_generic_free_cmd(&cmd->se_cmd, 0); |
1226 | break; | 1308 | break; |
1227 | } | 1309 | } |
@@ -1249,11 +1331,11 @@ static void | |||
1249 | isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd, | 1331 | isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd, |
1250 | struct ib_device *ib_dev) | 1332 | struct ib_device *ib_dev) |
1251 | { | 1333 | { |
1252 | if (isert_cmd->sense_buf_dma != 0) { | 1334 | if (isert_cmd->pdu_buf_dma != 0) { |
1253 | pr_debug("Calling ib_dma_unmap_single for isert_cmd->sense_buf_dma\n"); | 1335 | pr_debug("Calling ib_dma_unmap_single for isert_cmd->pdu_buf_dma\n"); |
1254 | ib_dma_unmap_single(ib_dev, isert_cmd->sense_buf_dma, | 1336 | ib_dma_unmap_single(ib_dev, isert_cmd->pdu_buf_dma, |
1255 | isert_cmd->sense_buf_len, DMA_TO_DEVICE); | 1337 | isert_cmd->pdu_buf_len, DMA_TO_DEVICE); |
1256 | isert_cmd->sense_buf_dma = 0; | 1338 | isert_cmd->pdu_buf_dma = 0; |
1257 | } | 1339 | } |
1258 | 1340 | ||
1259 | isert_unmap_tx_desc(tx_desc, ib_dev); | 1341 | isert_unmap_tx_desc(tx_desc, ib_dev); |
@@ -1318,8 +1400,8 @@ isert_do_control_comp(struct work_struct *work) | |||
1318 | atomic_dec(&isert_conn->post_send_buf_count); | 1400 | atomic_dec(&isert_conn->post_send_buf_count); |
1319 | 1401 | ||
1320 | cmd->i_state = ISTATE_SENT_STATUS; | 1402 | cmd->i_state = ISTATE_SENT_STATUS; |
1321 | complete(&cmd->reject_comp); | ||
1322 | isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev); | 1403 | isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev); |
1404 | break; | ||
1323 | case ISTATE_SEND_LOGOUTRSP: | 1405 | case ISTATE_SEND_LOGOUTRSP: |
1324 | pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); | 1406 | pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); |
1325 | /* | 1407 | /* |
@@ -1329,6 +1411,11 @@ isert_do_control_comp(struct work_struct *work) | |||
1329 | isert_conn->logout_posted = true; | 1411 | isert_conn->logout_posted = true; |
1330 | iscsit_logout_post_handler(cmd, cmd->conn); | 1412 | iscsit_logout_post_handler(cmd, cmd->conn); |
1331 | break; | 1413 | break; |
1414 | case ISTATE_SEND_TEXTRSP: | ||
1415 | atomic_dec(&isert_conn->post_send_buf_count); | ||
1416 | cmd->i_state = ISTATE_SENT_STATUS; | ||
1417 | isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev); | ||
1418 | break; | ||
1332 | default: | 1419 | default: |
1333 | pr_err("Unknown do_control_comp i_state %d\n", cmd->i_state); | 1420 | pr_err("Unknown do_control_comp i_state %d\n", cmd->i_state); |
1334 | dump_stack(); | 1421 | dump_stack(); |
@@ -1345,7 +1432,9 @@ isert_response_completion(struct iser_tx_desc *tx_desc, | |||
1345 | struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; | 1432 | struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; |
1346 | 1433 | ||
1347 | if (cmd->i_state == ISTATE_SEND_TASKMGTRSP || | 1434 | if (cmd->i_state == ISTATE_SEND_TASKMGTRSP || |
1348 | cmd->i_state == ISTATE_SEND_LOGOUTRSP) { | 1435 | cmd->i_state == ISTATE_SEND_LOGOUTRSP || |
1436 | cmd->i_state == ISTATE_SEND_REJECT || | ||
1437 | cmd->i_state == ISTATE_SEND_TEXTRSP) { | ||
1349 | isert_unmap_tx_desc(tx_desc, ib_dev); | 1438 | isert_unmap_tx_desc(tx_desc, ib_dev); |
1350 | 1439 | ||
1351 | INIT_WORK(&isert_cmd->comp_work, isert_do_control_comp); | 1440 | INIT_WORK(&isert_cmd->comp_work, isert_do_control_comp); |
@@ -1419,7 +1508,11 @@ isert_cq_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn) | |||
1419 | pr_debug("isert_cq_comp_err >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); | 1508 | pr_debug("isert_cq_comp_err >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); |
1420 | pr_debug("Calling wake_up from isert_cq_comp_err\n"); | 1509 | pr_debug("Calling wake_up from isert_cq_comp_err\n"); |
1421 | 1510 | ||
1422 | isert_conn->state = ISER_CONN_TERMINATING; | 1511 | mutex_lock(&isert_conn->conn_mutex); |
1512 | if (isert_conn->state != ISER_CONN_DOWN) | ||
1513 | isert_conn->state = ISER_CONN_TERMINATING; | ||
1514 | mutex_unlock(&isert_conn->conn_mutex); | ||
1515 | |||
1423 | wake_up(&isert_conn->conn_wait_comp_err); | 1516 | wake_up(&isert_conn->conn_wait_comp_err); |
1424 | } | 1517 | } |
1425 | } | 1518 | } |
@@ -1445,6 +1538,7 @@ isert_cq_tx_work(struct work_struct *work) | |||
1445 | } else { | 1538 | } else { |
1446 | pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); | 1539 | pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); |
1447 | pr_debug("TX wc.status: 0x%08x\n", wc.status); | 1540 | pr_debug("TX wc.status: 0x%08x\n", wc.status); |
1541 | pr_debug("TX wc.vendor_err: 0x%08x\n", wc.vendor_err); | ||
1448 | atomic_dec(&isert_conn->post_send_buf_count); | 1542 | atomic_dec(&isert_conn->post_send_buf_count); |
1449 | isert_cq_comp_err(tx_desc, isert_conn); | 1543 | isert_cq_comp_err(tx_desc, isert_conn); |
1450 | } | 1544 | } |
@@ -1484,9 +1578,11 @@ isert_cq_rx_work(struct work_struct *work) | |||
1484 | isert_rx_completion(rx_desc, isert_conn, xfer_len); | 1578 | isert_rx_completion(rx_desc, isert_conn, xfer_len); |
1485 | } else { | 1579 | } else { |
1486 | pr_debug("RX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); | 1580 | pr_debug("RX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); |
1487 | if (wc.status != IB_WC_WR_FLUSH_ERR) | 1581 | if (wc.status != IB_WC_WR_FLUSH_ERR) { |
1488 | pr_debug("RX wc.status: 0x%08x\n", wc.status); | 1582 | pr_debug("RX wc.status: 0x%08x\n", wc.status); |
1489 | 1583 | pr_debug("RX wc.vendor_err: 0x%08x\n", | |
1584 | wc.vendor_err); | ||
1585 | } | ||
1490 | isert_conn->post_recv_buf_count--; | 1586 | isert_conn->post_recv_buf_count--; |
1491 | isert_cq_comp_err(NULL, isert_conn); | 1587 | isert_cq_comp_err(NULL, isert_conn); |
1492 | } | 1588 | } |
@@ -1543,7 +1639,7 @@ isert_put_response(struct iscsi_conn *conn, struct iscsi_cmd *cmd) | |||
1543 | (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) { | 1639 | (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) { |
1544 | struct ib_device *ib_dev = isert_conn->conn_cm_id->device; | 1640 | struct ib_device *ib_dev = isert_conn->conn_cm_id->device; |
1545 | struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1]; | 1641 | struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1]; |
1546 | u32 padding, sense_len; | 1642 | u32 padding, pdu_len; |
1547 | 1643 | ||
1548 | put_unaligned_be16(cmd->se_cmd.scsi_sense_length, | 1644 | put_unaligned_be16(cmd->se_cmd.scsi_sense_length, |
1549 | cmd->sense_buffer); | 1645 | cmd->sense_buffer); |
@@ -1551,15 +1647,15 @@ isert_put_response(struct iscsi_conn *conn, struct iscsi_cmd *cmd) | |||
1551 | 1647 | ||
1552 | padding = -(cmd->se_cmd.scsi_sense_length) & 3; | 1648 | padding = -(cmd->se_cmd.scsi_sense_length) & 3; |
1553 | hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length); | 1649 | hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length); |
1554 | sense_len = cmd->se_cmd.scsi_sense_length + padding; | 1650 | pdu_len = cmd->se_cmd.scsi_sense_length + padding; |
1555 | 1651 | ||
1556 | isert_cmd->sense_buf_dma = ib_dma_map_single(ib_dev, | 1652 | isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev, |
1557 | (void *)cmd->sense_buffer, sense_len, | 1653 | (void *)cmd->sense_buffer, pdu_len, |
1558 | DMA_TO_DEVICE); | 1654 | DMA_TO_DEVICE); |
1559 | 1655 | ||
1560 | isert_cmd->sense_buf_len = sense_len; | 1656 | isert_cmd->pdu_buf_len = pdu_len; |
1561 | tx_dsg->addr = isert_cmd->sense_buf_dma; | 1657 | tx_dsg->addr = isert_cmd->pdu_buf_dma; |
1562 | tx_dsg->length = sense_len; | 1658 | tx_dsg->length = pdu_len; |
1563 | tx_dsg->lkey = isert_conn->conn_mr->lkey; | 1659 | tx_dsg->lkey = isert_conn->conn_mr->lkey; |
1564 | isert_cmd->tx_desc.num_sge = 2; | 1660 | isert_cmd->tx_desc.num_sge = 2; |
1565 | } | 1661 | } |
@@ -1637,11 +1733,25 @@ isert_put_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn) | |||
1637 | struct isert_cmd, iscsi_cmd); | 1733 | struct isert_cmd, iscsi_cmd); |
1638 | struct isert_conn *isert_conn = (struct isert_conn *)conn->context; | 1734 | struct isert_conn *isert_conn = (struct isert_conn *)conn->context; |
1639 | struct ib_send_wr *send_wr = &isert_cmd->tx_desc.send_wr; | 1735 | struct ib_send_wr *send_wr = &isert_cmd->tx_desc.send_wr; |
1736 | struct ib_device *ib_dev = isert_conn->conn_cm_id->device; | ||
1737 | struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1]; | ||
1738 | struct iscsi_reject *hdr = | ||
1739 | (struct iscsi_reject *)&isert_cmd->tx_desc.iscsi_header; | ||
1640 | 1740 | ||
1641 | isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc); | 1741 | isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc); |
1642 | iscsit_build_reject(cmd, conn, (struct iscsi_reject *) | 1742 | iscsit_build_reject(cmd, conn, hdr); |
1643 | &isert_cmd->tx_desc.iscsi_header); | ||
1644 | isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc); | 1743 | isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc); |
1744 | |||
1745 | hton24(hdr->dlength, ISCSI_HDR_LEN); | ||
1746 | isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev, | ||
1747 | (void *)cmd->buf_ptr, ISCSI_HDR_LEN, | ||
1748 | DMA_TO_DEVICE); | ||
1749 | isert_cmd->pdu_buf_len = ISCSI_HDR_LEN; | ||
1750 | tx_dsg->addr = isert_cmd->pdu_buf_dma; | ||
1751 | tx_dsg->length = ISCSI_HDR_LEN; | ||
1752 | tx_dsg->lkey = isert_conn->conn_mr->lkey; | ||
1753 | isert_cmd->tx_desc.num_sge = 2; | ||
1754 | |||
1645 | isert_init_send_wr(isert_cmd, send_wr); | 1755 | isert_init_send_wr(isert_cmd, send_wr); |
1646 | 1756 | ||
1647 | pr_debug("Posting Reject IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n"); | 1757 | pr_debug("Posting Reject IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n"); |
@@ -1650,6 +1760,47 @@ isert_put_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn) | |||
1650 | } | 1760 | } |
1651 | 1761 | ||
1652 | static int | 1762 | static int |
1763 | isert_put_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn) | ||
1764 | { | ||
1765 | struct isert_cmd *isert_cmd = container_of(cmd, | ||
1766 | struct isert_cmd, iscsi_cmd); | ||
1767 | struct isert_conn *isert_conn = (struct isert_conn *)conn->context; | ||
1768 | struct ib_send_wr *send_wr = &isert_cmd->tx_desc.send_wr; | ||
1769 | struct iscsi_text_rsp *hdr = | ||
1770 | (struct iscsi_text_rsp *)&isert_cmd->tx_desc.iscsi_header; | ||
1771 | u32 txt_rsp_len; | ||
1772 | int rc; | ||
1773 | |||
1774 | isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc); | ||
1775 | rc = iscsit_build_text_rsp(cmd, conn, hdr); | ||
1776 | if (rc < 0) | ||
1777 | return rc; | ||
1778 | |||
1779 | txt_rsp_len = rc; | ||
1780 | isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc); | ||
1781 | |||
1782 | if (txt_rsp_len) { | ||
1783 | struct ib_device *ib_dev = isert_conn->conn_cm_id->device; | ||
1784 | struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1]; | ||
1785 | void *txt_rsp_buf = cmd->buf_ptr; | ||
1786 | |||
1787 | isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev, | ||
1788 | txt_rsp_buf, txt_rsp_len, DMA_TO_DEVICE); | ||
1789 | |||
1790 | isert_cmd->pdu_buf_len = txt_rsp_len; | ||
1791 | tx_dsg->addr = isert_cmd->pdu_buf_dma; | ||
1792 | tx_dsg->length = txt_rsp_len; | ||
1793 | tx_dsg->lkey = isert_conn->conn_mr->lkey; | ||
1794 | isert_cmd->tx_desc.num_sge = 2; | ||
1795 | } | ||
1796 | isert_init_send_wr(isert_cmd, send_wr); | ||
1797 | |||
1798 | pr_debug("Posting Text Response IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n"); | ||
1799 | |||
1800 | return isert_post_response(isert_conn, isert_cmd); | ||
1801 | } | ||
1802 | |||
1803 | static int | ||
1653 | isert_build_rdma_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd, | 1804 | isert_build_rdma_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd, |
1654 | struct ib_sge *ib_sge, struct ib_send_wr *send_wr, | 1805 | struct ib_sge *ib_sge, struct ib_send_wr *send_wr, |
1655 | u32 data_left, u32 offset) | 1806 | u32 data_left, u32 offset) |
@@ -1947,6 +2098,9 @@ isert_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) | |||
1947 | case ISTATE_SEND_REJECT: | 2098 | case ISTATE_SEND_REJECT: |
1948 | ret = isert_put_reject(cmd, conn); | 2099 | ret = isert_put_reject(cmd, conn); |
1949 | break; | 2100 | break; |
2101 | case ISTATE_SEND_TEXTRSP: | ||
2102 | ret = isert_put_text_rsp(cmd, conn); | ||
2103 | break; | ||
1950 | case ISTATE_SEND_STATUS: | 2104 | case ISTATE_SEND_STATUS: |
1951 | /* | 2105 | /* |
1952 | * Special case for sending non GOOD SCSI status from TX thread | 2106 | * Special case for sending non GOOD SCSI status from TX thread |
@@ -2175,6 +2329,17 @@ isert_free_np(struct iscsi_np *np) | |||
2175 | kfree(isert_np); | 2329 | kfree(isert_np); |
2176 | } | 2330 | } |
2177 | 2331 | ||
2332 | static int isert_check_state(struct isert_conn *isert_conn, int state) | ||
2333 | { | ||
2334 | int ret; | ||
2335 | |||
2336 | mutex_lock(&isert_conn->conn_mutex); | ||
2337 | ret = (isert_conn->state == state); | ||
2338 | mutex_unlock(&isert_conn->conn_mutex); | ||
2339 | |||
2340 | return ret; | ||
2341 | } | ||
2342 | |||
2178 | static void isert_free_conn(struct iscsi_conn *conn) | 2343 | static void isert_free_conn(struct iscsi_conn *conn) |
2179 | { | 2344 | { |
2180 | struct isert_conn *isert_conn = conn->context; | 2345 | struct isert_conn *isert_conn = conn->context; |
@@ -2184,26 +2349,43 @@ static void isert_free_conn(struct iscsi_conn *conn) | |||
2184 | * Decrement post_send_buf_count for special case when called | 2349 | * Decrement post_send_buf_count for special case when called |
2185 | * from isert_do_control_comp() -> iscsit_logout_post_handler() | 2350 | * from isert_do_control_comp() -> iscsit_logout_post_handler() |
2186 | */ | 2351 | */ |
2352 | mutex_lock(&isert_conn->conn_mutex); | ||
2187 | if (isert_conn->logout_posted) | 2353 | if (isert_conn->logout_posted) |
2188 | atomic_dec(&isert_conn->post_send_buf_count); | 2354 | atomic_dec(&isert_conn->post_send_buf_count); |
2189 | 2355 | ||
2190 | if (isert_conn->conn_cm_id) | 2356 | if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) { |
2357 | pr_debug("Calling rdma_disconnect from isert_free_conn\n"); | ||
2191 | rdma_disconnect(isert_conn->conn_cm_id); | 2358 | rdma_disconnect(isert_conn->conn_cm_id); |
2359 | } | ||
2192 | /* | 2360 | /* |
2193 | * Only wait for conn_wait_comp_err if the isert_conn made it | 2361 | * Only wait for conn_wait_comp_err if the isert_conn made it |
2194 | * into full feature phase.. | 2362 | * into full feature phase.. |
2195 | */ | 2363 | */ |
2196 | if (isert_conn->state > ISER_CONN_INIT) { | 2364 | if (isert_conn->state == ISER_CONN_UP) { |
2197 | pr_debug("isert_free_conn: Before wait_event comp_err %d\n", | 2365 | pr_debug("isert_free_conn: Before wait_event comp_err %d\n", |
2198 | isert_conn->state); | 2366 | isert_conn->state); |
2367 | mutex_unlock(&isert_conn->conn_mutex); | ||
2368 | |||
2199 | wait_event(isert_conn->conn_wait_comp_err, | 2369 | wait_event(isert_conn->conn_wait_comp_err, |
2200 | isert_conn->state == ISER_CONN_TERMINATING); | 2370 | (isert_check_state(isert_conn, ISER_CONN_TERMINATING))); |
2201 | pr_debug("isert_free_conn: After wait_event #1 >>>>>>>>>>>>\n"); | 2371 | |
2372 | wait_event(isert_conn->conn_wait, | ||
2373 | (isert_check_state(isert_conn, ISER_CONN_DOWN))); | ||
2374 | |||
2375 | isert_put_conn(isert_conn); | ||
2376 | return; | ||
2377 | } | ||
2378 | if (isert_conn->state == ISER_CONN_INIT) { | ||
2379 | mutex_unlock(&isert_conn->conn_mutex); | ||
2380 | isert_put_conn(isert_conn); | ||
2381 | return; | ||
2202 | } | 2382 | } |
2383 | pr_debug("isert_free_conn: wait_event conn_wait %d\n", | ||
2384 | isert_conn->state); | ||
2385 | mutex_unlock(&isert_conn->conn_mutex); | ||
2203 | 2386 | ||
2204 | pr_debug("isert_free_conn: wait_event conn_wait %d\n", isert_conn->state); | 2387 | wait_event(isert_conn->conn_wait, |
2205 | wait_event(isert_conn->conn_wait, isert_conn->state == ISER_CONN_DOWN); | 2388 | (isert_check_state(isert_conn, ISER_CONN_DOWN))); |
2206 | pr_debug("isert_free_conn: After wait_event #2 >>>>>>>>>>>>>>>>>>>>\n"); | ||
2207 | 2389 | ||
2208 | isert_put_conn(isert_conn); | 2390 | isert_put_conn(isert_conn); |
2209 | } | 2391 | } |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index b104f4c2cd38..191117b5b508 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h | |||
@@ -61,8 +61,8 @@ struct isert_cmd { | |||
61 | uint32_t write_stag; | 61 | uint32_t write_stag; |
62 | uint64_t read_va; | 62 | uint64_t read_va; |
63 | uint64_t write_va; | 63 | uint64_t write_va; |
64 | u64 sense_buf_dma; | 64 | u64 pdu_buf_dma; |
65 | u32 sense_buf_len; | 65 | u32 pdu_buf_len; |
66 | u32 read_va_off; | 66 | u32 read_va_off; |
67 | u32 write_va_off; | 67 | u32 write_va_off; |
68 | u32 rdma_wr_num; | 68 | u32 rdma_wr_num; |
@@ -102,6 +102,7 @@ struct isert_conn { | |||
102 | struct ib_qp *conn_qp; | 102 | struct ib_qp *conn_qp; |
103 | struct isert_device *conn_device; | 103 | struct isert_device *conn_device; |
104 | struct work_struct conn_logout_work; | 104 | struct work_struct conn_logout_work; |
105 | struct mutex conn_mutex; | ||
105 | wait_queue_head_t conn_wait; | 106 | wait_queue_head_t conn_wait; |
106 | wait_queue_head_t conn_wait_comp_err; | 107 | wait_queue_head_t conn_wait_comp_err; |
107 | struct kref conn_kref; | 108 | struct kref conn_kref; |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 3f3f0416fbdd..653ac6bfc57a 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -3011,7 +3011,7 @@ static u8 tcm_to_srp_tsk_mgmt_status(const int tcm_mgmt_status) | |||
3011 | * Callback function called by the TCM core. Must not block since it can be | 3011 | * Callback function called by the TCM core. Must not block since it can be |
3012 | * invoked on the context of the IB completion handler. | 3012 | * invoked on the context of the IB completion handler. |
3013 | */ | 3013 | */ |
3014 | static int srpt_queue_response(struct se_cmd *cmd) | 3014 | static void srpt_queue_response(struct se_cmd *cmd) |
3015 | { | 3015 | { |
3016 | struct srpt_rdma_ch *ch; | 3016 | struct srpt_rdma_ch *ch; |
3017 | struct srpt_send_ioctx *ioctx; | 3017 | struct srpt_send_ioctx *ioctx; |
@@ -3022,8 +3022,6 @@ static int srpt_queue_response(struct se_cmd *cmd) | |||
3022 | int resp_len; | 3022 | int resp_len; |
3023 | u8 srp_tm_status; | 3023 | u8 srp_tm_status; |
3024 | 3024 | ||
3025 | ret = 0; | ||
3026 | |||
3027 | ioctx = container_of(cmd, struct srpt_send_ioctx, cmd); | 3025 | ioctx = container_of(cmd, struct srpt_send_ioctx, cmd); |
3028 | ch = ioctx->ch; | 3026 | ch = ioctx->ch; |
3029 | BUG_ON(!ch); | 3027 | BUG_ON(!ch); |
@@ -3049,7 +3047,7 @@ static int srpt_queue_response(struct se_cmd *cmd) | |||
3049 | || WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) { | 3047 | || WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) { |
3050 | atomic_inc(&ch->req_lim_delta); | 3048 | atomic_inc(&ch->req_lim_delta); |
3051 | srpt_abort_cmd(ioctx); | 3049 | srpt_abort_cmd(ioctx); |
3052 | goto out; | 3050 | return; |
3053 | } | 3051 | } |
3054 | 3052 | ||
3055 | dir = ioctx->cmd.data_direction; | 3053 | dir = ioctx->cmd.data_direction; |
@@ -3061,7 +3059,7 @@ static int srpt_queue_response(struct se_cmd *cmd) | |||
3061 | if (ret) { | 3059 | if (ret) { |
3062 | printk(KERN_ERR "xfer_data failed for tag %llu\n", | 3060 | printk(KERN_ERR "xfer_data failed for tag %llu\n", |
3063 | ioctx->tag); | 3061 | ioctx->tag); |
3064 | goto out; | 3062 | return; |
3065 | } | 3063 | } |
3066 | } | 3064 | } |
3067 | 3065 | ||
@@ -3082,9 +3080,17 @@ static int srpt_queue_response(struct se_cmd *cmd) | |||
3082 | srpt_set_cmd_state(ioctx, SRPT_STATE_DONE); | 3080 | srpt_set_cmd_state(ioctx, SRPT_STATE_DONE); |
3083 | target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd); | 3081 | target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd); |
3084 | } | 3082 | } |
3083 | } | ||
3085 | 3084 | ||
3086 | out: | 3085 | static int srpt_queue_data_in(struct se_cmd *cmd) |
3087 | return ret; | 3086 | { |
3087 | srpt_queue_response(cmd); | ||
3088 | return 0; | ||
3089 | } | ||
3090 | |||
3091 | static void srpt_queue_tm_rsp(struct se_cmd *cmd) | ||
3092 | { | ||
3093 | srpt_queue_response(cmd); | ||
3088 | } | 3094 | } |
3089 | 3095 | ||
3090 | static int srpt_queue_status(struct se_cmd *cmd) | 3096 | static int srpt_queue_status(struct se_cmd *cmd) |
@@ -3097,7 +3103,8 @@ static int srpt_queue_status(struct se_cmd *cmd) | |||
3097 | (SCF_TRANSPORT_TASK_SENSE | SCF_EMULATED_TASK_SENSE)) | 3103 | (SCF_TRANSPORT_TASK_SENSE | SCF_EMULATED_TASK_SENSE)) |
3098 | WARN_ON(cmd->scsi_status != SAM_STAT_CHECK_CONDITION); | 3104 | WARN_ON(cmd->scsi_status != SAM_STAT_CHECK_CONDITION); |
3099 | ioctx->queue_status_only = true; | 3105 | ioctx->queue_status_only = true; |
3100 | return srpt_queue_response(cmd); | 3106 | srpt_queue_response(cmd); |
3107 | return 0; | ||
3101 | } | 3108 | } |
3102 | 3109 | ||
3103 | static void srpt_refresh_port_work(struct work_struct *work) | 3110 | static void srpt_refresh_port_work(struct work_struct *work) |
@@ -3930,9 +3937,9 @@ static struct target_core_fabric_ops srpt_template = { | |||
3930 | .set_default_node_attributes = srpt_set_default_node_attrs, | 3937 | .set_default_node_attributes = srpt_set_default_node_attrs, |
3931 | .get_task_tag = srpt_get_task_tag, | 3938 | .get_task_tag = srpt_get_task_tag, |
3932 | .get_cmd_state = srpt_get_tcm_cmd_state, | 3939 | .get_cmd_state = srpt_get_tcm_cmd_state, |
3933 | .queue_data_in = srpt_queue_response, | 3940 | .queue_data_in = srpt_queue_data_in, |
3934 | .queue_status = srpt_queue_status, | 3941 | .queue_status = srpt_queue_status, |
3935 | .queue_tm_rsp = srpt_queue_response, | 3942 | .queue_tm_rsp = srpt_queue_tm_rsp, |
3936 | /* | 3943 | /* |
3937 | * Setup function pointers for generic logic in | 3944 | * Setup function pointers for generic logic in |
3938 | * target_core_fabric_configfs.c | 3945 | * target_core_fabric_configfs.c |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index fcdc22306cab..83a8f7a9ec76 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -544,102 +544,6 @@ out_free_id_list: | |||
544 | return res; | 544 | return res; |
545 | } | 545 | } |
546 | 546 | ||
547 | static bool qlt_check_fcport_exist(struct scsi_qla_host *vha, | ||
548 | struct qla_tgt_sess *sess) | ||
549 | { | ||
550 | struct qla_hw_data *ha = vha->hw; | ||
551 | struct qla_port_24xx_data *pmap24; | ||
552 | bool res, found = false; | ||
553 | int rc, i; | ||
554 | uint16_t loop_id = 0xFFFF; /* to eliminate compiler's warning */ | ||
555 | uint16_t entries; | ||
556 | void *pmap; | ||
557 | int pmap_len; | ||
558 | fc_port_t *fcport; | ||
559 | int global_resets; | ||
560 | unsigned long flags; | ||
561 | |||
562 | retry: | ||
563 | global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); | ||
564 | |||
565 | rc = qla2x00_get_node_name_list(vha, &pmap, &pmap_len); | ||
566 | if (rc != QLA_SUCCESS) { | ||
567 | res = false; | ||
568 | goto out; | ||
569 | } | ||
570 | |||
571 | pmap24 = pmap; | ||
572 | entries = pmap_len/sizeof(*pmap24); | ||
573 | |||
574 | for (i = 0; i < entries; ++i) { | ||
575 | if (!memcmp(sess->port_name, pmap24[i].port_name, WWN_SIZE)) { | ||
576 | loop_id = le16_to_cpu(pmap24[i].loop_id); | ||
577 | found = true; | ||
578 | break; | ||
579 | } | ||
580 | } | ||
581 | |||
582 | kfree(pmap); | ||
583 | |||
584 | if (!found) { | ||
585 | res = false; | ||
586 | goto out; | ||
587 | } | ||
588 | |||
589 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf046, | ||
590 | "qlt_check_fcport_exist(): loop_id %d", loop_id); | ||
591 | |||
592 | fcport = kzalloc(sizeof(*fcport), GFP_KERNEL); | ||
593 | if (fcport == NULL) { | ||
594 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf047, | ||
595 | "qla_target(%d): Allocation of tmp FC port failed", | ||
596 | vha->vp_idx); | ||
597 | res = false; | ||
598 | goto out; | ||
599 | } | ||
600 | |||
601 | fcport->loop_id = loop_id; | ||
602 | |||
603 | rc = qla2x00_get_port_database(vha, fcport, 0); | ||
604 | if (rc != QLA_SUCCESS) { | ||
605 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf048, | ||
606 | "qla_target(%d): Failed to retrieve fcport " | ||
607 | "information -- get_port_database() returned %x " | ||
608 | "(loop_id=0x%04x)", vha->vp_idx, rc, loop_id); | ||
609 | res = false; | ||
610 | goto out_free_fcport; | ||
611 | } | ||
612 | |||
613 | if (global_resets != | ||
614 | atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)) { | ||
615 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf002, | ||
616 | "qla_target(%d): global reset during session discovery" | ||
617 | " (counter was %d, new %d), retrying", | ||
618 | vha->vp_idx, global_resets, | ||
619 | atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)); | ||
620 | goto retry; | ||
621 | } | ||
622 | |||
623 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf003, | ||
624 | "Updating sess %p s_id %x:%x:%x, loop_id %d) to d_id %x:%x:%x, " | ||
625 | "loop_id %d", sess, sess->s_id.b.domain, sess->s_id.b.al_pa, | ||
626 | sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, | ||
627 | fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); | ||
628 | |||
629 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
630 | ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id, | ||
631 | (fcport->flags & FCF_CONF_COMP_SUPPORTED)); | ||
632 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
633 | |||
634 | res = true; | ||
635 | |||
636 | out_free_fcport: | ||
637 | kfree(fcport); | ||
638 | |||
639 | out: | ||
640 | return res; | ||
641 | } | ||
642 | |||
643 | /* ha->hardware_lock supposed to be held on entry */ | 547 | /* ha->hardware_lock supposed to be held on entry */ |
644 | static void qlt_undelete_sess(struct qla_tgt_sess *sess) | 548 | static void qlt_undelete_sess(struct qla_tgt_sess *sess) |
645 | { | 549 | { |
@@ -663,43 +567,13 @@ static void qlt_del_sess_work_fn(struct delayed_work *work) | |||
663 | sess = list_entry(tgt->del_sess_list.next, typeof(*sess), | 567 | sess = list_entry(tgt->del_sess_list.next, typeof(*sess), |
664 | del_list_entry); | 568 | del_list_entry); |
665 | if (time_after_eq(jiffies, sess->expires)) { | 569 | if (time_after_eq(jiffies, sess->expires)) { |
666 | bool cancel; | ||
667 | |||
668 | qlt_undelete_sess(sess); | 570 | qlt_undelete_sess(sess); |
669 | 571 | ||
670 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 572 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004, |
671 | cancel = qlt_check_fcport_exist(vha, sess); | 573 | "Timeout: sess %p about to be deleted\n", |
672 | 574 | sess); | |
673 | if (cancel) { | 575 | ha->tgt.tgt_ops->shutdown_sess(sess); |
674 | if (sess->deleted) { | 576 | ha->tgt.tgt_ops->put_sess(sess); |
675 | /* | ||
676 | * sess was again deleted while we were | ||
677 | * discovering it | ||
678 | */ | ||
679 | spin_lock_irqsave(&ha->hardware_lock, | ||
680 | flags); | ||
681 | continue; | ||
682 | } | ||
683 | |||
684 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf049, | ||
685 | "qla_target(%d): cancel deletion of " | ||
686 | "session for port %02x:%02x:%02x:%02x:%02x:" | ||
687 | "%02x:%02x:%02x (loop ID %d), because " | ||
688 | " it isn't deleted by firmware", | ||
689 | vha->vp_idx, sess->port_name[0], | ||
690 | sess->port_name[1], sess->port_name[2], | ||
691 | sess->port_name[3], sess->port_name[4], | ||
692 | sess->port_name[5], sess->port_name[6], | ||
693 | sess->port_name[7], sess->loop_id); | ||
694 | } else { | ||
695 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004, | ||
696 | "Timeout: sess %p about to be deleted\n", | ||
697 | sess); | ||
698 | ha->tgt.tgt_ops->shutdown_sess(sess); | ||
699 | ha->tgt.tgt_ops->put_sess(sess); | ||
700 | } | ||
701 | |||
702 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
703 | } else { | 577 | } else { |
704 | schedule_delayed_work(&tgt->sess_del_work, | 578 | schedule_delayed_work(&tgt->sess_del_work, |
705 | jiffies - sess->expires); | 579 | jiffies - sess->expires); |
@@ -884,9 +758,8 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
884 | sess->loop_id); | 758 | sess->loop_id); |
885 | sess->local = 0; | 759 | sess->local = 0; |
886 | } | 760 | } |
887 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
888 | |||
889 | ha->tgt.tgt_ops->put_sess(sess); | 761 | ha->tgt.tgt_ops->put_sess(sess); |
762 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
890 | } | 763 | } |
891 | 764 | ||
892 | void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport) | 765 | void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport) |
@@ -2706,7 +2579,9 @@ static void qlt_do_work(struct work_struct *work) | |||
2706 | /* | 2579 | /* |
2707 | * Drop extra session reference from qla_tgt_handle_cmd_for_atio*( | 2580 | * Drop extra session reference from qla_tgt_handle_cmd_for_atio*( |
2708 | */ | 2581 | */ |
2582 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
2709 | ha->tgt.tgt_ops->put_sess(sess); | 2583 | ha->tgt.tgt_ops->put_sess(sess); |
2584 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
2710 | return; | 2585 | return; |
2711 | 2586 | ||
2712 | out_term: | 2587 | out_term: |
@@ -2718,9 +2593,9 @@ out_term: | |||
2718 | spin_lock_irqsave(&ha->hardware_lock, flags); | 2593 | spin_lock_irqsave(&ha->hardware_lock, flags); |
2719 | qlt_send_term_exchange(vha, NULL, &cmd->atio, 1); | 2594 | qlt_send_term_exchange(vha, NULL, &cmd->atio, 1); |
2720 | kmem_cache_free(qla_tgt_cmd_cachep, cmd); | 2595 | kmem_cache_free(qla_tgt_cmd_cachep, cmd); |
2721 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
2722 | if (sess) | 2596 | if (sess) |
2723 | ha->tgt.tgt_ops->put_sess(sess); | 2597 | ha->tgt.tgt_ops->put_sess(sess); |
2598 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
2724 | } | 2599 | } |
2725 | 2600 | ||
2726 | /* ha->hardware_lock supposed to be held on entry */ | 2601 | /* ha->hardware_lock supposed to be held on entry */ |
@@ -4169,16 +4044,16 @@ static void qlt_abort_work(struct qla_tgt *tgt, | |||
4169 | rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess); | 4044 | rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess); |
4170 | if (rc != 0) | 4045 | if (rc != 0) |
4171 | goto out_term; | 4046 | goto out_term; |
4172 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4173 | 4047 | ||
4174 | ha->tgt.tgt_ops->put_sess(sess); | 4048 | ha->tgt.tgt_ops->put_sess(sess); |
4049 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4175 | return; | 4050 | return; |
4176 | 4051 | ||
4177 | out_term: | 4052 | out_term: |
4178 | qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false); | 4053 | qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false); |
4179 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4180 | if (sess) | 4054 | if (sess) |
4181 | ha->tgt.tgt_ops->put_sess(sess); | 4055 | ha->tgt.tgt_ops->put_sess(sess); |
4056 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4182 | } | 4057 | } |
4183 | 4058 | ||
4184 | static void qlt_tmr_work(struct qla_tgt *tgt, | 4059 | static void qlt_tmr_work(struct qla_tgt *tgt, |
@@ -4226,16 +4101,16 @@ static void qlt_tmr_work(struct qla_tgt *tgt, | |||
4226 | rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); | 4101 | rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); |
4227 | if (rc != 0) | 4102 | if (rc != 0) |
4228 | goto out_term; | 4103 | goto out_term; |
4229 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4230 | 4104 | ||
4231 | ha->tgt.tgt_ops->put_sess(sess); | 4105 | ha->tgt.tgt_ops->put_sess(sess); |
4106 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4232 | return; | 4107 | return; |
4233 | 4108 | ||
4234 | out_term: | 4109 | out_term: |
4235 | qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1); | 4110 | qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1); |
4236 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4237 | if (sess) | 4111 | if (sess) |
4238 | ha->tgt.tgt_ops->put_sess(sess); | 4112 | ha->tgt.tgt_ops->put_sess(sess); |
4113 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4239 | } | 4114 | } |
4240 | 4115 | ||
4241 | static void qlt_sess_work_fn(struct work_struct *work) | 4116 | static void qlt_sess_work_fn(struct work_struct *work) |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 66b0b26a1381..a318092e033f 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -703,7 +703,7 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) | |||
703 | return qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status); | 703 | return qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status); |
704 | } | 704 | } |
705 | 705 | ||
706 | static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) | 706 | static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) |
707 | { | 707 | { |
708 | struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; | 708 | struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; |
709 | struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd, | 709 | struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd, |
@@ -735,8 +735,6 @@ static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) | |||
735 | * CTIO response packet. | 735 | * CTIO response packet. |
736 | */ | 736 | */ |
737 | qlt_xmit_tm_rsp(mcmd); | 737 | qlt_xmit_tm_rsp(mcmd); |
738 | |||
739 | return 0; | ||
740 | } | 738 | } |
741 | 739 | ||
742 | /* Local pointer to allocated TCM configfs fabric module */ | 740 | /* Local pointer to allocated TCM configfs fabric module */ |
@@ -799,12 +797,14 @@ static void tcm_qla2xxx_put_session(struct se_session *se_sess) | |||
799 | 797 | ||
800 | static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess) | 798 | static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess) |
801 | { | 799 | { |
802 | tcm_qla2xxx_put_session(sess->se_sess); | 800 | assert_spin_locked(&sess->vha->hw->hardware_lock); |
801 | kref_put(&sess->se_sess->sess_kref, tcm_qla2xxx_release_session); | ||
803 | } | 802 | } |
804 | 803 | ||
805 | static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess) | 804 | static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess) |
806 | { | 805 | { |
807 | tcm_qla2xxx_shutdown_session(sess->se_sess); | 806 | assert_spin_locked(&sess->vha->hw->hardware_lock); |
807 | target_sess_cmd_list_set_waiting(sess->se_sess); | ||
808 | } | 808 | } |
809 | 809 | ||
810 | static struct se_node_acl *tcm_qla2xxx_make_nodeacl( | 810 | static struct se_node_acl *tcm_qla2xxx_make_nodeacl( |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index d7705e5824fb..f73da43cdf9e 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -628,25 +628,18 @@ static void __exit iscsi_target_cleanup_module(void) | |||
628 | } | 628 | } |
629 | 629 | ||
630 | static int iscsit_add_reject( | 630 | static int iscsit_add_reject( |
631 | struct iscsi_conn *conn, | ||
631 | u8 reason, | 632 | u8 reason, |
632 | int fail_conn, | 633 | unsigned char *buf) |
633 | unsigned char *buf, | ||
634 | struct iscsi_conn *conn) | ||
635 | { | 634 | { |
636 | struct iscsi_cmd *cmd; | 635 | struct iscsi_cmd *cmd; |
637 | struct iscsi_reject *hdr; | ||
638 | int ret; | ||
639 | 636 | ||
640 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 637 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
641 | if (!cmd) | 638 | if (!cmd) |
642 | return -1; | 639 | return -1; |
643 | 640 | ||
644 | cmd->iscsi_opcode = ISCSI_OP_REJECT; | 641 | cmd->iscsi_opcode = ISCSI_OP_REJECT; |
645 | if (fail_conn) | 642 | cmd->reject_reason = reason; |
646 | cmd->cmd_flags |= ICF_REJECT_FAIL_CONN; | ||
647 | |||
648 | hdr = (struct iscsi_reject *) cmd->pdu; | ||
649 | hdr->reason = reason; | ||
650 | 643 | ||
651 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); | 644 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
652 | if (!cmd->buf_ptr) { | 645 | if (!cmd->buf_ptr) { |
@@ -662,23 +655,16 @@ static int iscsit_add_reject( | |||
662 | cmd->i_state = ISTATE_SEND_REJECT; | 655 | cmd->i_state = ISTATE_SEND_REJECT; |
663 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); | 656 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); |
664 | 657 | ||
665 | ret = wait_for_completion_interruptible(&cmd->reject_comp); | 658 | return -1; |
666 | if (ret != 0) | ||
667 | return -1; | ||
668 | |||
669 | return (!fail_conn) ? 0 : -1; | ||
670 | } | 659 | } |
671 | 660 | ||
672 | int iscsit_add_reject_from_cmd( | 661 | static int iscsit_add_reject_from_cmd( |
662 | struct iscsi_cmd *cmd, | ||
673 | u8 reason, | 663 | u8 reason, |
674 | int fail_conn, | 664 | bool add_to_conn, |
675 | int add_to_conn, | 665 | unsigned char *buf) |
676 | unsigned char *buf, | ||
677 | struct iscsi_cmd *cmd) | ||
678 | { | 666 | { |
679 | struct iscsi_conn *conn; | 667 | struct iscsi_conn *conn; |
680 | struct iscsi_reject *hdr; | ||
681 | int ret; | ||
682 | 668 | ||
683 | if (!cmd->conn) { | 669 | if (!cmd->conn) { |
684 | pr_err("cmd->conn is NULL for ITT: 0x%08x\n", | 670 | pr_err("cmd->conn is NULL for ITT: 0x%08x\n", |
@@ -688,11 +674,7 @@ int iscsit_add_reject_from_cmd( | |||
688 | conn = cmd->conn; | 674 | conn = cmd->conn; |
689 | 675 | ||
690 | cmd->iscsi_opcode = ISCSI_OP_REJECT; | 676 | cmd->iscsi_opcode = ISCSI_OP_REJECT; |
691 | if (fail_conn) | 677 | cmd->reject_reason = reason; |
692 | cmd->cmd_flags |= ICF_REJECT_FAIL_CONN; | ||
693 | |||
694 | hdr = (struct iscsi_reject *) cmd->pdu; | ||
695 | hdr->reason = reason; | ||
696 | 678 | ||
697 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); | 679 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
698 | if (!cmd->buf_ptr) { | 680 | if (!cmd->buf_ptr) { |
@@ -709,8 +691,6 @@ int iscsit_add_reject_from_cmd( | |||
709 | 691 | ||
710 | cmd->i_state = ISTATE_SEND_REJECT; | 692 | cmd->i_state = ISTATE_SEND_REJECT; |
711 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); | 693 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); |
712 | |||
713 | ret = wait_for_completion_interruptible(&cmd->reject_comp); | ||
714 | /* | 694 | /* |
715 | * Perform the kref_put now if se_cmd has already been setup by | 695 | * Perform the kref_put now if se_cmd has already been setup by |
716 | * scsit_setup_scsi_cmd() | 696 | * scsit_setup_scsi_cmd() |
@@ -719,12 +699,19 @@ int iscsit_add_reject_from_cmd( | |||
719 | pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n"); | 699 | pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n"); |
720 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | 700 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); |
721 | } | 701 | } |
722 | if (ret != 0) | 702 | return -1; |
723 | return -1; | 703 | } |
724 | 704 | ||
725 | return (!fail_conn) ? 0 : -1; | 705 | static int iscsit_add_reject_cmd(struct iscsi_cmd *cmd, u8 reason, |
706 | unsigned char *buf) | ||
707 | { | ||
708 | return iscsit_add_reject_from_cmd(cmd, reason, true, buf); | ||
709 | } | ||
710 | |||
711 | int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8 reason, unsigned char *buf) | ||
712 | { | ||
713 | return iscsit_add_reject_from_cmd(cmd, reason, false, buf); | ||
726 | } | 714 | } |
727 | EXPORT_SYMBOL(iscsit_add_reject_from_cmd); | ||
728 | 715 | ||
729 | /* | 716 | /* |
730 | * Map some portion of the allocated scatterlist to an iovec, suitable for | 717 | * Map some portion of the allocated scatterlist to an iovec, suitable for |
@@ -844,8 +831,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
844 | !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) { | 831 | !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) { |
845 | pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL" | 832 | pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL" |
846 | " not set. Bad iSCSI Initiator.\n"); | 833 | " not set. Bad iSCSI Initiator.\n"); |
847 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 834 | return iscsit_add_reject_cmd(cmd, |
848 | 1, 1, buf, cmd); | 835 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
849 | } | 836 | } |
850 | 837 | ||
851 | if (((hdr->flags & ISCSI_FLAG_CMD_READ) || | 838 | if (((hdr->flags & ISCSI_FLAG_CMD_READ) || |
@@ -865,8 +852,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
865 | pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE" | 852 | pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE" |
866 | " set when Expected Data Transfer Length is 0 for" | 853 | " set when Expected Data Transfer Length is 0 for" |
867 | " CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]); | 854 | " CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]); |
868 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 855 | return iscsit_add_reject_cmd(cmd, |
869 | 1, 1, buf, cmd); | 856 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
870 | } | 857 | } |
871 | done: | 858 | done: |
872 | 859 | ||
@@ -875,62 +862,62 @@ done: | |||
875 | pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE" | 862 | pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE" |
876 | " MUST be set if Expected Data Transfer Length is not 0." | 863 | " MUST be set if Expected Data Transfer Length is not 0." |
877 | " Bad iSCSI Initiator\n"); | 864 | " Bad iSCSI Initiator\n"); |
878 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 865 | return iscsit_add_reject_cmd(cmd, |
879 | 1, 1, buf, cmd); | 866 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
880 | } | 867 | } |
881 | 868 | ||
882 | if ((hdr->flags & ISCSI_FLAG_CMD_READ) && | 869 | if ((hdr->flags & ISCSI_FLAG_CMD_READ) && |
883 | (hdr->flags & ISCSI_FLAG_CMD_WRITE)) { | 870 | (hdr->flags & ISCSI_FLAG_CMD_WRITE)) { |
884 | pr_err("Bidirectional operations not supported!\n"); | 871 | pr_err("Bidirectional operations not supported!\n"); |
885 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 872 | return iscsit_add_reject_cmd(cmd, |
886 | 1, 1, buf, cmd); | 873 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
887 | } | 874 | } |
888 | 875 | ||
889 | if (hdr->opcode & ISCSI_OP_IMMEDIATE) { | 876 | if (hdr->opcode & ISCSI_OP_IMMEDIATE) { |
890 | pr_err("Illegally set Immediate Bit in iSCSI Initiator" | 877 | pr_err("Illegally set Immediate Bit in iSCSI Initiator" |
891 | " Scsi Command PDU.\n"); | 878 | " Scsi Command PDU.\n"); |
892 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 879 | return iscsit_add_reject_cmd(cmd, |
893 | 1, 1, buf, cmd); | 880 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
894 | } | 881 | } |
895 | 882 | ||
896 | if (payload_length && !conn->sess->sess_ops->ImmediateData) { | 883 | if (payload_length && !conn->sess->sess_ops->ImmediateData) { |
897 | pr_err("ImmediateData=No but DataSegmentLength=%u," | 884 | pr_err("ImmediateData=No but DataSegmentLength=%u," |
898 | " protocol error.\n", payload_length); | 885 | " protocol error.\n", payload_length); |
899 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 886 | return iscsit_add_reject_cmd(cmd, |
900 | 1, 1, buf, cmd); | 887 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
901 | } | 888 | } |
902 | 889 | ||
903 | if ((be32_to_cpu(hdr->data_length )== payload_length) && | 890 | if ((be32_to_cpu(hdr->data_length) == payload_length) && |
904 | (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) { | 891 | (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) { |
905 | pr_err("Expected Data Transfer Length and Length of" | 892 | pr_err("Expected Data Transfer Length and Length of" |
906 | " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL" | 893 | " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL" |
907 | " bit is not set protocol error\n"); | 894 | " bit is not set protocol error\n"); |
908 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 895 | return iscsit_add_reject_cmd(cmd, |
909 | 1, 1, buf, cmd); | 896 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
910 | } | 897 | } |
911 | 898 | ||
912 | if (payload_length > be32_to_cpu(hdr->data_length)) { | 899 | if (payload_length > be32_to_cpu(hdr->data_length)) { |
913 | pr_err("DataSegmentLength: %u is greater than" | 900 | pr_err("DataSegmentLength: %u is greater than" |
914 | " EDTL: %u, protocol error.\n", payload_length, | 901 | " EDTL: %u, protocol error.\n", payload_length, |
915 | hdr->data_length); | 902 | hdr->data_length); |
916 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 903 | return iscsit_add_reject_cmd(cmd, |
917 | 1, 1, buf, cmd); | 904 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
918 | } | 905 | } |
919 | 906 | ||
920 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { | 907 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { |
921 | pr_err("DataSegmentLength: %u is greater than" | 908 | pr_err("DataSegmentLength: %u is greater than" |
922 | " MaxXmitDataSegmentLength: %u, protocol error.\n", | 909 | " MaxXmitDataSegmentLength: %u, protocol error.\n", |
923 | payload_length, conn->conn_ops->MaxXmitDataSegmentLength); | 910 | payload_length, conn->conn_ops->MaxXmitDataSegmentLength); |
924 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 911 | return iscsit_add_reject_cmd(cmd, |
925 | 1, 1, buf, cmd); | 912 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
926 | } | 913 | } |
927 | 914 | ||
928 | if (payload_length > conn->sess->sess_ops->FirstBurstLength) { | 915 | if (payload_length > conn->sess->sess_ops->FirstBurstLength) { |
929 | pr_err("DataSegmentLength: %u is greater than" | 916 | pr_err("DataSegmentLength: %u is greater than" |
930 | " FirstBurstLength: %u, protocol error.\n", | 917 | " FirstBurstLength: %u, protocol error.\n", |
931 | payload_length, conn->sess->sess_ops->FirstBurstLength); | 918 | payload_length, conn->sess->sess_ops->FirstBurstLength); |
932 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 919 | return iscsit_add_reject_cmd(cmd, |
933 | 1, 1, buf, cmd); | 920 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
934 | } | 921 | } |
935 | 922 | ||
936 | data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : | 923 | data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : |
@@ -985,9 +972,8 @@ done: | |||
985 | 972 | ||
986 | dr = iscsit_allocate_datain_req(); | 973 | dr = iscsit_allocate_datain_req(); |
987 | if (!dr) | 974 | if (!dr) |
988 | return iscsit_add_reject_from_cmd( | 975 | return iscsit_add_reject_cmd(cmd, |
989 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 976 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
990 | 1, 1, buf, cmd); | ||
991 | 977 | ||
992 | iscsit_attach_datain_req(cmd, dr); | 978 | iscsit_attach_datain_req(cmd, dr); |
993 | } | 979 | } |
@@ -1015,18 +1001,16 @@ done: | |||
1015 | cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); | 1001 | cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); |
1016 | if (cmd->sense_reason) { | 1002 | if (cmd->sense_reason) { |
1017 | if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) { | 1003 | if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) { |
1018 | return iscsit_add_reject_from_cmd( | 1004 | return iscsit_add_reject_cmd(cmd, |
1019 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1005 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
1020 | 1, 1, buf, cmd); | ||
1021 | } | 1006 | } |
1022 | 1007 | ||
1023 | goto attach_cmd; | 1008 | goto attach_cmd; |
1024 | } | 1009 | } |
1025 | 1010 | ||
1026 | if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) { | 1011 | if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) { |
1027 | return iscsit_add_reject_from_cmd( | 1012 | return iscsit_add_reject_cmd(cmd, |
1028 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1013 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
1029 | 1, 1, buf, cmd); | ||
1030 | } | 1014 | } |
1031 | 1015 | ||
1032 | attach_cmd: | 1016 | attach_cmd: |
@@ -1068,17 +1052,13 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1068 | * be acknowledged. (See below) | 1052 | * be acknowledged. (See below) |
1069 | */ | 1053 | */ |
1070 | if (!cmd->immediate_data) { | 1054 | if (!cmd->immediate_data) { |
1071 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); | 1055 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, |
1072 | if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) { | 1056 | (unsigned char *)hdr, hdr->cmdsn); |
1073 | if (!cmd->sense_reason) | 1057 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) |
1074 | return 0; | 1058 | return -1; |
1075 | 1059 | else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) { | |
1076 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | 1060 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); |
1077 | return 0; | 1061 | return 0; |
1078 | } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) { | ||
1079 | return iscsit_add_reject_from_cmd( | ||
1080 | ISCSI_REASON_PROTOCOL_ERROR, | ||
1081 | 1, 0, (unsigned char *)hdr, cmd); | ||
1082 | } | 1062 | } |
1083 | } | 1063 | } |
1084 | 1064 | ||
@@ -1103,6 +1083,9 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1103 | * iscsit_check_received_cmdsn() in iscsit_get_immediate_data() below. | 1083 | * iscsit_check_received_cmdsn() in iscsit_get_immediate_data() below. |
1104 | */ | 1084 | */ |
1105 | if (cmd->sense_reason) { | 1085 | if (cmd->sense_reason) { |
1086 | if (cmd->reject_reason) | ||
1087 | return 0; | ||
1088 | |||
1106 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | 1089 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); |
1107 | return 1; | 1090 | return 1; |
1108 | } | 1091 | } |
@@ -1111,10 +1094,8 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1111 | * the backend memory allocation. | 1094 | * the backend memory allocation. |
1112 | */ | 1095 | */ |
1113 | cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd); | 1096 | cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd); |
1114 | if (cmd->sense_reason) { | 1097 | if (cmd->sense_reason) |
1115 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | ||
1116 | return 1; | 1098 | return 1; |
1117 | } | ||
1118 | 1099 | ||
1119 | return 0; | 1100 | return 0; |
1120 | } | 1101 | } |
@@ -1124,6 +1105,7 @@ static int | |||
1124 | iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr, | 1105 | iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr, |
1125 | bool dump_payload) | 1106 | bool dump_payload) |
1126 | { | 1107 | { |
1108 | struct iscsi_conn *conn = cmd->conn; | ||
1127 | int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; | 1109 | int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; |
1128 | /* | 1110 | /* |
1129 | * Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes. | 1111 | * Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes. |
@@ -1140,20 +1122,25 @@ after_immediate_data: | |||
1140 | * DataCRC, check against ExpCmdSN/MaxCmdSN if | 1122 | * DataCRC, check against ExpCmdSN/MaxCmdSN if |
1141 | * Immediate Bit is not set. | 1123 | * Immediate Bit is not set. |
1142 | */ | 1124 | */ |
1143 | cmdsn_ret = iscsit_sequence_cmd(cmd->conn, cmd, hdr->cmdsn); | 1125 | cmdsn_ret = iscsit_sequence_cmd(cmd->conn, cmd, |
1126 | (unsigned char *)hdr, hdr->cmdsn); | ||
1127 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) { | ||
1128 | return -1; | ||
1129 | } else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) { | ||
1130 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | ||
1131 | return 0; | ||
1132 | } | ||
1144 | 1133 | ||
1145 | if (cmd->sense_reason) { | 1134 | if (cmd->sense_reason) { |
1146 | if (iscsit_dump_data_payload(cmd->conn, | 1135 | int rc; |
1147 | cmd->first_burst_len, 1) < 0) | 1136 | |
1148 | return -1; | 1137 | rc = iscsit_dump_data_payload(cmd->conn, |
1138 | cmd->first_burst_len, 1); | ||
1139 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | ||
1140 | return rc; | ||
1149 | } else if (cmd->unsolicited_data) | 1141 | } else if (cmd->unsolicited_data) |
1150 | iscsit_set_unsoliticed_dataout(cmd); | 1142 | iscsit_set_unsoliticed_dataout(cmd); |
1151 | 1143 | ||
1152 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | ||
1153 | return iscsit_add_reject_from_cmd( | ||
1154 | ISCSI_REASON_PROTOCOL_ERROR, | ||
1155 | 1, 0, (unsigned char *)hdr, cmd); | ||
1156 | |||
1157 | } else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) { | 1144 | } else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) { |
1158 | /* | 1145 | /* |
1159 | * Immediate Data failed DataCRC and ERL>=1, | 1146 | * Immediate Data failed DataCRC and ERL>=1, |
@@ -1184,15 +1171,14 @@ iscsit_handle_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1184 | 1171 | ||
1185 | rc = iscsit_setup_scsi_cmd(conn, cmd, buf); | 1172 | rc = iscsit_setup_scsi_cmd(conn, cmd, buf); |
1186 | if (rc < 0) | 1173 | if (rc < 0) |
1187 | return rc; | 1174 | return 0; |
1188 | /* | 1175 | /* |
1189 | * Allocation iovecs needed for struct socket operations for | 1176 | * Allocation iovecs needed for struct socket operations for |
1190 | * traditional iSCSI block I/O. | 1177 | * traditional iSCSI block I/O. |
1191 | */ | 1178 | */ |
1192 | if (iscsit_allocate_iovecs(cmd) < 0) { | 1179 | if (iscsit_allocate_iovecs(cmd) < 0) { |
1193 | return iscsit_add_reject_from_cmd( | 1180 | return iscsit_add_reject_cmd(cmd, |
1194 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1181 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
1195 | 1, 0, buf, cmd); | ||
1196 | } | 1182 | } |
1197 | immed_data = cmd->immediate_data; | 1183 | immed_data = cmd->immediate_data; |
1198 | 1184 | ||
@@ -1277,14 +1263,13 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, | |||
1277 | struct iscsi_data *hdr = (struct iscsi_data *)buf; | 1263 | struct iscsi_data *hdr = (struct iscsi_data *)buf; |
1278 | struct iscsi_cmd *cmd = NULL; | 1264 | struct iscsi_cmd *cmd = NULL; |
1279 | struct se_cmd *se_cmd; | 1265 | struct se_cmd *se_cmd; |
1280 | unsigned long flags; | ||
1281 | u32 payload_length = ntoh24(hdr->dlength); | 1266 | u32 payload_length = ntoh24(hdr->dlength); |
1282 | int rc; | 1267 | int rc; |
1283 | 1268 | ||
1284 | if (!payload_length) { | 1269 | if (!payload_length) { |
1285 | pr_err("DataOUT payload is ZERO, protocol error.\n"); | 1270 | pr_err("DataOUT payload is ZERO, protocol error.\n"); |
1286 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 1271 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
1287 | buf, conn); | 1272 | buf); |
1288 | } | 1273 | } |
1289 | 1274 | ||
1290 | /* iSCSI write */ | 1275 | /* iSCSI write */ |
@@ -1301,8 +1286,8 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, | |||
1301 | pr_err("DataSegmentLength: %u is greater than" | 1286 | pr_err("DataSegmentLength: %u is greater than" |
1302 | " MaxXmitDataSegmentLength: %u\n", payload_length, | 1287 | " MaxXmitDataSegmentLength: %u\n", payload_length, |
1303 | conn->conn_ops->MaxXmitDataSegmentLength); | 1288 | conn->conn_ops->MaxXmitDataSegmentLength); |
1304 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 1289 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
1305 | buf, conn); | 1290 | buf); |
1306 | } | 1291 | } |
1307 | 1292 | ||
1308 | cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt, | 1293 | cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt, |
@@ -1325,8 +1310,7 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, | |||
1325 | if (cmd->data_direction != DMA_TO_DEVICE) { | 1310 | if (cmd->data_direction != DMA_TO_DEVICE) { |
1326 | pr_err("Command ITT: 0x%08x received DataOUT for a" | 1311 | pr_err("Command ITT: 0x%08x received DataOUT for a" |
1327 | " NON-WRITE command.\n", cmd->init_task_tag); | 1312 | " NON-WRITE command.\n", cmd->init_task_tag); |
1328 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 1313 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf); |
1329 | 1, 0, buf, cmd); | ||
1330 | } | 1314 | } |
1331 | se_cmd = &cmd->se_cmd; | 1315 | se_cmd = &cmd->se_cmd; |
1332 | iscsit_mod_dataout_timer(cmd); | 1316 | iscsit_mod_dataout_timer(cmd); |
@@ -1335,8 +1319,7 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, | |||
1335 | pr_err("DataOut Offset: %u, Length %u greater than" | 1319 | pr_err("DataOut Offset: %u, Length %u greater than" |
1336 | " iSCSI Command EDTL %u, protocol error.\n", | 1320 | " iSCSI Command EDTL %u, protocol error.\n", |
1337 | hdr->offset, payload_length, cmd->se_cmd.data_length); | 1321 | hdr->offset, payload_length, cmd->se_cmd.data_length); |
1338 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 1322 | return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID, buf); |
1339 | 1, 0, buf, cmd); | ||
1340 | } | 1323 | } |
1341 | 1324 | ||
1342 | if (cmd->unsolicited_data) { | 1325 | if (cmd->unsolicited_data) { |
@@ -1356,14 +1339,9 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, | |||
1356 | */ | 1339 | */ |
1357 | 1340 | ||
1358 | /* Something's amiss if we're not in WRITE_PENDING state... */ | 1341 | /* Something's amiss if we're not in WRITE_PENDING state... */ |
1359 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); | ||
1360 | WARN_ON(se_cmd->t_state != TRANSPORT_WRITE_PENDING); | 1342 | WARN_ON(se_cmd->t_state != TRANSPORT_WRITE_PENDING); |
1361 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); | ||
1362 | |||
1363 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); | ||
1364 | if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE)) | 1343 | if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE)) |
1365 | dump_unsolicited_data = 1; | 1344 | dump_unsolicited_data = 1; |
1366 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); | ||
1367 | 1345 | ||
1368 | if (dump_unsolicited_data) { | 1346 | if (dump_unsolicited_data) { |
1369 | /* | 1347 | /* |
@@ -1528,7 +1506,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | |||
1528 | 1506 | ||
1529 | rc = iscsit_check_dataout_hdr(conn, buf, &cmd); | 1507 | rc = iscsit_check_dataout_hdr(conn, buf, &cmd); |
1530 | if (rc < 0) | 1508 | if (rc < 0) |
1531 | return rc; | 1509 | return 0; |
1532 | else if (!cmd) | 1510 | else if (!cmd) |
1533 | return 0; | 1511 | return 0; |
1534 | 1512 | ||
@@ -1541,24 +1519,16 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | |||
1541 | return iscsit_check_dataout_payload(cmd, hdr, data_crc_failed); | 1519 | return iscsit_check_dataout_payload(cmd, hdr, data_crc_failed); |
1542 | } | 1520 | } |
1543 | 1521 | ||
1544 | int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | 1522 | int iscsit_setup_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, |
1545 | unsigned char *buf) | 1523 | struct iscsi_nopout *hdr) |
1546 | { | 1524 | { |
1547 | unsigned char *ping_data = NULL; | 1525 | u32 payload_length = ntoh24(hdr->dlength); |
1548 | int cmdsn_ret, niov = 0, ret = 0, rx_got, rx_size; | ||
1549 | u32 checksum, data_crc, padding = 0, payload_length; | ||
1550 | struct iscsi_cmd *cmd_p = NULL; | ||
1551 | struct kvec *iov = NULL; | ||
1552 | struct iscsi_nopout *hdr; | ||
1553 | |||
1554 | hdr = (struct iscsi_nopout *) buf; | ||
1555 | payload_length = ntoh24(hdr->dlength); | ||
1556 | 1526 | ||
1557 | if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { | 1527 | if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { |
1558 | pr_err("NOPOUT ITT is reserved, but Immediate Bit is" | 1528 | pr_err("NOPOUT ITT is reserved, but Immediate Bit is" |
1559 | " not set, protocol error.\n"); | 1529 | " not set, protocol error.\n"); |
1560 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 1530 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, |
1561 | buf, conn); | 1531 | (unsigned char *)hdr); |
1562 | } | 1532 | } |
1563 | 1533 | ||
1564 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { | 1534 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { |
@@ -1566,8 +1536,8 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1566 | " greater than MaxXmitDataSegmentLength: %u, protocol" | 1536 | " greater than MaxXmitDataSegmentLength: %u, protocol" |
1567 | " error.\n", payload_length, | 1537 | " error.\n", payload_length, |
1568 | conn->conn_ops->MaxXmitDataSegmentLength); | 1538 | conn->conn_ops->MaxXmitDataSegmentLength); |
1569 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 1539 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, |
1570 | buf, conn); | 1540 | (unsigned char *)hdr); |
1571 | } | 1541 | } |
1572 | 1542 | ||
1573 | pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%08x," | 1543 | pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%08x," |
@@ -1583,11 +1553,6 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1583 | * can contain ping data. | 1553 | * can contain ping data. |
1584 | */ | 1554 | */ |
1585 | if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { | 1555 | if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { |
1586 | if (!cmd) | ||
1587 | return iscsit_add_reject( | ||
1588 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
1589 | 1, buf, conn); | ||
1590 | |||
1591 | cmd->iscsi_opcode = ISCSI_OP_NOOP_OUT; | 1556 | cmd->iscsi_opcode = ISCSI_OP_NOOP_OUT; |
1592 | cmd->i_state = ISTATE_SEND_NOPIN; | 1557 | cmd->i_state = ISTATE_SEND_NOPIN; |
1593 | cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? | 1558 | cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? |
@@ -1599,8 +1564,85 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1599 | cmd->data_direction = DMA_NONE; | 1564 | cmd->data_direction = DMA_NONE; |
1600 | } | 1565 | } |
1601 | 1566 | ||
1567 | return 0; | ||
1568 | } | ||
1569 | EXPORT_SYMBOL(iscsit_setup_nop_out); | ||
1570 | |||
1571 | int iscsit_process_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | ||
1572 | struct iscsi_nopout *hdr) | ||
1573 | { | ||
1574 | struct iscsi_cmd *cmd_p = NULL; | ||
1575 | int cmdsn_ret = 0; | ||
1576 | /* | ||
1577 | * Initiator is expecting a NopIN ping reply.. | ||
1578 | */ | ||
1579 | if (hdr->itt != RESERVED_ITT) { | ||
1580 | BUG_ON(!cmd); | ||
1581 | |||
1582 | spin_lock_bh(&conn->cmd_lock); | ||
1583 | list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); | ||
1584 | spin_unlock_bh(&conn->cmd_lock); | ||
1585 | |||
1586 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); | ||
1587 | |||
1588 | if (hdr->opcode & ISCSI_OP_IMMEDIATE) { | ||
1589 | iscsit_add_cmd_to_response_queue(cmd, conn, | ||
1590 | cmd->i_state); | ||
1591 | return 0; | ||
1592 | } | ||
1593 | |||
1594 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, | ||
1595 | (unsigned char *)hdr, hdr->cmdsn); | ||
1596 | if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) | ||
1597 | return 0; | ||
1598 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | ||
1599 | return -1; | ||
1600 | |||
1601 | return 0; | ||
1602 | } | ||
1603 | /* | ||
1604 | * This was a response to a unsolicited NOPIN ping. | ||
1605 | */ | ||
1606 | if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) { | ||
1607 | cmd_p = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt)); | ||
1608 | if (!cmd_p) | ||
1609 | return -EINVAL; | ||
1610 | |||
1611 | iscsit_stop_nopin_response_timer(conn); | ||
1612 | |||
1613 | cmd_p->i_state = ISTATE_REMOVE; | ||
1614 | iscsit_add_cmd_to_immediate_queue(cmd_p, conn, cmd_p->i_state); | ||
1615 | |||
1616 | iscsit_start_nopin_timer(conn); | ||
1617 | return 0; | ||
1618 | } | ||
1619 | /* | ||
1620 | * Otherwise, initiator is not expecting a NOPIN is response. | ||
1621 | * Just ignore for now. | ||
1622 | */ | ||
1623 | return 0; | ||
1624 | } | ||
1625 | EXPORT_SYMBOL(iscsit_process_nop_out); | ||
1626 | |||
1627 | static int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | ||
1628 | unsigned char *buf) | ||
1629 | { | ||
1630 | unsigned char *ping_data = NULL; | ||
1631 | struct iscsi_nopout *hdr = (struct iscsi_nopout *)buf; | ||
1632 | struct kvec *iov = NULL; | ||
1633 | u32 payload_length = ntoh24(hdr->dlength); | ||
1634 | int ret; | ||
1635 | |||
1636 | ret = iscsit_setup_nop_out(conn, cmd, hdr); | ||
1637 | if (ret < 0) | ||
1638 | return 0; | ||
1639 | /* | ||
1640 | * Handle NOP-OUT payload for traditional iSCSI sockets | ||
1641 | */ | ||
1602 | if (payload_length && hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { | 1642 | if (payload_length && hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { |
1603 | rx_size = payload_length; | 1643 | u32 checksum, data_crc, padding = 0; |
1644 | int niov = 0, rx_got, rx_size = payload_length; | ||
1645 | |||
1604 | ping_data = kzalloc(payload_length + 1, GFP_KERNEL); | 1646 | ping_data = kzalloc(payload_length + 1, GFP_KERNEL); |
1605 | if (!ping_data) { | 1647 | if (!ping_data) { |
1606 | pr_err("Unable to allocate memory for" | 1648 | pr_err("Unable to allocate memory for" |
@@ -1679,76 +1721,14 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1679 | pr_debug("Ping Data: \"%s\"\n", ping_data); | 1721 | pr_debug("Ping Data: \"%s\"\n", ping_data); |
1680 | } | 1722 | } |
1681 | 1723 | ||
1682 | if (hdr->itt != RESERVED_ITT) { | 1724 | return iscsit_process_nop_out(conn, cmd, hdr); |
1683 | if (!cmd) { | ||
1684 | pr_err("Checking CmdSN for NOPOUT," | ||
1685 | " but cmd is NULL!\n"); | ||
1686 | return -1; | ||
1687 | } | ||
1688 | /* | ||
1689 | * Initiator is expecting a NopIN ping reply, | ||
1690 | */ | ||
1691 | spin_lock_bh(&conn->cmd_lock); | ||
1692 | list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); | ||
1693 | spin_unlock_bh(&conn->cmd_lock); | ||
1694 | |||
1695 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); | ||
1696 | |||
1697 | if (hdr->opcode & ISCSI_OP_IMMEDIATE) { | ||
1698 | iscsit_add_cmd_to_response_queue(cmd, conn, | ||
1699 | cmd->i_state); | ||
1700 | return 0; | ||
1701 | } | ||
1702 | |||
1703 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); | ||
1704 | if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) { | ||
1705 | ret = 0; | ||
1706 | goto ping_out; | ||
1707 | } | ||
1708 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | ||
1709 | return iscsit_add_reject_from_cmd( | ||
1710 | ISCSI_REASON_PROTOCOL_ERROR, | ||
1711 | 1, 0, buf, cmd); | ||
1712 | |||
1713 | return 0; | ||
1714 | } | ||
1715 | |||
1716 | if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) { | ||
1717 | /* | ||
1718 | * This was a response to a unsolicited NOPIN ping. | ||
1719 | */ | ||
1720 | cmd_p = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt)); | ||
1721 | if (!cmd_p) | ||
1722 | return -1; | ||
1723 | |||
1724 | iscsit_stop_nopin_response_timer(conn); | ||
1725 | |||
1726 | cmd_p->i_state = ISTATE_REMOVE; | ||
1727 | iscsit_add_cmd_to_immediate_queue(cmd_p, conn, cmd_p->i_state); | ||
1728 | iscsit_start_nopin_timer(conn); | ||
1729 | } else { | ||
1730 | /* | ||
1731 | * Initiator is not expecting a NOPIN is response. | ||
1732 | * Just ignore for now. | ||
1733 | * | ||
1734 | * iSCSI v19-91 10.18 | ||
1735 | * "A NOP-OUT may also be used to confirm a changed | ||
1736 | * ExpStatSN if another PDU will not be available | ||
1737 | * for a long time." | ||
1738 | */ | ||
1739 | ret = 0; | ||
1740 | goto out; | ||
1741 | } | ||
1742 | |||
1743 | return 0; | ||
1744 | out: | 1725 | out: |
1745 | if (cmd) | 1726 | if (cmd) |
1746 | iscsit_free_cmd(cmd, false); | 1727 | iscsit_free_cmd(cmd, false); |
1747 | ping_out: | 1728 | |
1748 | kfree(ping_data); | 1729 | kfree(ping_data); |
1749 | return ret; | 1730 | return ret; |
1750 | } | 1731 | } |
1751 | EXPORT_SYMBOL(iscsit_handle_nop_out); | ||
1752 | 1732 | ||
1753 | int | 1733 | int |
1754 | iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | 1734 | iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, |
@@ -1757,8 +1737,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1757 | struct se_tmr_req *se_tmr; | 1737 | struct se_tmr_req *se_tmr; |
1758 | struct iscsi_tmr_req *tmr_req; | 1738 | struct iscsi_tmr_req *tmr_req; |
1759 | struct iscsi_tm *hdr; | 1739 | struct iscsi_tm *hdr; |
1760 | int out_of_order_cmdsn = 0; | 1740 | int out_of_order_cmdsn = 0, ret; |
1761 | int ret; | 1741 | bool sess_ref = false; |
1762 | u8 function; | 1742 | u8 function; |
1763 | 1743 | ||
1764 | hdr = (struct iscsi_tm *) buf; | 1744 | hdr = (struct iscsi_tm *) buf; |
@@ -1782,8 +1762,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1782 | pr_err("Task Management Request TASK_REASSIGN not" | 1762 | pr_err("Task Management Request TASK_REASSIGN not" |
1783 | " issued as immediate command, bad iSCSI Initiator" | 1763 | " issued as immediate command, bad iSCSI Initiator" |
1784 | "implementation\n"); | 1764 | "implementation\n"); |
1785 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 1765 | return iscsit_add_reject_cmd(cmd, |
1786 | 1, 1, buf, cmd); | 1766 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
1787 | } | 1767 | } |
1788 | if ((function != ISCSI_TM_FUNC_ABORT_TASK) && | 1768 | if ((function != ISCSI_TM_FUNC_ABORT_TASK) && |
1789 | be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG) | 1769 | be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG) |
@@ -1795,9 +1775,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1795 | if (!cmd->tmr_req) { | 1775 | if (!cmd->tmr_req) { |
1796 | pr_err("Unable to allocate memory for" | 1776 | pr_err("Unable to allocate memory for" |
1797 | " Task Management command!\n"); | 1777 | " Task Management command!\n"); |
1798 | return iscsit_add_reject_from_cmd( | 1778 | return iscsit_add_reject_cmd(cmd, |
1799 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1779 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
1800 | 1, 1, buf, cmd); | 1780 | buf); |
1801 | } | 1781 | } |
1802 | 1782 | ||
1803 | /* | 1783 | /* |
@@ -1814,6 +1794,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1814 | conn->sess->se_sess, 0, DMA_NONE, | 1794 | conn->sess->se_sess, 0, DMA_NONE, |
1815 | MSG_SIMPLE_TAG, cmd->sense_buffer + 2); | 1795 | MSG_SIMPLE_TAG, cmd->sense_buffer + 2); |
1816 | 1796 | ||
1797 | target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true); | ||
1798 | sess_ref = true; | ||
1799 | |||
1817 | switch (function) { | 1800 | switch (function) { |
1818 | case ISCSI_TM_FUNC_ABORT_TASK: | 1801 | case ISCSI_TM_FUNC_ABORT_TASK: |
1819 | tcm_function = TMR_ABORT_TASK; | 1802 | tcm_function = TMR_ABORT_TASK; |
@@ -1839,17 +1822,15 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1839 | default: | 1822 | default: |
1840 | pr_err("Unknown iSCSI TMR Function:" | 1823 | pr_err("Unknown iSCSI TMR Function:" |
1841 | " 0x%02x\n", function); | 1824 | " 0x%02x\n", function); |
1842 | return iscsit_add_reject_from_cmd( | 1825 | return iscsit_add_reject_cmd(cmd, |
1843 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1826 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
1844 | 1, 1, buf, cmd); | ||
1845 | } | 1827 | } |
1846 | 1828 | ||
1847 | ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req, | 1829 | ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req, |
1848 | tcm_function, GFP_KERNEL); | 1830 | tcm_function, GFP_KERNEL); |
1849 | if (ret < 0) | 1831 | if (ret < 0) |
1850 | return iscsit_add_reject_from_cmd( | 1832 | return iscsit_add_reject_cmd(cmd, |
1851 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1833 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
1852 | 1, 1, buf, cmd); | ||
1853 | 1834 | ||
1854 | cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req; | 1835 | cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req; |
1855 | } | 1836 | } |
@@ -1908,9 +1889,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1908 | break; | 1889 | break; |
1909 | 1890 | ||
1910 | if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0) | 1891 | if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0) |
1911 | return iscsit_add_reject_from_cmd( | 1892 | return iscsit_add_reject_cmd(cmd, |
1912 | ISCSI_REASON_BOOKMARK_INVALID, 1, 1, | 1893 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
1913 | buf, cmd); | ||
1914 | break; | 1894 | break; |
1915 | default: | 1895 | default: |
1916 | pr_err("Unknown TMR function: 0x%02x, protocol" | 1896 | pr_err("Unknown TMR function: 0x%02x, protocol" |
@@ -1928,15 +1908,13 @@ attach: | |||
1928 | spin_unlock_bh(&conn->cmd_lock); | 1908 | spin_unlock_bh(&conn->cmd_lock); |
1929 | 1909 | ||
1930 | if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { | 1910 | if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { |
1931 | int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); | 1911 | int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn); |
1932 | if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP) | 1912 | if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP) |
1933 | out_of_order_cmdsn = 1; | 1913 | out_of_order_cmdsn = 1; |
1934 | else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) | 1914 | else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) |
1935 | return 0; | 1915 | return 0; |
1936 | else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | 1916 | else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) |
1937 | return iscsit_add_reject_from_cmd( | 1917 | return -1; |
1938 | ISCSI_REASON_PROTOCOL_ERROR, | ||
1939 | 1, 0, buf, cmd); | ||
1940 | } | 1918 | } |
1941 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); | 1919 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); |
1942 | 1920 | ||
@@ -1956,51 +1934,135 @@ attach: | |||
1956 | * For connection recovery, this is also the default action for | 1934 | * For connection recovery, this is also the default action for |
1957 | * TMR TASK_REASSIGN. | 1935 | * TMR TASK_REASSIGN. |
1958 | */ | 1936 | */ |
1937 | if (sess_ref) { | ||
1938 | pr_debug("Handle TMR, using sess_ref=true check\n"); | ||
1939 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | ||
1940 | } | ||
1941 | |||
1959 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); | 1942 | iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); |
1960 | return 0; | 1943 | return 0; |
1961 | } | 1944 | } |
1962 | EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd); | 1945 | EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd); |
1963 | 1946 | ||
1964 | /* #warning FIXME: Support Text Command parameters besides SendTargets */ | 1947 | /* #warning FIXME: Support Text Command parameters besides SendTargets */ |
1965 | static int iscsit_handle_text_cmd( | 1948 | int |
1966 | struct iscsi_conn *conn, | 1949 | iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, |
1967 | unsigned char *buf) | 1950 | struct iscsi_text *hdr) |
1968 | { | 1951 | { |
1969 | char *text_ptr, *text_in; | 1952 | u32 payload_length = ntoh24(hdr->dlength); |
1970 | int cmdsn_ret, niov = 0, rx_got, rx_size; | ||
1971 | u32 checksum = 0, data_crc = 0, payload_length; | ||
1972 | u32 padding = 0, pad_bytes = 0, text_length = 0; | ||
1973 | struct iscsi_cmd *cmd; | ||
1974 | struct kvec iov[3]; | ||
1975 | struct iscsi_text *hdr; | ||
1976 | |||
1977 | hdr = (struct iscsi_text *) buf; | ||
1978 | payload_length = ntoh24(hdr->dlength); | ||
1979 | 1953 | ||
1980 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { | 1954 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { |
1981 | pr_err("Unable to accept text parameter length: %u" | 1955 | pr_err("Unable to accept text parameter length: %u" |
1982 | "greater than MaxXmitDataSegmentLength %u.\n", | 1956 | "greater than MaxXmitDataSegmentLength %u.\n", |
1983 | payload_length, conn->conn_ops->MaxXmitDataSegmentLength); | 1957 | payload_length, conn->conn_ops->MaxXmitDataSegmentLength); |
1984 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 1958 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, |
1985 | buf, conn); | 1959 | (unsigned char *)hdr); |
1986 | } | 1960 | } |
1987 | 1961 | ||
1988 | pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x," | 1962 | pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x," |
1989 | " ExpStatSN: 0x%08x, Length: %u\n", hdr->itt, hdr->cmdsn, | 1963 | " ExpStatSN: 0x%08x, Length: %u\n", hdr->itt, hdr->cmdsn, |
1990 | hdr->exp_statsn, payload_length); | 1964 | hdr->exp_statsn, payload_length); |
1991 | 1965 | ||
1992 | rx_size = text_length = payload_length; | 1966 | cmd->iscsi_opcode = ISCSI_OP_TEXT; |
1993 | if (text_length) { | 1967 | cmd->i_state = ISTATE_SEND_TEXTRSP; |
1994 | text_in = kzalloc(text_length, GFP_KERNEL); | 1968 | cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); |
1969 | conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; | ||
1970 | cmd->targ_xfer_tag = 0xFFFFFFFF; | ||
1971 | cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); | ||
1972 | cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); | ||
1973 | cmd->data_direction = DMA_NONE; | ||
1974 | |||
1975 | return 0; | ||
1976 | } | ||
1977 | EXPORT_SYMBOL(iscsit_setup_text_cmd); | ||
1978 | |||
1979 | int | ||
1980 | iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | ||
1981 | struct iscsi_text *hdr) | ||
1982 | { | ||
1983 | unsigned char *text_in = cmd->text_in_ptr, *text_ptr; | ||
1984 | int cmdsn_ret; | ||
1985 | |||
1986 | if (!text_in) { | ||
1987 | pr_err("Unable to locate text_in buffer for sendtargets" | ||
1988 | " discovery\n"); | ||
1989 | goto reject; | ||
1990 | } | ||
1991 | if (strncmp("SendTargets", text_in, 11) != 0) { | ||
1992 | pr_err("Received Text Data that is not" | ||
1993 | " SendTargets, cannot continue.\n"); | ||
1994 | goto reject; | ||
1995 | } | ||
1996 | text_ptr = strchr(text_in, '='); | ||
1997 | if (!text_ptr) { | ||
1998 | pr_err("No \"=\" separator found in Text Data," | ||
1999 | " cannot continue.\n"); | ||
2000 | goto reject; | ||
2001 | } | ||
2002 | if (!strncmp("=All", text_ptr, 4)) { | ||
2003 | cmd->cmd_flags |= IFC_SENDTARGETS_ALL; | ||
2004 | } else if (!strncmp("=iqn.", text_ptr, 5) || | ||
2005 | !strncmp("=eui.", text_ptr, 5)) { | ||
2006 | cmd->cmd_flags |= IFC_SENDTARGETS_SINGLE; | ||
2007 | } else { | ||
2008 | pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr); | ||
2009 | goto reject; | ||
2010 | } | ||
2011 | |||
2012 | spin_lock_bh(&conn->cmd_lock); | ||
2013 | list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); | ||
2014 | spin_unlock_bh(&conn->cmd_lock); | ||
2015 | |||
2016 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); | ||
2017 | |||
2018 | if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { | ||
2019 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, | ||
2020 | (unsigned char *)hdr, hdr->cmdsn); | ||
2021 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | ||
2022 | return -1; | ||
2023 | |||
2024 | return 0; | ||
2025 | } | ||
2026 | |||
2027 | return iscsit_execute_cmd(cmd, 0); | ||
2028 | |||
2029 | reject: | ||
2030 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, | ||
2031 | (unsigned char *)hdr); | ||
2032 | } | ||
2033 | EXPORT_SYMBOL(iscsit_process_text_cmd); | ||
2034 | |||
2035 | static int | ||
2036 | iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | ||
2037 | unsigned char *buf) | ||
2038 | { | ||
2039 | struct iscsi_text *hdr = (struct iscsi_text *)buf; | ||
2040 | char *text_in = NULL; | ||
2041 | u32 payload_length = ntoh24(hdr->dlength); | ||
2042 | int rx_size, rc; | ||
2043 | |||
2044 | rc = iscsit_setup_text_cmd(conn, cmd, hdr); | ||
2045 | if (rc < 0) | ||
2046 | return 0; | ||
2047 | |||
2048 | rx_size = payload_length; | ||
2049 | if (payload_length) { | ||
2050 | u32 checksum = 0, data_crc = 0; | ||
2051 | u32 padding = 0, pad_bytes = 0; | ||
2052 | int niov = 0, rx_got; | ||
2053 | struct kvec iov[3]; | ||
2054 | |||
2055 | text_in = kzalloc(payload_length, GFP_KERNEL); | ||
1995 | if (!text_in) { | 2056 | if (!text_in) { |
1996 | pr_err("Unable to allocate memory for" | 2057 | pr_err("Unable to allocate memory for" |
1997 | " incoming text parameters\n"); | 2058 | " incoming text parameters\n"); |
1998 | return -1; | 2059 | goto reject; |
1999 | } | 2060 | } |
2061 | cmd->text_in_ptr = text_in; | ||
2000 | 2062 | ||
2001 | memset(iov, 0, 3 * sizeof(struct kvec)); | 2063 | memset(iov, 0, 3 * sizeof(struct kvec)); |
2002 | iov[niov].iov_base = text_in; | 2064 | iov[niov].iov_base = text_in; |
2003 | iov[niov++].iov_len = text_length; | 2065 | iov[niov++].iov_len = payload_length; |
2004 | 2066 | ||
2005 | padding = ((-payload_length) & 3); | 2067 | padding = ((-payload_length) & 3); |
2006 | if (padding != 0) { | 2068 | if (padding != 0) { |
@@ -2017,14 +2079,12 @@ static int iscsit_handle_text_cmd( | |||
2017 | } | 2079 | } |
2018 | 2080 | ||
2019 | rx_got = rx_data(conn, &iov[0], niov, rx_size); | 2081 | rx_got = rx_data(conn, &iov[0], niov, rx_size); |
2020 | if (rx_got != rx_size) { | 2082 | if (rx_got != rx_size) |
2021 | kfree(text_in); | 2083 | goto reject; |
2022 | return -1; | ||
2023 | } | ||
2024 | 2084 | ||
2025 | if (conn->conn_ops->DataDigest) { | 2085 | if (conn->conn_ops->DataDigest) { |
2026 | iscsit_do_crypto_hash_buf(&conn->conn_rx_hash, | 2086 | iscsit_do_crypto_hash_buf(&conn->conn_rx_hash, |
2027 | text_in, text_length, | 2087 | text_in, payload_length, |
2028 | padding, (u8 *)&pad_bytes, | 2088 | padding, (u8 *)&pad_bytes, |
2029 | (u8 *)&data_crc); | 2089 | (u8 *)&data_crc); |
2030 | 2090 | ||
@@ -2036,8 +2096,7 @@ static int iscsit_handle_text_cmd( | |||
2036 | pr_err("Unable to recover from" | 2096 | pr_err("Unable to recover from" |
2037 | " Text Data digest failure while in" | 2097 | " Text Data digest failure while in" |
2038 | " ERL=0.\n"); | 2098 | " ERL=0.\n"); |
2039 | kfree(text_in); | 2099 | goto reject; |
2040 | return -1; | ||
2041 | } else { | 2100 | } else { |
2042 | /* | 2101 | /* |
2043 | * Silently drop this PDU and let the | 2102 | * Silently drop this PDU and let the |
@@ -2052,68 +2111,22 @@ static int iscsit_handle_text_cmd( | |||
2052 | } else { | 2111 | } else { |
2053 | pr_debug("Got CRC32C DataDigest" | 2112 | pr_debug("Got CRC32C DataDigest" |
2054 | " 0x%08x for %u bytes of text data.\n", | 2113 | " 0x%08x for %u bytes of text data.\n", |
2055 | checksum, text_length); | 2114 | checksum, payload_length); |
2056 | } | 2115 | } |
2057 | } | 2116 | } |
2058 | text_in[text_length - 1] = '\0'; | 2117 | text_in[payload_length - 1] = '\0'; |
2059 | pr_debug("Successfully read %d bytes of text" | 2118 | pr_debug("Successfully read %d bytes of text" |
2060 | " data.\n", text_length); | 2119 | " data.\n", payload_length); |
2061 | |||
2062 | if (strncmp("SendTargets", text_in, 11) != 0) { | ||
2063 | pr_err("Received Text Data that is not" | ||
2064 | " SendTargets, cannot continue.\n"); | ||
2065 | kfree(text_in); | ||
2066 | return -1; | ||
2067 | } | ||
2068 | text_ptr = strchr(text_in, '='); | ||
2069 | if (!text_ptr) { | ||
2070 | pr_err("No \"=\" separator found in Text Data," | ||
2071 | " cannot continue.\n"); | ||
2072 | kfree(text_in); | ||
2073 | return -1; | ||
2074 | } | ||
2075 | if (strncmp("=All", text_ptr, 4) != 0) { | ||
2076 | pr_err("Unable to locate All value for" | ||
2077 | " SendTargets key, cannot continue.\n"); | ||
2078 | kfree(text_in); | ||
2079 | return -1; | ||
2080 | } | ||
2081 | /*#warning Support SendTargets=(iSCSI Target Name/Nothing) values. */ | ||
2082 | kfree(text_in); | ||
2083 | } | 2120 | } |
2084 | 2121 | ||
2085 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 2122 | return iscsit_process_text_cmd(conn, cmd, hdr); |
2086 | if (!cmd) | ||
2087 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
2088 | 1, buf, conn); | ||
2089 | |||
2090 | cmd->iscsi_opcode = ISCSI_OP_TEXT; | ||
2091 | cmd->i_state = ISTATE_SEND_TEXTRSP; | ||
2092 | cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); | ||
2093 | conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; | ||
2094 | cmd->targ_xfer_tag = 0xFFFFFFFF; | ||
2095 | cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); | ||
2096 | cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); | ||
2097 | cmd->data_direction = DMA_NONE; | ||
2098 | |||
2099 | spin_lock_bh(&conn->cmd_lock); | ||
2100 | list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); | ||
2101 | spin_unlock_bh(&conn->cmd_lock); | ||
2102 | 2123 | ||
2103 | iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); | 2124 | reject: |
2104 | 2125 | kfree(cmd->text_in_ptr); | |
2105 | if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { | 2126 | cmd->text_in_ptr = NULL; |
2106 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); | 2127 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf); |
2107 | if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) | ||
2108 | return iscsit_add_reject_from_cmd( | ||
2109 | ISCSI_REASON_PROTOCOL_ERROR, | ||
2110 | 1, 0, buf, cmd); | ||
2111 | |||
2112 | return 0; | ||
2113 | } | ||
2114 | |||
2115 | return iscsit_execute_cmd(cmd, 0); | ||
2116 | } | 2128 | } |
2129 | EXPORT_SYMBOL(iscsit_handle_text_cmd); | ||
2117 | 2130 | ||
2118 | int iscsit_logout_closesession(struct iscsi_cmd *cmd, struct iscsi_conn *conn) | 2131 | int iscsit_logout_closesession(struct iscsi_cmd *cmd, struct iscsi_conn *conn) |
2119 | { | 2132 | { |
@@ -2292,14 +2305,11 @@ iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2292 | if (ret < 0) | 2305 | if (ret < 0) |
2293 | return ret; | 2306 | return ret; |
2294 | } else { | 2307 | } else { |
2295 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); | 2308 | cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn); |
2296 | if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) { | 2309 | if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) |
2297 | logout_remove = 0; | 2310 | logout_remove = 0; |
2298 | } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) { | 2311 | else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) |
2299 | return iscsit_add_reject_from_cmd( | 2312 | return -1; |
2300 | ISCSI_REASON_PROTOCOL_ERROR, | ||
2301 | 1, 0, buf, cmd); | ||
2302 | } | ||
2303 | } | 2313 | } |
2304 | 2314 | ||
2305 | return logout_remove; | 2315 | return logout_remove; |
@@ -2323,8 +2333,8 @@ static int iscsit_handle_snack( | |||
2323 | if (!conn->sess->sess_ops->ErrorRecoveryLevel) { | 2333 | if (!conn->sess->sess_ops->ErrorRecoveryLevel) { |
2324 | pr_err("Initiator sent SNACK request while in" | 2334 | pr_err("Initiator sent SNACK request while in" |
2325 | " ErrorRecoveryLevel=0.\n"); | 2335 | " ErrorRecoveryLevel=0.\n"); |
2326 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 2336 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
2327 | buf, conn); | 2337 | buf); |
2328 | } | 2338 | } |
2329 | /* | 2339 | /* |
2330 | * SNACK_DATA and SNACK_R2T are both 0, so check which function to | 2340 | * SNACK_DATA and SNACK_R2T are both 0, so check which function to |
@@ -2348,13 +2358,13 @@ static int iscsit_handle_snack( | |||
2348 | case ISCSI_FLAG_SNACK_TYPE_RDATA: | 2358 | case ISCSI_FLAG_SNACK_TYPE_RDATA: |
2349 | /* FIXME: Support R-Data SNACK */ | 2359 | /* FIXME: Support R-Data SNACK */ |
2350 | pr_err("R-Data SNACK Not Supported.\n"); | 2360 | pr_err("R-Data SNACK Not Supported.\n"); |
2351 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 2361 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
2352 | buf, conn); | 2362 | buf); |
2353 | default: | 2363 | default: |
2354 | pr_err("Unknown SNACK type 0x%02x, protocol" | 2364 | pr_err("Unknown SNACK type 0x%02x, protocol" |
2355 | " error.\n", hdr->flags & 0x0f); | 2365 | " error.\n", hdr->flags & 0x0f); |
2356 | return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 2366 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
2357 | buf, conn); | 2367 | buf); |
2358 | } | 2368 | } |
2359 | 2369 | ||
2360 | return 0; | 2370 | return 0; |
@@ -2426,14 +2436,14 @@ static int iscsit_handle_immediate_data( | |||
2426 | pr_err("Unable to recover from" | 2436 | pr_err("Unable to recover from" |
2427 | " Immediate Data digest failure while" | 2437 | " Immediate Data digest failure while" |
2428 | " in ERL=0.\n"); | 2438 | " in ERL=0.\n"); |
2429 | iscsit_add_reject_from_cmd( | 2439 | iscsit_reject_cmd(cmd, |
2430 | ISCSI_REASON_DATA_DIGEST_ERROR, | 2440 | ISCSI_REASON_DATA_DIGEST_ERROR, |
2431 | 1, 0, (unsigned char *)hdr, cmd); | 2441 | (unsigned char *)hdr); |
2432 | return IMMEDIATE_DATA_CANNOT_RECOVER; | 2442 | return IMMEDIATE_DATA_CANNOT_RECOVER; |
2433 | } else { | 2443 | } else { |
2434 | iscsit_add_reject_from_cmd( | 2444 | iscsit_reject_cmd(cmd, |
2435 | ISCSI_REASON_DATA_DIGEST_ERROR, | 2445 | ISCSI_REASON_DATA_DIGEST_ERROR, |
2436 | 0, 0, (unsigned char *)hdr, cmd); | 2446 | (unsigned char *)hdr); |
2437 | return IMMEDIATE_DATA_ERL1_CRC_FAILURE; | 2447 | return IMMEDIATE_DATA_ERL1_CRC_FAILURE; |
2438 | } | 2448 | } |
2439 | } else { | 2449 | } else { |
@@ -3276,8 +3286,6 @@ static u8 iscsit_convert_tcm_tmr_rsp(struct se_tmr_req *se_tmr) | |||
3276 | return ISCSI_TMF_RSP_NO_LUN; | 3286 | return ISCSI_TMF_RSP_NO_LUN; |
3277 | case TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED: | 3287 | case TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED: |
3278 | return ISCSI_TMF_RSP_NOT_SUPPORTED; | 3288 | return ISCSI_TMF_RSP_NOT_SUPPORTED; |
3279 | case TMR_FUNCTION_AUTHORIZATION_FAILED: | ||
3280 | return ISCSI_TMF_RSP_AUTH_FAILED; | ||
3281 | case TMR_FUNCTION_REJECTED: | 3289 | case TMR_FUNCTION_REJECTED: |
3282 | default: | 3290 | default: |
3283 | return ISCSI_TMF_RSP_REJECTED; | 3291 | return ISCSI_TMF_RSP_REJECTED; |
@@ -3372,6 +3380,7 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) | |||
3372 | struct iscsi_tpg_np *tpg_np; | 3380 | struct iscsi_tpg_np *tpg_np; |
3373 | int buffer_len, end_of_buf = 0, len = 0, payload_len = 0; | 3381 | int buffer_len, end_of_buf = 0, len = 0, payload_len = 0; |
3374 | unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */ | 3382 | unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */ |
3383 | unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL; | ||
3375 | 3384 | ||
3376 | buffer_len = max(conn->conn_ops->MaxRecvDataSegmentLength, | 3385 | buffer_len = max(conn->conn_ops->MaxRecvDataSegmentLength, |
3377 | SENDTARGETS_BUF_LIMIT); | 3386 | SENDTARGETS_BUF_LIMIT); |
@@ -3382,9 +3391,31 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) | |||
3382 | " response.\n"); | 3391 | " response.\n"); |
3383 | return -ENOMEM; | 3392 | return -ENOMEM; |
3384 | } | 3393 | } |
3394 | /* | ||
3395 | * Locate pointer to iqn./eui. string for IFC_SENDTARGETS_SINGLE | ||
3396 | * explicit case.. | ||
3397 | */ | ||
3398 | if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) { | ||
3399 | text_ptr = strchr(text_in, '='); | ||
3400 | if (!text_ptr) { | ||
3401 | pr_err("Unable to locate '=' string in text_in:" | ||
3402 | " %s\n", text_in); | ||
3403 | kfree(payload); | ||
3404 | return -EINVAL; | ||
3405 | } | ||
3406 | /* | ||
3407 | * Skip over '=' character.. | ||
3408 | */ | ||
3409 | text_ptr += 1; | ||
3410 | } | ||
3385 | 3411 | ||
3386 | spin_lock(&tiqn_lock); | 3412 | spin_lock(&tiqn_lock); |
3387 | list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) { | 3413 | list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) { |
3414 | if ((cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) && | ||
3415 | strcmp(tiqn->tiqn, text_ptr)) { | ||
3416 | continue; | ||
3417 | } | ||
3418 | |||
3388 | len = sprintf(buf, "TargetName=%s", tiqn->tiqn); | 3419 | len = sprintf(buf, "TargetName=%s", tiqn->tiqn); |
3389 | len += 1; | 3420 | len += 1; |
3390 | 3421 | ||
@@ -3438,6 +3469,9 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) | |||
3438 | eob: | 3469 | eob: |
3439 | if (end_of_buf) | 3470 | if (end_of_buf) |
3440 | break; | 3471 | break; |
3472 | |||
3473 | if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) | ||
3474 | break; | ||
3441 | } | 3475 | } |
3442 | spin_unlock(&tiqn_lock); | 3476 | spin_unlock(&tiqn_lock); |
3443 | 3477 | ||
@@ -3446,52 +3480,62 @@ eob: | |||
3446 | return payload_len; | 3480 | return payload_len; |
3447 | } | 3481 | } |
3448 | 3482 | ||
3449 | /* | 3483 | int |
3450 | * FIXME: Add support for F_BIT and C_BIT when the length is longer than | 3484 | iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, |
3451 | * MaxRecvDataSegmentLength. | 3485 | struct iscsi_text_rsp *hdr) |
3452 | */ | ||
3453 | static int iscsit_send_text_rsp( | ||
3454 | struct iscsi_cmd *cmd, | ||
3455 | struct iscsi_conn *conn) | ||
3456 | { | 3486 | { |
3457 | struct iscsi_text_rsp *hdr; | 3487 | int text_length, padding; |
3458 | struct kvec *iov; | ||
3459 | u32 padding = 0, tx_size = 0; | ||
3460 | int text_length, iov_count = 0; | ||
3461 | 3488 | ||
3462 | text_length = iscsit_build_sendtargets_response(cmd); | 3489 | text_length = iscsit_build_sendtargets_response(cmd); |
3463 | if (text_length < 0) | 3490 | if (text_length < 0) |
3464 | return text_length; | 3491 | return text_length; |
3465 | 3492 | ||
3493 | hdr->opcode = ISCSI_OP_TEXT_RSP; | ||
3494 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | ||
3466 | padding = ((-text_length) & 3); | 3495 | padding = ((-text_length) & 3); |
3467 | if (padding != 0) { | ||
3468 | memset(cmd->buf_ptr + text_length, 0, padding); | ||
3469 | pr_debug("Attaching %u additional bytes for" | ||
3470 | " padding.\n", padding); | ||
3471 | } | ||
3472 | |||
3473 | hdr = (struct iscsi_text_rsp *) cmd->pdu; | ||
3474 | memset(hdr, 0, ISCSI_HDR_LEN); | ||
3475 | hdr->opcode = ISCSI_OP_TEXT_RSP; | ||
3476 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | ||
3477 | hton24(hdr->dlength, text_length); | 3496 | hton24(hdr->dlength, text_length); |
3478 | hdr->itt = cmd->init_task_tag; | 3497 | hdr->itt = cmd->init_task_tag; |
3479 | hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); | 3498 | hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); |
3480 | cmd->stat_sn = conn->stat_sn++; | 3499 | cmd->stat_sn = conn->stat_sn++; |
3481 | hdr->statsn = cpu_to_be32(cmd->stat_sn); | 3500 | hdr->statsn = cpu_to_be32(cmd->stat_sn); |
3482 | 3501 | ||
3483 | iscsit_increment_maxcmdsn(cmd, conn->sess); | 3502 | iscsit_increment_maxcmdsn(cmd, conn->sess); |
3484 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); | 3503 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); |
3485 | hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); | 3504 | hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); |
3486 | 3505 | ||
3487 | iov = &cmd->iov_misc[0]; | 3506 | pr_debug("Built Text Response: ITT: 0x%08x, StatSN: 0x%08x," |
3507 | " Length: %u, CID: %hu\n", cmd->init_task_tag, cmd->stat_sn, | ||
3508 | text_length, conn->cid); | ||
3509 | |||
3510 | return text_length + padding; | ||
3511 | } | ||
3512 | EXPORT_SYMBOL(iscsit_build_text_rsp); | ||
3488 | 3513 | ||
3514 | /* | ||
3515 | * FIXME: Add support for F_BIT and C_BIT when the length is longer than | ||
3516 | * MaxRecvDataSegmentLength. | ||
3517 | */ | ||
3518 | static int iscsit_send_text_rsp( | ||
3519 | struct iscsi_cmd *cmd, | ||
3520 | struct iscsi_conn *conn) | ||
3521 | { | ||
3522 | struct iscsi_text_rsp *hdr = (struct iscsi_text_rsp *)cmd->pdu; | ||
3523 | struct kvec *iov; | ||
3524 | u32 tx_size = 0; | ||
3525 | int text_length, iov_count = 0, rc; | ||
3526 | |||
3527 | rc = iscsit_build_text_rsp(cmd, conn, hdr); | ||
3528 | if (rc < 0) | ||
3529 | return rc; | ||
3530 | |||
3531 | text_length = rc; | ||
3532 | iov = &cmd->iov_misc[0]; | ||
3489 | iov[iov_count].iov_base = cmd->pdu; | 3533 | iov[iov_count].iov_base = cmd->pdu; |
3490 | iov[iov_count++].iov_len = ISCSI_HDR_LEN; | 3534 | iov[iov_count++].iov_len = ISCSI_HDR_LEN; |
3491 | iov[iov_count].iov_base = cmd->buf_ptr; | 3535 | iov[iov_count].iov_base = cmd->buf_ptr; |
3492 | iov[iov_count++].iov_len = text_length + padding; | 3536 | iov[iov_count++].iov_len = text_length; |
3493 | 3537 | ||
3494 | tx_size += (ISCSI_HDR_LEN + text_length + padding); | 3538 | tx_size += (ISCSI_HDR_LEN + text_length); |
3495 | 3539 | ||
3496 | if (conn->conn_ops->HeaderDigest) { | 3540 | if (conn->conn_ops->HeaderDigest) { |
3497 | u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; | 3541 | u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; |
@@ -3507,7 +3551,7 @@ static int iscsit_send_text_rsp( | |||
3507 | 3551 | ||
3508 | if (conn->conn_ops->DataDigest) { | 3552 | if (conn->conn_ops->DataDigest) { |
3509 | iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, | 3553 | iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, |
3510 | cmd->buf_ptr, (text_length + padding), | 3554 | cmd->buf_ptr, text_length, |
3511 | 0, NULL, (u8 *)&cmd->data_crc); | 3555 | 0, NULL, (u8 *)&cmd->data_crc); |
3512 | 3556 | ||
3513 | iov[iov_count].iov_base = &cmd->data_crc; | 3557 | iov[iov_count].iov_base = &cmd->data_crc; |
@@ -3515,16 +3559,13 @@ static int iscsit_send_text_rsp( | |||
3515 | tx_size += ISCSI_CRC_LEN; | 3559 | tx_size += ISCSI_CRC_LEN; |
3516 | 3560 | ||
3517 | pr_debug("Attaching DataDigest for %u bytes of text" | 3561 | pr_debug("Attaching DataDigest for %u bytes of text" |
3518 | " data, CRC 0x%08x\n", (text_length + padding), | 3562 | " data, CRC 0x%08x\n", text_length, |
3519 | cmd->data_crc); | 3563 | cmd->data_crc); |
3520 | } | 3564 | } |
3521 | 3565 | ||
3522 | cmd->iov_misc_count = iov_count; | 3566 | cmd->iov_misc_count = iov_count; |
3523 | cmd->tx_size = tx_size; | 3567 | cmd->tx_size = tx_size; |
3524 | 3568 | ||
3525 | pr_debug("Built Text Response: ITT: 0x%08x, StatSN: 0x%08x," | ||
3526 | " Length: %u, CID: %hu\n", cmd->init_task_tag, cmd->stat_sn, | ||
3527 | text_length, conn->cid); | ||
3528 | return 0; | 3569 | return 0; |
3529 | } | 3570 | } |
3530 | 3571 | ||
@@ -3533,6 +3574,7 @@ iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | |||
3533 | struct iscsi_reject *hdr) | 3574 | struct iscsi_reject *hdr) |
3534 | { | 3575 | { |
3535 | hdr->opcode = ISCSI_OP_REJECT; | 3576 | hdr->opcode = ISCSI_OP_REJECT; |
3577 | hdr->reason = cmd->reject_reason; | ||
3536 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | 3578 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; |
3537 | hton24(hdr->dlength, ISCSI_HDR_LEN); | 3579 | hton24(hdr->dlength, ISCSI_HDR_LEN); |
3538 | hdr->ffffffff = cpu_to_be32(0xffffffff); | 3580 | hdr->ffffffff = cpu_to_be32(0xffffffff); |
@@ -3806,18 +3848,11 @@ check_rsp_state: | |||
3806 | case ISTATE_SEND_STATUS_RECOVERY: | 3848 | case ISTATE_SEND_STATUS_RECOVERY: |
3807 | case ISTATE_SEND_TEXTRSP: | 3849 | case ISTATE_SEND_TEXTRSP: |
3808 | case ISTATE_SEND_TASKMGTRSP: | 3850 | case ISTATE_SEND_TASKMGTRSP: |
3851 | case ISTATE_SEND_REJECT: | ||
3809 | spin_lock_bh(&cmd->istate_lock); | 3852 | spin_lock_bh(&cmd->istate_lock); |
3810 | cmd->i_state = ISTATE_SENT_STATUS; | 3853 | cmd->i_state = ISTATE_SENT_STATUS; |
3811 | spin_unlock_bh(&cmd->istate_lock); | 3854 | spin_unlock_bh(&cmd->istate_lock); |
3812 | break; | 3855 | break; |
3813 | case ISTATE_SEND_REJECT: | ||
3814 | if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) { | ||
3815 | cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN; | ||
3816 | complete(&cmd->reject_comp); | ||
3817 | goto err; | ||
3818 | } | ||
3819 | complete(&cmd->reject_comp); | ||
3820 | break; | ||
3821 | default: | 3856 | default: |
3822 | pr_err("Unknown Opcode: 0x%02x ITT:" | 3857 | pr_err("Unknown Opcode: 0x%02x ITT:" |
3823 | " 0x%08x, i_state: %d on CID: %hu\n", | 3858 | " 0x%08x, i_state: %d on CID: %hu\n", |
@@ -3922,8 +3957,7 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) | |||
3922 | case ISCSI_OP_SCSI_CMD: | 3957 | case ISCSI_OP_SCSI_CMD: |
3923 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 3958 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
3924 | if (!cmd) | 3959 | if (!cmd) |
3925 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 3960 | goto reject; |
3926 | 1, buf, conn); | ||
3927 | 3961 | ||
3928 | ret = iscsit_handle_scsi_cmd(conn, cmd, buf); | 3962 | ret = iscsit_handle_scsi_cmd(conn, cmd, buf); |
3929 | break; | 3963 | break; |
@@ -3935,27 +3969,28 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) | |||
3935 | if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { | 3969 | if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { |
3936 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 3970 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
3937 | if (!cmd) | 3971 | if (!cmd) |
3938 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 3972 | goto reject; |
3939 | 1, buf, conn); | ||
3940 | } | 3973 | } |
3941 | ret = iscsit_handle_nop_out(conn, cmd, buf); | 3974 | ret = iscsit_handle_nop_out(conn, cmd, buf); |
3942 | break; | 3975 | break; |
3943 | case ISCSI_OP_SCSI_TMFUNC: | 3976 | case ISCSI_OP_SCSI_TMFUNC: |
3944 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 3977 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
3945 | if (!cmd) | 3978 | if (!cmd) |
3946 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 3979 | goto reject; |
3947 | 1, buf, conn); | ||
3948 | 3980 | ||
3949 | ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf); | 3981 | ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf); |
3950 | break; | 3982 | break; |
3951 | case ISCSI_OP_TEXT: | 3983 | case ISCSI_OP_TEXT: |
3952 | ret = iscsit_handle_text_cmd(conn, buf); | 3984 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
3985 | if (!cmd) | ||
3986 | goto reject; | ||
3987 | |||
3988 | ret = iscsit_handle_text_cmd(conn, cmd, buf); | ||
3953 | break; | 3989 | break; |
3954 | case ISCSI_OP_LOGOUT: | 3990 | case ISCSI_OP_LOGOUT: |
3955 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); | 3991 | cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); |
3956 | if (!cmd) | 3992 | if (!cmd) |
3957 | return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 3993 | goto reject; |
3958 | 1, buf, conn); | ||
3959 | 3994 | ||
3960 | ret = iscsit_handle_logout_cmd(conn, cmd, buf); | 3995 | ret = iscsit_handle_logout_cmd(conn, cmd, buf); |
3961 | if (ret > 0) | 3996 | if (ret > 0) |
@@ -3987,6 +4022,8 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) | |||
3987 | } | 4022 | } |
3988 | 4023 | ||
3989 | return ret; | 4024 | return ret; |
4025 | reject: | ||
4026 | return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); | ||
3990 | } | 4027 | } |
3991 | 4028 | ||
3992 | int iscsi_target_rx_thread(void *arg) | 4029 | int iscsi_target_rx_thread(void *arg) |
@@ -4039,11 +4076,6 @@ restart: | |||
4039 | goto transport_err; | 4076 | goto transport_err; |
4040 | } | 4077 | } |
4041 | 4078 | ||
4042 | /* | ||
4043 | * Set conn->bad_hdr for use with REJECT PDUs. | ||
4044 | */ | ||
4045 | memcpy(&conn->bad_hdr, &buffer, ISCSI_HDR_LEN); | ||
4046 | |||
4047 | if (conn->conn_ops->HeaderDigest) { | 4079 | if (conn->conn_ops->HeaderDigest) { |
4048 | iov.iov_base = &digest; | 4080 | iov.iov_base = &digest; |
4049 | iov.iov_len = ISCSI_CRC_LEN; | 4081 | iov.iov_len = ISCSI_CRC_LEN; |
@@ -4086,8 +4118,8 @@ restart: | |||
4086 | (!(opcode & ISCSI_OP_LOGOUT)))) { | 4118 | (!(opcode & ISCSI_OP_LOGOUT)))) { |
4087 | pr_err("Received illegal iSCSI Opcode: 0x%02x" | 4119 | pr_err("Received illegal iSCSI Opcode: 0x%02x" |
4088 | " while in Discovery Session, rejecting.\n", opcode); | 4120 | " while in Discovery Session, rejecting.\n", opcode); |
4089 | iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, | 4121 | iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, |
4090 | buffer, conn); | 4122 | buffer); |
4091 | goto transport_err; | 4123 | goto transport_err; |
4092 | } | 4124 | } |
4093 | 4125 | ||
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index a0050b2f294e..2c437cb8ca00 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h | |||
@@ -15,7 +15,7 @@ extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *, | |||
15 | extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, | 15 | extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, |
16 | struct iscsi_portal_group *); | 16 | struct iscsi_portal_group *); |
17 | extern int iscsit_del_np(struct iscsi_np *); | 17 | extern int iscsit_del_np(struct iscsi_np *); |
18 | extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *, struct iscsi_cmd *); | 18 | extern int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8, unsigned char *); |
19 | extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); | 19 | extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); |
20 | extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *); | 20 | extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *); |
21 | extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); | 21 | extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); |
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 8d8b3ff68490..bbfd28893164 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c | |||
@@ -20,6 +20,7 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include <linux/configfs.h> | 22 | #include <linux/configfs.h> |
23 | #include <linux/ctype.h> | ||
23 | #include <linux/export.h> | 24 | #include <linux/export.h> |
24 | #include <linux/inet.h> | 25 | #include <linux/inet.h> |
25 | #include <target/target_core_base.h> | 26 | #include <target/target_core_base.h> |
@@ -78,11 +79,12 @@ static ssize_t lio_target_np_store_sctp( | |||
78 | struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np, | 79 | struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np, |
79 | struct iscsi_tpg_np, se_tpg_np); | 80 | struct iscsi_tpg_np, se_tpg_np); |
80 | struct iscsi_tpg_np *tpg_np_sctp = NULL; | 81 | struct iscsi_tpg_np *tpg_np_sctp = NULL; |
81 | char *endptr; | ||
82 | u32 op; | 82 | u32 op; |
83 | int ret; | 83 | int ret; |
84 | 84 | ||
85 | op = simple_strtoul(page, &endptr, 0); | 85 | ret = kstrtou32(page, 0, &op); |
86 | if (ret) | ||
87 | return ret; | ||
86 | if ((op != 1) && (op != 0)) { | 88 | if ((op != 1) && (op != 0)) { |
87 | pr_err("Illegal value for tpg_enable: %u\n", op); | 89 | pr_err("Illegal value for tpg_enable: %u\n", op); |
88 | return -EINVAL; | 90 | return -EINVAL; |
@@ -382,11 +384,12 @@ static ssize_t iscsi_nacl_attrib_store_##name( \ | |||
382 | { \ | 384 | { \ |
383 | struct iscsi_node_acl *nacl = container_of(se_nacl, struct iscsi_node_acl, \ | 385 | struct iscsi_node_acl *nacl = container_of(se_nacl, struct iscsi_node_acl, \ |
384 | se_node_acl); \ | 386 | se_node_acl); \ |
385 | char *endptr; \ | ||
386 | u32 val; \ | 387 | u32 val; \ |
387 | int ret; \ | 388 | int ret; \ |
388 | \ | 389 | \ |
389 | val = simple_strtoul(page, &endptr, 0); \ | 390 | ret = kstrtou32(page, 0, &val); \ |
391 | if (ret) \ | ||
392 | return ret; \ | ||
390 | ret = iscsit_na_##name(nacl, val); \ | 393 | ret = iscsit_na_##name(nacl, val); \ |
391 | if (ret < 0) \ | 394 | if (ret < 0) \ |
392 | return ret; \ | 395 | return ret; \ |
@@ -474,7 +477,7 @@ static ssize_t __iscsi_##prefix##_store_##name( \ | |||
474 | if (!capable(CAP_SYS_ADMIN)) \ | 477 | if (!capable(CAP_SYS_ADMIN)) \ |
475 | return -EPERM; \ | 478 | return -EPERM; \ |
476 | \ | 479 | \ |
477 | snprintf(auth->name, PAGE_SIZE, "%s", page); \ | 480 | snprintf(auth->name, sizeof(auth->name), "%s", page); \ |
478 | if (!strncmp("NULL", auth->name, 4)) \ | 481 | if (!strncmp("NULL", auth->name, 4)) \ |
479 | auth->naf_flags &= ~flags; \ | 482 | auth->naf_flags &= ~flags; \ |
480 | else \ | 483 | else \ |
@@ -789,11 +792,12 @@ static ssize_t lio_target_nacl_store_cmdsn_depth( | |||
789 | struct iscsi_portal_group *tpg = container_of(se_tpg, | 792 | struct iscsi_portal_group *tpg = container_of(se_tpg, |
790 | struct iscsi_portal_group, tpg_se_tpg); | 793 | struct iscsi_portal_group, tpg_se_tpg); |
791 | struct config_item *acl_ci, *tpg_ci, *wwn_ci; | 794 | struct config_item *acl_ci, *tpg_ci, *wwn_ci; |
792 | char *endptr; | ||
793 | u32 cmdsn_depth = 0; | 795 | u32 cmdsn_depth = 0; |
794 | int ret; | 796 | int ret; |
795 | 797 | ||
796 | cmdsn_depth = simple_strtoul(page, &endptr, 0); | 798 | ret = kstrtou32(page, 0, &cmdsn_depth); |
799 | if (ret) | ||
800 | return ret; | ||
797 | if (cmdsn_depth > TA_DEFAULT_CMDSN_DEPTH_MAX) { | 801 | if (cmdsn_depth > TA_DEFAULT_CMDSN_DEPTH_MAX) { |
798 | pr_err("Passed cmdsn_depth: %u exceeds" | 802 | pr_err("Passed cmdsn_depth: %u exceeds" |
799 | " TA_DEFAULT_CMDSN_DEPTH_MAX: %u\n", cmdsn_depth, | 803 | " TA_DEFAULT_CMDSN_DEPTH_MAX: %u\n", cmdsn_depth, |
@@ -977,14 +981,15 @@ static ssize_t iscsi_tpg_attrib_store_##name( \ | |||
977 | { \ | 981 | { \ |
978 | struct iscsi_portal_group *tpg = container_of(se_tpg, \ | 982 | struct iscsi_portal_group *tpg = container_of(se_tpg, \ |
979 | struct iscsi_portal_group, tpg_se_tpg); \ | 983 | struct iscsi_portal_group, tpg_se_tpg); \ |
980 | char *endptr; \ | ||
981 | u32 val; \ | 984 | u32 val; \ |
982 | int ret; \ | 985 | int ret; \ |
983 | \ | 986 | \ |
984 | if (iscsit_get_tpg(tpg) < 0) \ | 987 | if (iscsit_get_tpg(tpg) < 0) \ |
985 | return -EINVAL; \ | 988 | return -EINVAL; \ |
986 | \ | 989 | \ |
987 | val = simple_strtoul(page, &endptr, 0); \ | 990 | ret = kstrtou32(page, 0, &val); \ |
991 | if (ret) \ | ||
992 | goto out; \ | ||
988 | ret = iscsit_ta_##name(tpg, val); \ | 993 | ret = iscsit_ta_##name(tpg, val); \ |
989 | if (ret < 0) \ | 994 | if (ret < 0) \ |
990 | goto out; \ | 995 | goto out; \ |
@@ -1053,6 +1058,131 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { | |||
1053 | 1058 | ||
1054 | /* End items for lio_target_tpg_attrib_cit */ | 1059 | /* End items for lio_target_tpg_attrib_cit */ |
1055 | 1060 | ||
1061 | /* Start items for lio_target_tpg_auth_cit */ | ||
1062 | |||
1063 | #define __DEF_TPG_AUTH_STR(prefix, name, flags) \ | ||
1064 | static ssize_t __iscsi_##prefix##_show_##name( \ | ||
1065 | struct se_portal_group *se_tpg, \ | ||
1066 | char *page) \ | ||
1067 | { \ | ||
1068 | struct iscsi_portal_group *tpg = container_of(se_tpg, \ | ||
1069 | struct iscsi_portal_group, tpg_se_tpg); \ | ||
1070 | struct iscsi_node_auth *auth = &tpg->tpg_demo_auth; \ | ||
1071 | \ | ||
1072 | if (!capable(CAP_SYS_ADMIN)) \ | ||
1073 | return -EPERM; \ | ||
1074 | \ | ||
1075 | return snprintf(page, PAGE_SIZE, "%s\n", auth->name); \ | ||
1076 | } \ | ||
1077 | \ | ||
1078 | static ssize_t __iscsi_##prefix##_store_##name( \ | ||
1079 | struct se_portal_group *se_tpg, \ | ||
1080 | const char *page, \ | ||
1081 | size_t count) \ | ||
1082 | { \ | ||
1083 | struct iscsi_portal_group *tpg = container_of(se_tpg, \ | ||
1084 | struct iscsi_portal_group, tpg_se_tpg); \ | ||
1085 | struct iscsi_node_auth *auth = &tpg->tpg_demo_auth; \ | ||
1086 | \ | ||
1087 | if (!capable(CAP_SYS_ADMIN)) \ | ||
1088 | return -EPERM; \ | ||
1089 | \ | ||
1090 | snprintf(auth->name, sizeof(auth->name), "%s", page); \ | ||
1091 | if (!(strncmp("NULL", auth->name, 4))) \ | ||
1092 | auth->naf_flags &= ~flags; \ | ||
1093 | else \ | ||
1094 | auth->naf_flags |= flags; \ | ||
1095 | \ | ||
1096 | if ((auth->naf_flags & NAF_USERID_IN_SET) && \ | ||
1097 | (auth->naf_flags & NAF_PASSWORD_IN_SET)) \ | ||
1098 | auth->authenticate_target = 1; \ | ||
1099 | else \ | ||
1100 | auth->authenticate_target = 0; \ | ||
1101 | \ | ||
1102 | return count; \ | ||
1103 | } | ||
1104 | |||
1105 | #define __DEF_TPG_AUTH_INT(prefix, name) \ | ||
1106 | static ssize_t __iscsi_##prefix##_show_##name( \ | ||
1107 | struct se_portal_group *se_tpg, \ | ||
1108 | char *page) \ | ||
1109 | { \ | ||
1110 | struct iscsi_portal_group *tpg = container_of(se_tpg, \ | ||
1111 | struct iscsi_portal_group, tpg_se_tpg); \ | ||
1112 | struct iscsi_node_auth *auth = &tpg->tpg_demo_auth; \ | ||
1113 | \ | ||
1114 | if (!capable(CAP_SYS_ADMIN)) \ | ||
1115 | return -EPERM; \ | ||
1116 | \ | ||
1117 | return snprintf(page, PAGE_SIZE, "%d\n", auth->name); \ | ||
1118 | } | ||
1119 | |||
1120 | #define DEF_TPG_AUTH_STR(name, flags) \ | ||
1121 | __DEF_TPG_AUTH_STR(tpg_auth, name, flags) \ | ||
1122 | static ssize_t iscsi_tpg_auth_show_##name( \ | ||
1123 | struct se_portal_group *se_tpg, \ | ||
1124 | char *page) \ | ||
1125 | { \ | ||
1126 | return __iscsi_tpg_auth_show_##name(se_tpg, page); \ | ||
1127 | } \ | ||
1128 | \ | ||
1129 | static ssize_t iscsi_tpg_auth_store_##name( \ | ||
1130 | struct se_portal_group *se_tpg, \ | ||
1131 | const char *page, \ | ||
1132 | size_t count) \ | ||
1133 | { \ | ||
1134 | return __iscsi_tpg_auth_store_##name(se_tpg, page, count); \ | ||
1135 | } | ||
1136 | |||
1137 | #define DEF_TPG_AUTH_INT(name) \ | ||
1138 | __DEF_TPG_AUTH_INT(tpg_auth, name) \ | ||
1139 | static ssize_t iscsi_tpg_auth_show_##name( \ | ||
1140 | struct se_portal_group *se_tpg, \ | ||
1141 | char *page) \ | ||
1142 | { \ | ||
1143 | return __iscsi_tpg_auth_show_##name(se_tpg, page); \ | ||
1144 | } | ||
1145 | |||
1146 | #define TPG_AUTH_ATTR(_name, _mode) TF_TPG_AUTH_ATTR(iscsi, _name, _mode); | ||
1147 | #define TPG_AUTH_ATTR_RO(_name) TF_TPG_AUTH_ATTR_RO(iscsi, _name); | ||
1148 | |||
1149 | /* | ||
1150 | * * One-way authentication userid | ||
1151 | * */ | ||
1152 | DEF_TPG_AUTH_STR(userid, NAF_USERID_SET); | ||
1153 | TPG_AUTH_ATTR(userid, S_IRUGO | S_IWUSR); | ||
1154 | /* | ||
1155 | * * One-way authentication password | ||
1156 | * */ | ||
1157 | DEF_TPG_AUTH_STR(password, NAF_PASSWORD_SET); | ||
1158 | TPG_AUTH_ATTR(password, S_IRUGO | S_IWUSR); | ||
1159 | /* | ||
1160 | * * Enforce mutual authentication | ||
1161 | * */ | ||
1162 | DEF_TPG_AUTH_INT(authenticate_target); | ||
1163 | TPG_AUTH_ATTR_RO(authenticate_target); | ||
1164 | /* | ||
1165 | * * Mutual authentication userid | ||
1166 | * */ | ||
1167 | DEF_TPG_AUTH_STR(userid_mutual, NAF_USERID_IN_SET); | ||
1168 | TPG_AUTH_ATTR(userid_mutual, S_IRUGO | S_IWUSR); | ||
1169 | /* | ||
1170 | * * Mutual authentication password | ||
1171 | * */ | ||
1172 | DEF_TPG_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET); | ||
1173 | TPG_AUTH_ATTR(password_mutual, S_IRUGO | S_IWUSR); | ||
1174 | |||
1175 | static struct configfs_attribute *lio_target_tpg_auth_attrs[] = { | ||
1176 | &iscsi_tpg_auth_userid.attr, | ||
1177 | &iscsi_tpg_auth_password.attr, | ||
1178 | &iscsi_tpg_auth_authenticate_target.attr, | ||
1179 | &iscsi_tpg_auth_userid_mutual.attr, | ||
1180 | &iscsi_tpg_auth_password_mutual.attr, | ||
1181 | NULL, | ||
1182 | }; | ||
1183 | |||
1184 | /* End items for lio_target_tpg_auth_cit */ | ||
1185 | |||
1056 | /* Start items for lio_target_tpg_param_cit */ | 1186 | /* Start items for lio_target_tpg_param_cit */ |
1057 | 1187 | ||
1058 | #define DEF_TPG_PARAM(name) \ | 1188 | #define DEF_TPG_PARAM(name) \ |
@@ -1087,13 +1217,14 @@ static ssize_t iscsi_tpg_param_store_##name( \ | |||
1087 | struct iscsi_portal_group *tpg = container_of(se_tpg, \ | 1217 | struct iscsi_portal_group *tpg = container_of(se_tpg, \ |
1088 | struct iscsi_portal_group, tpg_se_tpg); \ | 1218 | struct iscsi_portal_group, tpg_se_tpg); \ |
1089 | char *buf; \ | 1219 | char *buf; \ |
1090 | int ret; \ | 1220 | int ret, len; \ |
1091 | \ | 1221 | \ |
1092 | buf = kzalloc(PAGE_SIZE, GFP_KERNEL); \ | 1222 | buf = kzalloc(PAGE_SIZE, GFP_KERNEL); \ |
1093 | if (!buf) \ | 1223 | if (!buf) \ |
1094 | return -ENOMEM; \ | 1224 | return -ENOMEM; \ |
1095 | snprintf(buf, PAGE_SIZE, "%s=%s", __stringify(name), page); \ | 1225 | len = snprintf(buf, PAGE_SIZE, "%s=%s", __stringify(name), page); \ |
1096 | buf[strlen(buf)-1] = '\0'; /* Kill newline */ \ | 1226 | if (isspace(buf[len-1])) \ |
1227 | buf[len-1] = '\0'; /* Kill newline */ \ | ||
1097 | \ | 1228 | \ |
1098 | if (iscsit_get_tpg(tpg) < 0) { \ | 1229 | if (iscsit_get_tpg(tpg) < 0) { \ |
1099 | kfree(buf); \ | 1230 | kfree(buf); \ |
@@ -1230,11 +1361,12 @@ static ssize_t lio_target_tpg_store_enable( | |||
1230 | { | 1361 | { |
1231 | struct iscsi_portal_group *tpg = container_of(se_tpg, | 1362 | struct iscsi_portal_group *tpg = container_of(se_tpg, |
1232 | struct iscsi_portal_group, tpg_se_tpg); | 1363 | struct iscsi_portal_group, tpg_se_tpg); |
1233 | char *endptr; | ||
1234 | u32 op; | 1364 | u32 op; |
1235 | int ret = 0; | 1365 | int ret; |
1236 | 1366 | ||
1237 | op = simple_strtoul(page, &endptr, 0); | 1367 | ret = kstrtou32(page, 0, &op); |
1368 | if (ret) | ||
1369 | return ret; | ||
1238 | if ((op != 1) && (op != 0)) { | 1370 | if ((op != 1) && (op != 0)) { |
1239 | pr_err("Illegal value for tpg_enable: %u\n", op); | 1371 | pr_err("Illegal value for tpg_enable: %u\n", op); |
1240 | return -EINVAL; | 1372 | return -EINVAL; |
@@ -1282,15 +1414,15 @@ static struct se_portal_group *lio_target_tiqn_addtpg( | |||
1282 | { | 1414 | { |
1283 | struct iscsi_portal_group *tpg; | 1415 | struct iscsi_portal_group *tpg; |
1284 | struct iscsi_tiqn *tiqn; | 1416 | struct iscsi_tiqn *tiqn; |
1285 | char *tpgt_str, *end_ptr; | 1417 | char *tpgt_str; |
1286 | int ret = 0; | 1418 | int ret; |
1287 | unsigned short int tpgt; | 1419 | u16 tpgt; |
1288 | 1420 | ||
1289 | tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn); | 1421 | tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn); |
1290 | /* | 1422 | /* |
1291 | * Only tpgt_# directory groups can be created below | 1423 | * Only tpgt_# directory groups can be created below |
1292 | * target/iscsi/iqn.superturodiskarry/ | 1424 | * target/iscsi/iqn.superturodiskarry/ |
1293 | */ | 1425 | */ |
1294 | tpgt_str = strstr(name, "tpgt_"); | 1426 | tpgt_str = strstr(name, "tpgt_"); |
1295 | if (!tpgt_str) { | 1427 | if (!tpgt_str) { |
1296 | pr_err("Unable to locate \"tpgt_#\" directory" | 1428 | pr_err("Unable to locate \"tpgt_#\" directory" |
@@ -1298,7 +1430,9 @@ static struct se_portal_group *lio_target_tiqn_addtpg( | |||
1298 | return NULL; | 1430 | return NULL; |
1299 | } | 1431 | } |
1300 | tpgt_str += 5; /* Skip ahead of "tpgt_" */ | 1432 | tpgt_str += 5; /* Skip ahead of "tpgt_" */ |
1301 | tpgt = (unsigned short int) simple_strtoul(tpgt_str, &end_ptr, 0); | 1433 | ret = kstrtou16(tpgt_str, 0, &tpgt); |
1434 | if (ret) | ||
1435 | return NULL; | ||
1302 | 1436 | ||
1303 | tpg = iscsit_alloc_portal_group(tiqn, tpgt); | 1437 | tpg = iscsit_alloc_portal_group(tiqn, tpgt); |
1304 | if (!tpg) | 1438 | if (!tpg) |
@@ -1506,10 +1640,12 @@ static ssize_t iscsi_disc_store_enforce_discovery_auth( | |||
1506 | { | 1640 | { |
1507 | struct iscsi_param *param; | 1641 | struct iscsi_param *param; |
1508 | struct iscsi_portal_group *discovery_tpg = iscsit_global->discovery_tpg; | 1642 | struct iscsi_portal_group *discovery_tpg = iscsit_global->discovery_tpg; |
1509 | char *endptr; | ||
1510 | u32 op; | 1643 | u32 op; |
1644 | int err; | ||
1511 | 1645 | ||
1512 | op = simple_strtoul(page, &endptr, 0); | 1646 | err = kstrtou32(page, 0, &op); |
1647 | if (err) | ||
1648 | return -EINVAL; | ||
1513 | if ((op != 1) && (op != 0)) { | 1649 | if ((op != 1) && (op != 0)) { |
1514 | pr_err("Illegal value for enforce_discovery_auth:" | 1650 | pr_err("Illegal value for enforce_discovery_auth:" |
1515 | " %u\n", op); | 1651 | " %u\n", op); |
@@ -1655,13 +1791,12 @@ static int lio_queue_status(struct se_cmd *se_cmd) | |||
1655 | return 0; | 1791 | return 0; |
1656 | } | 1792 | } |
1657 | 1793 | ||
1658 | static int lio_queue_tm_rsp(struct se_cmd *se_cmd) | 1794 | static void lio_queue_tm_rsp(struct se_cmd *se_cmd) |
1659 | { | 1795 | { |
1660 | struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); | 1796 | struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); |
1661 | 1797 | ||
1662 | cmd->i_state = ISTATE_SEND_TASKMGTRSP; | 1798 | cmd->i_state = ISTATE_SEND_TASKMGTRSP; |
1663 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); | 1799 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); |
1664 | return 0; | ||
1665 | } | 1800 | } |
1666 | 1801 | ||
1667 | static char *lio_tpg_get_endpoint_wwn(struct se_portal_group *se_tpg) | 1802 | static char *lio_tpg_get_endpoint_wwn(struct se_portal_group *se_tpg) |
@@ -1866,6 +2001,7 @@ int iscsi_target_register_configfs(void) | |||
1866 | TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = lio_target_wwn_attrs; | 2001 | TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = lio_target_wwn_attrs; |
1867 | TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = lio_target_tpg_attrs; | 2002 | TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = lio_target_tpg_attrs; |
1868 | TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = lio_target_tpg_attrib_attrs; | 2003 | TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = lio_target_tpg_attrib_attrs; |
2004 | TF_CIT_TMPL(fabric)->tfc_tpg_auth_cit.ct_attrs = lio_target_tpg_auth_attrs; | ||
1869 | TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = lio_target_tpg_param_attrs; | 2005 | TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = lio_target_tpg_param_attrs; |
1870 | TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = lio_target_portal_attrs; | 2006 | TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = lio_target_portal_attrs; |
1871 | TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = lio_target_initiator_attrs; | 2007 | TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = lio_target_initiator_attrs; |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 60ec4b92be03..4f77a78edef9 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -132,7 +132,8 @@ enum cmd_flags_table { | |||
132 | ICF_CONTIG_MEMORY = 0x00000020, | 132 | ICF_CONTIG_MEMORY = 0x00000020, |
133 | ICF_ATTACHED_TO_RQUEUE = 0x00000040, | 133 | ICF_ATTACHED_TO_RQUEUE = 0x00000040, |
134 | ICF_OOO_CMDSN = 0x00000080, | 134 | ICF_OOO_CMDSN = 0x00000080, |
135 | ICF_REJECT_FAIL_CONN = 0x00000100, | 135 | IFC_SENDTARGETS_ALL = 0x00000100, |
136 | IFC_SENDTARGETS_SINGLE = 0x00000200, | ||
136 | }; | 137 | }; |
137 | 138 | ||
138 | /* struct iscsi_cmd->i_state */ | 139 | /* struct iscsi_cmd->i_state */ |
@@ -366,6 +367,8 @@ struct iscsi_cmd { | |||
366 | u8 maxcmdsn_inc; | 367 | u8 maxcmdsn_inc; |
367 | /* Immediate Unsolicited Dataout */ | 368 | /* Immediate Unsolicited Dataout */ |
368 | u8 unsolicited_data; | 369 | u8 unsolicited_data; |
370 | /* Reject reason code */ | ||
371 | u8 reject_reason; | ||
369 | /* CID contained in logout PDU when opcode == ISCSI_INIT_LOGOUT_CMND */ | 372 | /* CID contained in logout PDU when opcode == ISCSI_INIT_LOGOUT_CMND */ |
370 | u16 logout_cid; | 373 | u16 logout_cid; |
371 | /* Command flags */ | 374 | /* Command flags */ |
@@ -427,6 +430,8 @@ struct iscsi_cmd { | |||
427 | u32 tx_size; | 430 | u32 tx_size; |
428 | /* Buffer used for various purposes */ | 431 | /* Buffer used for various purposes */ |
429 | void *buf_ptr; | 432 | void *buf_ptr; |
433 | /* Used by SendTargets=[iqn.,eui.] discovery */ | ||
434 | void *text_in_ptr; | ||
430 | /* See include/linux/dma-mapping.h */ | 435 | /* See include/linux/dma-mapping.h */ |
431 | enum dma_data_direction data_direction; | 436 | enum dma_data_direction data_direction; |
432 | /* iSCSI PDU Header + CRC */ | 437 | /* iSCSI PDU Header + CRC */ |
@@ -446,7 +451,6 @@ struct iscsi_cmd { | |||
446 | struct list_head datain_list; | 451 | struct list_head datain_list; |
447 | /* R2T List */ | 452 | /* R2T List */ |
448 | struct list_head cmd_r2t_list; | 453 | struct list_head cmd_r2t_list; |
449 | struct completion reject_comp; | ||
450 | /* Timer for DataOUT */ | 454 | /* Timer for DataOUT */ |
451 | struct timer_list dataout_timer; | 455 | struct timer_list dataout_timer; |
452 | /* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */ | 456 | /* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */ |
@@ -528,8 +532,6 @@ struct iscsi_conn { | |||
528 | u32 of_marker; | 532 | u32 of_marker; |
529 | /* Used for calculating OFMarker offset to next PDU */ | 533 | /* Used for calculating OFMarker offset to next PDU */ |
530 | u32 of_marker_offset; | 534 | u32 of_marker_offset; |
531 | /* Complete Bad PDU for sending reject */ | ||
532 | unsigned char bad_hdr[ISCSI_HDR_LEN]; | ||
533 | #define IPV6_ADDRESS_SPACE 48 | 535 | #define IPV6_ADDRESS_SPACE 48 |
534 | unsigned char login_ip[IPV6_ADDRESS_SPACE]; | 536 | unsigned char login_ip[IPV6_ADDRESS_SPACE]; |
535 | unsigned char local_ip[IPV6_ADDRESS_SPACE]; | 537 | unsigned char local_ip[IPV6_ADDRESS_SPACE]; |
@@ -809,6 +811,7 @@ struct iscsi_portal_group { | |||
809 | struct mutex tpg_access_lock; | 811 | struct mutex tpg_access_lock; |
810 | struct mutex np_login_lock; | 812 | struct mutex np_login_lock; |
811 | struct iscsi_tpg_attrib tpg_attrib; | 813 | struct iscsi_tpg_attrib tpg_attrib; |
814 | struct iscsi_node_auth tpg_demo_auth; | ||
812 | /* Pointer to default list of iSCSI parameters for TPG */ | 815 | /* Pointer to default list of iSCSI parameters for TPG */ |
813 | struct iscsi_param_list *param_list; | 816 | struct iscsi_param_list *param_list; |
814 | struct iscsi_tiqn *tpg_tiqn; | 817 | struct iscsi_tiqn *tpg_tiqn; |
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index dcb199da06b9..08bd87833321 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c | |||
@@ -746,13 +746,12 @@ int iscsit_check_post_dataout( | |||
746 | if (!conn->sess->sess_ops->ErrorRecoveryLevel) { | 746 | if (!conn->sess->sess_ops->ErrorRecoveryLevel) { |
747 | pr_err("Unable to recover from DataOUT CRC" | 747 | pr_err("Unable to recover from DataOUT CRC" |
748 | " failure while ERL=0, closing session.\n"); | 748 | " failure while ERL=0, closing session.\n"); |
749 | iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR, | 749 | iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, |
750 | 1, 0, buf, cmd); | 750 | buf); |
751 | return DATAOUT_CANNOT_RECOVER; | 751 | return DATAOUT_CANNOT_RECOVER; |
752 | } | 752 | } |
753 | 753 | ||
754 | iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR, | 754 | iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, buf); |
755 | 0, 0, buf, cmd); | ||
756 | return iscsit_dataout_post_crc_failed(cmd, buf); | 755 | return iscsit_dataout_post_crc_failed(cmd, buf); |
757 | } | 756 | } |
758 | } | 757 | } |
@@ -909,6 +908,7 @@ void iscsit_cause_connection_reinstatement(struct iscsi_conn *conn, int sleep) | |||
909 | wait_for_completion(&conn->conn_wait_comp); | 908 | wait_for_completion(&conn->conn_wait_comp); |
910 | complete(&conn->conn_post_wait_comp); | 909 | complete(&conn->conn_post_wait_comp); |
911 | } | 910 | } |
911 | EXPORT_SYMBOL(iscsit_cause_connection_reinstatement); | ||
912 | 912 | ||
913 | void iscsit_fall_back_to_erl0(struct iscsi_session *sess) | 913 | void iscsit_fall_back_to_erl0(struct iscsi_session *sess) |
914 | { | 914 | { |
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index 40d9dbca987b..586c268679a4 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c | |||
@@ -162,9 +162,8 @@ static int iscsit_handle_r2t_snack( | |||
162 | " protocol error.\n", cmd->init_task_tag, begrun, | 162 | " protocol error.\n", cmd->init_task_tag, begrun, |
163 | (begrun + runlength), cmd->acked_data_sn); | 163 | (begrun + runlength), cmd->acked_data_sn); |
164 | 164 | ||
165 | return iscsit_add_reject_from_cmd( | 165 | return iscsit_reject_cmd(cmd, |
166 | ISCSI_REASON_PROTOCOL_ERROR, | 166 | ISCSI_REASON_PROTOCOL_ERROR, buf); |
167 | 1, 0, buf, cmd); | ||
168 | } | 167 | } |
169 | 168 | ||
170 | if (runlength) { | 169 | if (runlength) { |
@@ -173,8 +172,8 @@ static int iscsit_handle_r2t_snack( | |||
173 | " with BegRun: 0x%08x, RunLength: 0x%08x, exceeds" | 172 | " with BegRun: 0x%08x, RunLength: 0x%08x, exceeds" |
174 | " current R2TSN: 0x%08x, protocol error.\n", | 173 | " current R2TSN: 0x%08x, protocol error.\n", |
175 | cmd->init_task_tag, begrun, runlength, cmd->r2t_sn); | 174 | cmd->init_task_tag, begrun, runlength, cmd->r2t_sn); |
176 | return iscsit_add_reject_from_cmd( | 175 | return iscsit_reject_cmd(cmd, |
177 | ISCSI_REASON_BOOKMARK_INVALID, 1, 0, buf, cmd); | 176 | ISCSI_REASON_BOOKMARK_INVALID, buf); |
178 | } | 177 | } |
179 | last_r2tsn = (begrun + runlength); | 178 | last_r2tsn = (begrun + runlength); |
180 | } else | 179 | } else |
@@ -433,8 +432,7 @@ static int iscsit_handle_recovery_datain( | |||
433 | " protocol error.\n", cmd->init_task_tag, begrun, | 432 | " protocol error.\n", cmd->init_task_tag, begrun, |
434 | (begrun + runlength), cmd->acked_data_sn); | 433 | (begrun + runlength), cmd->acked_data_sn); |
435 | 434 | ||
436 | return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, | 435 | return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf); |
437 | 1, 0, buf, cmd); | ||
438 | } | 436 | } |
439 | 437 | ||
440 | /* | 438 | /* |
@@ -445,14 +443,14 @@ static int iscsit_handle_recovery_datain( | |||
445 | pr_err("Initiator requesting BegRun: 0x%08x, RunLength" | 443 | pr_err("Initiator requesting BegRun: 0x%08x, RunLength" |
446 | ": 0x%08x greater than maximum DataSN: 0x%08x.\n", | 444 | ": 0x%08x greater than maximum DataSN: 0x%08x.\n", |
447 | begrun, runlength, (cmd->data_sn - 1)); | 445 | begrun, runlength, (cmd->data_sn - 1)); |
448 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, | 446 | return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID, |
449 | 1, 0, buf, cmd); | 447 | buf); |
450 | } | 448 | } |
451 | 449 | ||
452 | dr = iscsit_allocate_datain_req(); | 450 | dr = iscsit_allocate_datain_req(); |
453 | if (!dr) | 451 | if (!dr) |
454 | return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 452 | return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
455 | 1, 0, buf, cmd); | 453 | buf); |
456 | 454 | ||
457 | dr->data_sn = dr->begrun = begrun; | 455 | dr->data_sn = dr->begrun = begrun; |
458 | dr->runlength = runlength; | 456 | dr->runlength = runlength; |
@@ -1090,7 +1088,7 @@ int iscsit_handle_ooo_cmdsn( | |||
1090 | 1088 | ||
1091 | ooo_cmdsn = iscsit_allocate_ooo_cmdsn(); | 1089 | ooo_cmdsn = iscsit_allocate_ooo_cmdsn(); |
1092 | if (!ooo_cmdsn) | 1090 | if (!ooo_cmdsn) |
1093 | return CMDSN_ERROR_CANNOT_RECOVER; | 1091 | return -ENOMEM; |
1094 | 1092 | ||
1095 | ooo_cmdsn->cmd = cmd; | 1093 | ooo_cmdsn->cmd = cmd; |
1096 | ooo_cmdsn->batch_count = (batch) ? | 1094 | ooo_cmdsn->batch_count = (batch) ? |
@@ -1101,10 +1099,10 @@ int iscsit_handle_ooo_cmdsn( | |||
1101 | 1099 | ||
1102 | if (iscsit_attach_ooo_cmdsn(sess, ooo_cmdsn) < 0) { | 1100 | if (iscsit_attach_ooo_cmdsn(sess, ooo_cmdsn) < 0) { |
1103 | kmem_cache_free(lio_ooo_cache, ooo_cmdsn); | 1101 | kmem_cache_free(lio_ooo_cache, ooo_cmdsn); |
1104 | return CMDSN_ERROR_CANNOT_RECOVER; | 1102 | return -ENOMEM; |
1105 | } | 1103 | } |
1106 | 1104 | ||
1107 | return CMDSN_HIGHER_THAN_EXP; | 1105 | return 0; |
1108 | } | 1106 | } |
1109 | 1107 | ||
1110 | static int iscsit_set_dataout_timeout_values( | 1108 | static int iscsit_set_dataout_timeout_values( |
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index cd5018ff9cd7..c4675b4ceb49 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c | |||
@@ -112,6 +112,7 @@ static u32 iscsi_handle_authentication( | |||
112 | struct iscsi_session *sess = conn->sess; | 112 | struct iscsi_session *sess = conn->sess; |
113 | struct iscsi_node_auth *auth; | 113 | struct iscsi_node_auth *auth; |
114 | struct iscsi_node_acl *iscsi_nacl; | 114 | struct iscsi_node_acl *iscsi_nacl; |
115 | struct iscsi_portal_group *iscsi_tpg; | ||
115 | struct se_node_acl *se_nacl; | 116 | struct se_node_acl *se_nacl; |
116 | 117 | ||
117 | if (!sess->sess_ops->SessionType) { | 118 | if (!sess->sess_ops->SessionType) { |
@@ -132,7 +133,17 @@ static u32 iscsi_handle_authentication( | |||
132 | return -1; | 133 | return -1; |
133 | } | 134 | } |
134 | 135 | ||
135 | auth = ISCSI_NODE_AUTH(iscsi_nacl); | 136 | if (se_nacl->dynamic_node_acl) { |
137 | iscsi_tpg = container_of(se_nacl->se_tpg, | ||
138 | struct iscsi_portal_group, tpg_se_tpg); | ||
139 | |||
140 | auth = &iscsi_tpg->tpg_demo_auth; | ||
141 | } else { | ||
142 | iscsi_nacl = container_of(se_nacl, struct iscsi_node_acl, | ||
143 | se_node_acl); | ||
144 | |||
145 | auth = ISCSI_NODE_AUTH(iscsi_nacl); | ||
146 | } | ||
136 | } else { | 147 | } else { |
137 | /* | 148 | /* |
138 | * For SessionType=Discovery | 149 | * For SessionType=Discovery |
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index e38222191a33..35fd6439eb01 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c | |||
@@ -1799,9 +1799,6 @@ void iscsi_set_connection_parameters( | |||
1799 | * this key is not sent over the wire. | 1799 | * this key is not sent over the wire. |
1800 | */ | 1800 | */ |
1801 | if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) { | 1801 | if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) { |
1802 | if (param_list->iser == true) | ||
1803 | continue; | ||
1804 | |||
1805 | ops->MaxXmitDataSegmentLength = | 1802 | ops->MaxXmitDataSegmentLength = |
1806 | simple_strtoul(param->value, &tmpptr, 0); | 1803 | simple_strtoul(param->value, &tmpptr, 0); |
1807 | pr_debug("MaxXmitDataSegmentLength: %s\n", | 1804 | pr_debug("MaxXmitDataSegmentLength: %s\n", |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 08a3bacef0c5..1df06d5e4e01 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -178,7 +178,6 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask) | |||
178 | INIT_LIST_HEAD(&cmd->i_conn_node); | 178 | INIT_LIST_HEAD(&cmd->i_conn_node); |
179 | INIT_LIST_HEAD(&cmd->datain_list); | 179 | INIT_LIST_HEAD(&cmd->datain_list); |
180 | INIT_LIST_HEAD(&cmd->cmd_r2t_list); | 180 | INIT_LIST_HEAD(&cmd->cmd_r2t_list); |
181 | init_completion(&cmd->reject_comp); | ||
182 | spin_lock_init(&cmd->datain_lock); | 181 | spin_lock_init(&cmd->datain_lock); |
183 | spin_lock_init(&cmd->dataout_timeout_lock); | 182 | spin_lock_init(&cmd->dataout_timeout_lock); |
184 | spin_lock_init(&cmd->istate_lock); | 183 | spin_lock_init(&cmd->istate_lock); |
@@ -284,13 +283,12 @@ static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cm | |||
284 | * Commands may be received out of order if MC/S is in use. | 283 | * Commands may be received out of order if MC/S is in use. |
285 | * Ensure they are executed in CmdSN order. | 284 | * Ensure they are executed in CmdSN order. |
286 | */ | 285 | */ |
287 | int iscsit_sequence_cmd( | 286 | int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, |
288 | struct iscsi_conn *conn, | 287 | unsigned char *buf, __be32 cmdsn) |
289 | struct iscsi_cmd *cmd, | ||
290 | __be32 cmdsn) | ||
291 | { | 288 | { |
292 | int ret; | 289 | int ret, cmdsn_ret; |
293 | int cmdsn_ret; | 290 | bool reject = false; |
291 | u8 reason = ISCSI_REASON_BOOKMARK_NO_RESOURCES; | ||
294 | 292 | ||
295 | mutex_lock(&conn->sess->cmdsn_mutex); | 293 | mutex_lock(&conn->sess->cmdsn_mutex); |
296 | 294 | ||
@@ -300,9 +298,19 @@ int iscsit_sequence_cmd( | |||
300 | ret = iscsit_execute_cmd(cmd, 0); | 298 | ret = iscsit_execute_cmd(cmd, 0); |
301 | if ((ret >= 0) && !list_empty(&conn->sess->sess_ooo_cmdsn_list)) | 299 | if ((ret >= 0) && !list_empty(&conn->sess->sess_ooo_cmdsn_list)) |
302 | iscsit_execute_ooo_cmdsns(conn->sess); | 300 | iscsit_execute_ooo_cmdsns(conn->sess); |
301 | else if (ret < 0) { | ||
302 | reject = true; | ||
303 | ret = CMDSN_ERROR_CANNOT_RECOVER; | ||
304 | } | ||
303 | break; | 305 | break; |
304 | case CMDSN_HIGHER_THAN_EXP: | 306 | case CMDSN_HIGHER_THAN_EXP: |
305 | ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, be32_to_cpu(cmdsn)); | 307 | ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, be32_to_cpu(cmdsn)); |
308 | if (ret < 0) { | ||
309 | reject = true; | ||
310 | ret = CMDSN_ERROR_CANNOT_RECOVER; | ||
311 | break; | ||
312 | } | ||
313 | ret = CMDSN_HIGHER_THAN_EXP; | ||
306 | break; | 314 | break; |
307 | case CMDSN_LOWER_THAN_EXP: | 315 | case CMDSN_LOWER_THAN_EXP: |
308 | cmd->i_state = ISTATE_REMOVE; | 316 | cmd->i_state = ISTATE_REMOVE; |
@@ -310,11 +318,16 @@ int iscsit_sequence_cmd( | |||
310 | ret = cmdsn_ret; | 318 | ret = cmdsn_ret; |
311 | break; | 319 | break; |
312 | default: | 320 | default: |
321 | reason = ISCSI_REASON_PROTOCOL_ERROR; | ||
322 | reject = true; | ||
313 | ret = cmdsn_ret; | 323 | ret = cmdsn_ret; |
314 | break; | 324 | break; |
315 | } | 325 | } |
316 | mutex_unlock(&conn->sess->cmdsn_mutex); | 326 | mutex_unlock(&conn->sess->cmdsn_mutex); |
317 | 327 | ||
328 | if (reject) | ||
329 | iscsit_reject_cmd(cmd, reason, buf); | ||
330 | |||
318 | return ret; | 331 | return ret; |
319 | } | 332 | } |
320 | EXPORT_SYMBOL(iscsit_sequence_cmd); | 333 | EXPORT_SYMBOL(iscsit_sequence_cmd); |
@@ -681,6 +694,7 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd) | |||
681 | kfree(cmd->seq_list); | 694 | kfree(cmd->seq_list); |
682 | kfree(cmd->tmr_req); | 695 | kfree(cmd->tmr_req); |
683 | kfree(cmd->iov_data); | 696 | kfree(cmd->iov_data); |
697 | kfree(cmd->text_in_ptr); | ||
684 | 698 | ||
685 | kmem_cache_free(lio_cmd_cache, cmd); | 699 | kmem_cache_free(lio_cmd_cache, cmd); |
686 | } | 700 | } |
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index a4422659d049..e4fc34a02f57 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h | |||
@@ -13,7 +13,8 @@ extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t); | |||
13 | extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32); | 13 | extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32); |
14 | extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *); | 14 | extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *); |
15 | extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32); | 15 | extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32); |
16 | int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, __be32 cmdsn); | 16 | extern int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, |
17 | unsigned char * ,__be32 cmdsn); | ||
17 | extern int iscsit_check_unsolicited_dataout(struct iscsi_cmd *, unsigned char *); | 18 | extern int iscsit_check_unsolicited_dataout(struct iscsi_cmd *, unsigned char *); |
18 | extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t); | 19 | extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t); |
19 | extern struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *, | 20 | extern struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *, |
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 7c908141cc8a..568ad25f25d3 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c | |||
@@ -786,7 +786,7 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd) | |||
786 | return 0; | 786 | return 0; |
787 | } | 787 | } |
788 | 788 | ||
789 | static int tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd) | 789 | static void tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd) |
790 | { | 790 | { |
791 | struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; | 791 | struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; |
792 | struct tcm_loop_tmr *tl_tmr = se_tmr->fabric_tmr_ptr; | 792 | struct tcm_loop_tmr *tl_tmr = se_tmr->fabric_tmr_ptr; |
@@ -796,7 +796,6 @@ static int tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd) | |||
796 | */ | 796 | */ |
797 | atomic_set(&tl_tmr->tmr_complete, 1); | 797 | atomic_set(&tl_tmr->tmr_complete, 1); |
798 | wake_up(&tl_tmr->tl_tmr_wait); | 798 | wake_up(&tl_tmr->tl_tmr_wait); |
799 | return 0; | ||
800 | } | 799 | } |
801 | 800 | ||
802 | static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba) | 801 | static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba) |
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index d3536f57444f..e51b09a04d52 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c | |||
@@ -1842,9 +1842,8 @@ static int sbp_queue_status(struct se_cmd *se_cmd) | |||
1842 | return sbp_send_sense(req); | 1842 | return sbp_send_sense(req); |
1843 | } | 1843 | } |
1844 | 1844 | ||
1845 | static int sbp_queue_tm_rsp(struct se_cmd *se_cmd) | 1845 | static void sbp_queue_tm_rsp(struct se_cmd *se_cmd) |
1846 | { | 1846 | { |
1847 | return 0; | ||
1848 | } | 1847 | } |
1849 | 1848 | ||
1850 | static int sbp_check_stop_free(struct se_cmd *se_cmd) | 1849 | static int sbp_check_stop_free(struct se_cmd *se_cmd) |
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 4a8bd36d3958..e4d22933efaf 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -983,7 +983,6 @@ static ssize_t target_core_dev_pr_show_spc3_res(struct se_device *dev, | |||
983 | struct se_node_acl *se_nacl; | 983 | struct se_node_acl *se_nacl; |
984 | struct t10_pr_registration *pr_reg; | 984 | struct t10_pr_registration *pr_reg; |
985 | char i_buf[PR_REG_ISID_ID_LEN]; | 985 | char i_buf[PR_REG_ISID_ID_LEN]; |
986 | int prf_isid; | ||
987 | 986 | ||
988 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 987 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
989 | 988 | ||
@@ -992,12 +991,11 @@ static ssize_t target_core_dev_pr_show_spc3_res(struct se_device *dev, | |||
992 | return sprintf(page, "No SPC-3 Reservation holder\n"); | 991 | return sprintf(page, "No SPC-3 Reservation holder\n"); |
993 | 992 | ||
994 | se_nacl = pr_reg->pr_reg_nacl; | 993 | se_nacl = pr_reg->pr_reg_nacl; |
995 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], | 994 | core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); |
996 | PR_REG_ISID_ID_LEN); | ||
997 | 995 | ||
998 | return sprintf(page, "SPC-3 Reservation: %s Initiator: %s%s\n", | 996 | return sprintf(page, "SPC-3 Reservation: %s Initiator: %s%s\n", |
999 | se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(), | 997 | se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(), |
1000 | se_nacl->initiatorname, (prf_isid) ? &i_buf[0] : ""); | 998 | se_nacl->initiatorname, i_buf); |
1001 | } | 999 | } |
1002 | 1000 | ||
1003 | static ssize_t target_core_dev_pr_show_spc2_res(struct se_device *dev, | 1001 | static ssize_t target_core_dev_pr_show_spc2_res(struct se_device *dev, |
@@ -1116,7 +1114,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts( | |||
1116 | unsigned char buf[384]; | 1114 | unsigned char buf[384]; |
1117 | char i_buf[PR_REG_ISID_ID_LEN]; | 1115 | char i_buf[PR_REG_ISID_ID_LEN]; |
1118 | ssize_t len = 0; | 1116 | ssize_t len = 0; |
1119 | int reg_count = 0, prf_isid; | 1117 | int reg_count = 0; |
1120 | 1118 | ||
1121 | len += sprintf(page+len, "SPC-3 PR Registrations:\n"); | 1119 | len += sprintf(page+len, "SPC-3 PR Registrations:\n"); |
1122 | 1120 | ||
@@ -1127,12 +1125,11 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts( | |||
1127 | memset(buf, 0, 384); | 1125 | memset(buf, 0, 384); |
1128 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 1126 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
1129 | tfo = pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo; | 1127 | tfo = pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo; |
1130 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], | 1128 | core_pr_dump_initiator_port(pr_reg, i_buf, |
1131 | PR_REG_ISID_ID_LEN); | 1129 | PR_REG_ISID_ID_LEN); |
1132 | sprintf(buf, "%s Node: %s%s Key: 0x%016Lx PRgen: 0x%08x\n", | 1130 | sprintf(buf, "%s Node: %s%s Key: 0x%016Lx PRgen: 0x%08x\n", |
1133 | tfo->get_fabric_name(), | 1131 | tfo->get_fabric_name(), |
1134 | pr_reg->pr_reg_nacl->initiatorname, (prf_isid) ? | 1132 | pr_reg->pr_reg_nacl->initiatorname, i_buf, pr_reg->pr_res_key, |
1135 | &i_buf[0] : "", pr_reg->pr_res_key, | ||
1136 | pr_reg->pr_res_generation); | 1133 | pr_reg->pr_res_generation); |
1137 | 1134 | ||
1138 | if (len + strlen(buf) >= PAGE_SIZE) | 1135 | if (len + strlen(buf) >= PAGE_SIZE) |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 4630481b6043..8f4142fe5f19 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -1410,7 +1410,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) | |||
1410 | INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list); | 1410 | INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list); |
1411 | spin_lock_init(&dev->t10_alua.tg_pt_gps_lock); | 1411 | spin_lock_init(&dev->t10_alua.tg_pt_gps_lock); |
1412 | 1412 | ||
1413 | dev->t10_pr.pr_aptpl_buf_len = PR_APTPL_BUF_LEN; | ||
1414 | dev->t10_wwn.t10_dev = dev; | 1413 | dev->t10_wwn.t10_dev = dev; |
1415 | dev->t10_alua.t10_dev = dev; | 1414 | dev->t10_alua.t10_dev = dev; |
1416 | 1415 | ||
@@ -1545,7 +1544,7 @@ int core_dev_setup_virtual_lun0(void) | |||
1545 | { | 1544 | { |
1546 | struct se_hba *hba; | 1545 | struct se_hba *hba; |
1547 | struct se_device *dev; | 1546 | struct se_device *dev; |
1548 | char buf[16]; | 1547 | char buf[] = "rd_pages=8,rd_nullio=1"; |
1549 | int ret; | 1548 | int ret; |
1550 | 1549 | ||
1551 | hba = core_alloc_hba("rd_mcp", 0, HBA_FLAGS_INTERNAL_USE); | 1550 | hba = core_alloc_hba("rd_mcp", 0, HBA_FLAGS_INTERNAL_USE); |
@@ -1558,8 +1557,6 @@ int core_dev_setup_virtual_lun0(void) | |||
1558 | goto out_free_hba; | 1557 | goto out_free_hba; |
1559 | } | 1558 | } |
1560 | 1559 | ||
1561 | memset(buf, 0, 16); | ||
1562 | sprintf(buf, "rd_pages=8"); | ||
1563 | hba->transport->set_configfs_dev_params(dev, buf, sizeof(buf)); | 1560 | hba->transport->set_configfs_dev_params(dev, buf, sizeof(buf)); |
1564 | 1561 | ||
1565 | ret = target_configure_device(dev); | 1562 | ret = target_configure_device(dev); |
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 04c775cb3e65..eb56eb129563 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c | |||
@@ -965,6 +965,19 @@ TF_CIT_SETUP(tpg_attrib, &target_fabric_tpg_attrib_item_ops, NULL, NULL); | |||
965 | 965 | ||
966 | /* End of tfc_tpg_attrib_cit */ | 966 | /* End of tfc_tpg_attrib_cit */ |
967 | 967 | ||
968 | /* Start of tfc_tpg_auth_cit */ | ||
969 | |||
970 | CONFIGFS_EATTR_OPS(target_fabric_tpg_auth, se_portal_group, tpg_auth_group); | ||
971 | |||
972 | static struct configfs_item_operations target_fabric_tpg_auth_item_ops = { | ||
973 | .show_attribute = target_fabric_tpg_auth_attr_show, | ||
974 | .store_attribute = target_fabric_tpg_auth_attr_store, | ||
975 | }; | ||
976 | |||
977 | TF_CIT_SETUP(tpg_auth, &target_fabric_tpg_auth_item_ops, NULL, NULL); | ||
978 | |||
979 | /* End of tfc_tpg_attrib_cit */ | ||
980 | |||
968 | /* Start of tfc_tpg_param_cit */ | 981 | /* Start of tfc_tpg_param_cit */ |
969 | 982 | ||
970 | CONFIGFS_EATTR_OPS(target_fabric_tpg_param, se_portal_group, tpg_param_group); | 983 | CONFIGFS_EATTR_OPS(target_fabric_tpg_param, se_portal_group, tpg_param_group); |
@@ -1030,8 +1043,9 @@ static struct config_group *target_fabric_make_tpg( | |||
1030 | se_tpg->tpg_group.default_groups[1] = &se_tpg->tpg_np_group; | 1043 | se_tpg->tpg_group.default_groups[1] = &se_tpg->tpg_np_group; |
1031 | se_tpg->tpg_group.default_groups[2] = &se_tpg->tpg_acl_group; | 1044 | se_tpg->tpg_group.default_groups[2] = &se_tpg->tpg_acl_group; |
1032 | se_tpg->tpg_group.default_groups[3] = &se_tpg->tpg_attrib_group; | 1045 | se_tpg->tpg_group.default_groups[3] = &se_tpg->tpg_attrib_group; |
1033 | se_tpg->tpg_group.default_groups[4] = &se_tpg->tpg_param_group; | 1046 | se_tpg->tpg_group.default_groups[4] = &se_tpg->tpg_auth_group; |
1034 | se_tpg->tpg_group.default_groups[5] = NULL; | 1047 | se_tpg->tpg_group.default_groups[5] = &se_tpg->tpg_param_group; |
1048 | se_tpg->tpg_group.default_groups[6] = NULL; | ||
1035 | 1049 | ||
1036 | config_group_init_type_name(&se_tpg->tpg_group, name, | 1050 | config_group_init_type_name(&se_tpg->tpg_group, name, |
1037 | &TF_CIT_TMPL(tf)->tfc_tpg_base_cit); | 1051 | &TF_CIT_TMPL(tf)->tfc_tpg_base_cit); |
@@ -1043,6 +1057,8 @@ static struct config_group *target_fabric_make_tpg( | |||
1043 | &TF_CIT_TMPL(tf)->tfc_tpg_nacl_cit); | 1057 | &TF_CIT_TMPL(tf)->tfc_tpg_nacl_cit); |
1044 | config_group_init_type_name(&se_tpg->tpg_attrib_group, "attrib", | 1058 | config_group_init_type_name(&se_tpg->tpg_attrib_group, "attrib", |
1045 | &TF_CIT_TMPL(tf)->tfc_tpg_attrib_cit); | 1059 | &TF_CIT_TMPL(tf)->tfc_tpg_attrib_cit); |
1060 | config_group_init_type_name(&se_tpg->tpg_auth_group, "auth", | ||
1061 | &TF_CIT_TMPL(tf)->tfc_tpg_auth_cit); | ||
1046 | config_group_init_type_name(&se_tpg->tpg_param_group, "param", | 1062 | config_group_init_type_name(&se_tpg->tpg_param_group, "param", |
1047 | &TF_CIT_TMPL(tf)->tfc_tpg_param_cit); | 1063 | &TF_CIT_TMPL(tf)->tfc_tpg_param_cit); |
1048 | 1064 | ||
@@ -1202,6 +1218,7 @@ int target_fabric_setup_cits(struct target_fabric_configfs *tf) | |||
1202 | target_fabric_setup_tpg_np_cit(tf); | 1218 | target_fabric_setup_tpg_np_cit(tf); |
1203 | target_fabric_setup_tpg_np_base_cit(tf); | 1219 | target_fabric_setup_tpg_np_base_cit(tf); |
1204 | target_fabric_setup_tpg_attrib_cit(tf); | 1220 | target_fabric_setup_tpg_attrib_cit(tf); |
1221 | target_fabric_setup_tpg_auth_cit(tf); | ||
1205 | target_fabric_setup_tpg_param_cit(tf); | 1222 | target_fabric_setup_tpg_param_cit(tf); |
1206 | target_fabric_setup_tpg_nacl_cit(tf); | 1223 | target_fabric_setup_tpg_nacl_cit(tf); |
1207 | target_fabric_setup_tpg_nacl_base_cit(tf); | 1224 | target_fabric_setup_tpg_nacl_base_cit(tf); |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 3240f2cc81ef..bd78faf67c6b 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -53,18 +53,28 @@ struct pr_transport_id_holder { | |||
53 | struct list_head dest_list; | 53 | struct list_head dest_list; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | int core_pr_dump_initiator_port( | 56 | void core_pr_dump_initiator_port( |
57 | struct t10_pr_registration *pr_reg, | 57 | struct t10_pr_registration *pr_reg, |
58 | char *buf, | 58 | char *buf, |
59 | u32 size) | 59 | u32 size) |
60 | { | 60 | { |
61 | if (!pr_reg->isid_present_at_reg) | 61 | if (!pr_reg->isid_present_at_reg) |
62 | return 0; | 62 | buf[0] = '\0'; |
63 | 63 | ||
64 | snprintf(buf, size, ",i,0x%s", &pr_reg->pr_reg_isid[0]); | 64 | snprintf(buf, size, ",i,0x%s", pr_reg->pr_reg_isid); |
65 | return 1; | ||
66 | } | 65 | } |
67 | 66 | ||
67 | enum register_type { | ||
68 | REGISTER, | ||
69 | REGISTER_AND_IGNORE_EXISTING_KEY, | ||
70 | REGISTER_AND_MOVE, | ||
71 | }; | ||
72 | |||
73 | enum preempt_type { | ||
74 | PREEMPT, | ||
75 | PREEMPT_AND_ABORT, | ||
76 | }; | ||
77 | |||
68 | static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, | 78 | static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, |
69 | struct t10_pr_registration *, int); | 79 | struct t10_pr_registration *, int); |
70 | 80 | ||
@@ -596,14 +606,6 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration( | |||
596 | return NULL; | 606 | return NULL; |
597 | } | 607 | } |
598 | 608 | ||
599 | pr_reg->pr_aptpl_buf = kzalloc(dev->t10_pr.pr_aptpl_buf_len, | ||
600 | GFP_ATOMIC); | ||
601 | if (!pr_reg->pr_aptpl_buf) { | ||
602 | pr_err("Unable to allocate pr_reg->pr_aptpl_buf\n"); | ||
603 | kmem_cache_free(t10_pr_reg_cache, pr_reg); | ||
604 | return NULL; | ||
605 | } | ||
606 | |||
607 | INIT_LIST_HEAD(&pr_reg->pr_reg_list); | 609 | INIT_LIST_HEAD(&pr_reg->pr_reg_list); |
608 | INIT_LIST_HEAD(&pr_reg->pr_reg_abort_list); | 610 | INIT_LIST_HEAD(&pr_reg->pr_reg_abort_list); |
609 | INIT_LIST_HEAD(&pr_reg->pr_reg_aptpl_list); | 611 | INIT_LIST_HEAD(&pr_reg->pr_reg_aptpl_list); |
@@ -794,7 +796,6 @@ int core_scsi3_alloc_aptpl_registration( | |||
794 | pr_err("Unable to allocate struct t10_pr_registration\n"); | 796 | pr_err("Unable to allocate struct t10_pr_registration\n"); |
795 | return -ENOMEM; | 797 | return -ENOMEM; |
796 | } | 798 | } |
797 | pr_reg->pr_aptpl_buf = kzalloc(pr_tmpl->pr_aptpl_buf_len, GFP_KERNEL); | ||
798 | 799 | ||
799 | INIT_LIST_HEAD(&pr_reg->pr_reg_list); | 800 | INIT_LIST_HEAD(&pr_reg->pr_reg_list); |
800 | INIT_LIST_HEAD(&pr_reg->pr_reg_abort_list); | 801 | INIT_LIST_HEAD(&pr_reg->pr_reg_abort_list); |
@@ -848,11 +849,9 @@ static void core_scsi3_aptpl_reserve( | |||
848 | struct t10_pr_registration *pr_reg) | 849 | struct t10_pr_registration *pr_reg) |
849 | { | 850 | { |
850 | char i_buf[PR_REG_ISID_ID_LEN]; | 851 | char i_buf[PR_REG_ISID_ID_LEN]; |
851 | int prf_isid; | ||
852 | 852 | ||
853 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 853 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
854 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], | 854 | core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); |
855 | PR_REG_ISID_ID_LEN); | ||
856 | 855 | ||
857 | spin_lock(&dev->dev_reservation_lock); | 856 | spin_lock(&dev->dev_reservation_lock); |
858 | dev->dev_pr_res_holder = pr_reg; | 857 | dev->dev_pr_res_holder = pr_reg; |
@@ -865,11 +864,11 @@ static void core_scsi3_aptpl_reserve( | |||
865 | (pr_reg->pr_reg_all_tg_pt) ? 1 : 0); | 864 | (pr_reg->pr_reg_all_tg_pt) ? 1 : 0); |
866 | pr_debug("SPC-3 PR [%s] RESERVE Node: %s%s\n", | 865 | pr_debug("SPC-3 PR [%s] RESERVE Node: %s%s\n", |
867 | tpg->se_tpg_tfo->get_fabric_name(), node_acl->initiatorname, | 866 | tpg->se_tpg_tfo->get_fabric_name(), node_acl->initiatorname, |
868 | (prf_isid) ? &i_buf[0] : ""); | 867 | i_buf); |
869 | } | 868 | } |
870 | 869 | ||
871 | static void __core_scsi3_add_registration(struct se_device *, struct se_node_acl *, | 870 | static void __core_scsi3_add_registration(struct se_device *, struct se_node_acl *, |
872 | struct t10_pr_registration *, int, int); | 871 | struct t10_pr_registration *, enum register_type, int); |
873 | 872 | ||
874 | static int __core_scsi3_check_aptpl_registration( | 873 | static int __core_scsi3_check_aptpl_registration( |
875 | struct se_device *dev, | 874 | struct se_device *dev, |
@@ -962,21 +961,19 @@ static void __core_scsi3_dump_registration( | |||
962 | struct se_device *dev, | 961 | struct se_device *dev, |
963 | struct se_node_acl *nacl, | 962 | struct se_node_acl *nacl, |
964 | struct t10_pr_registration *pr_reg, | 963 | struct t10_pr_registration *pr_reg, |
965 | int register_type) | 964 | enum register_type register_type) |
966 | { | 965 | { |
967 | struct se_portal_group *se_tpg = nacl->se_tpg; | 966 | struct se_portal_group *se_tpg = nacl->se_tpg; |
968 | char i_buf[PR_REG_ISID_ID_LEN]; | 967 | char i_buf[PR_REG_ISID_ID_LEN]; |
969 | int prf_isid; | ||
970 | 968 | ||
971 | memset(&i_buf[0], 0, PR_REG_ISID_ID_LEN); | 969 | memset(&i_buf[0], 0, PR_REG_ISID_ID_LEN); |
972 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], | 970 | core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); |
973 | PR_REG_ISID_ID_LEN); | ||
974 | 971 | ||
975 | pr_debug("SPC-3 PR [%s] Service Action: REGISTER%s Initiator" | 972 | pr_debug("SPC-3 PR [%s] Service Action: REGISTER%s Initiator" |
976 | " Node: %s%s\n", tfo->get_fabric_name(), (register_type == 2) ? | 973 | " Node: %s%s\n", tfo->get_fabric_name(), (register_type == REGISTER_AND_MOVE) ? |
977 | "_AND_MOVE" : (register_type == 1) ? | 974 | "_AND_MOVE" : (register_type == REGISTER_AND_IGNORE_EXISTING_KEY) ? |
978 | "_AND_IGNORE_EXISTING_KEY" : "", nacl->initiatorname, | 975 | "_AND_IGNORE_EXISTING_KEY" : "", nacl->initiatorname, |
979 | (prf_isid) ? i_buf : ""); | 976 | i_buf); |
980 | pr_debug("SPC-3 PR [%s] registration on Target Port: %s,0x%04x\n", | 977 | pr_debug("SPC-3 PR [%s] registration on Target Port: %s,0x%04x\n", |
981 | tfo->get_fabric_name(), tfo->tpg_get_wwn(se_tpg), | 978 | tfo->get_fabric_name(), tfo->tpg_get_wwn(se_tpg), |
982 | tfo->tpg_get_tag(se_tpg)); | 979 | tfo->tpg_get_tag(se_tpg)); |
@@ -998,7 +995,7 @@ static void __core_scsi3_add_registration( | |||
998 | struct se_device *dev, | 995 | struct se_device *dev, |
999 | struct se_node_acl *nacl, | 996 | struct se_node_acl *nacl, |
1000 | struct t10_pr_registration *pr_reg, | 997 | struct t10_pr_registration *pr_reg, |
1001 | int register_type, | 998 | enum register_type register_type, |
1002 | int register_move) | 999 | int register_move) |
1003 | { | 1000 | { |
1004 | struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; | 1001 | struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; |
@@ -1064,7 +1061,7 @@ static int core_scsi3_alloc_registration( | |||
1064 | u64 sa_res_key, | 1061 | u64 sa_res_key, |
1065 | int all_tg_pt, | 1062 | int all_tg_pt, |
1066 | int aptpl, | 1063 | int aptpl, |
1067 | int register_type, | 1064 | enum register_type register_type, |
1068 | int register_move) | 1065 | int register_move) |
1069 | { | 1066 | { |
1070 | struct t10_pr_registration *pr_reg; | 1067 | struct t10_pr_registration *pr_reg; |
@@ -1225,11 +1222,9 @@ static void __core_scsi3_free_registration( | |||
1225 | pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo; | 1222 | pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo; |
1226 | struct t10_reservation *pr_tmpl = &dev->t10_pr; | 1223 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
1227 | char i_buf[PR_REG_ISID_ID_LEN]; | 1224 | char i_buf[PR_REG_ISID_ID_LEN]; |
1228 | int prf_isid; | ||
1229 | 1225 | ||
1230 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 1226 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
1231 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], | 1227 | core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); |
1232 | PR_REG_ISID_ID_LEN); | ||
1233 | 1228 | ||
1234 | pr_reg->pr_reg_deve->def_pr_registered = 0; | 1229 | pr_reg->pr_reg_deve->def_pr_registered = 0; |
1235 | pr_reg->pr_reg_deve->pr_res_key = 0; | 1230 | pr_reg->pr_reg_deve->pr_res_key = 0; |
@@ -1257,7 +1252,7 @@ static void __core_scsi3_free_registration( | |||
1257 | pr_debug("SPC-3 PR [%s] Service Action: UNREGISTER Initiator" | 1252 | pr_debug("SPC-3 PR [%s] Service Action: UNREGISTER Initiator" |
1258 | " Node: %s%s\n", tfo->get_fabric_name(), | 1253 | " Node: %s%s\n", tfo->get_fabric_name(), |
1259 | pr_reg->pr_reg_nacl->initiatorname, | 1254 | pr_reg->pr_reg_nacl->initiatorname, |
1260 | (prf_isid) ? &i_buf[0] : ""); | 1255 | i_buf); |
1261 | pr_debug("SPC-3 PR [%s] for %s TCM Subsystem %s Object Target" | 1256 | pr_debug("SPC-3 PR [%s] for %s TCM Subsystem %s Object Target" |
1262 | " Port(s)\n", tfo->get_fabric_name(), | 1257 | " Port(s)\n", tfo->get_fabric_name(), |
1263 | (pr_reg->pr_reg_all_tg_pt) ? "ALL" : "SINGLE", | 1258 | (pr_reg->pr_reg_all_tg_pt) ? "ALL" : "SINGLE", |
@@ -1269,7 +1264,6 @@ static void __core_scsi3_free_registration( | |||
1269 | if (!preempt_and_abort_list) { | 1264 | if (!preempt_and_abort_list) { |
1270 | pr_reg->pr_reg_deve = NULL; | 1265 | pr_reg->pr_reg_deve = NULL; |
1271 | pr_reg->pr_reg_nacl = NULL; | 1266 | pr_reg->pr_reg_nacl = NULL; |
1272 | kfree(pr_reg->pr_aptpl_buf); | ||
1273 | kmem_cache_free(t10_pr_reg_cache, pr_reg); | 1267 | kmem_cache_free(t10_pr_reg_cache, pr_reg); |
1274 | return; | 1268 | return; |
1275 | } | 1269 | } |
@@ -1338,7 +1332,6 @@ void core_scsi3_free_all_registrations( | |||
1338 | list_for_each_entry_safe(pr_reg, pr_reg_tmp, &pr_tmpl->aptpl_reg_list, | 1332 | list_for_each_entry_safe(pr_reg, pr_reg_tmp, &pr_tmpl->aptpl_reg_list, |
1339 | pr_reg_aptpl_list) { | 1333 | pr_reg_aptpl_list) { |
1340 | list_del(&pr_reg->pr_reg_aptpl_list); | 1334 | list_del(&pr_reg->pr_reg_aptpl_list); |
1341 | kfree(pr_reg->pr_aptpl_buf); | ||
1342 | kmem_cache_free(t10_pr_reg_cache, pr_reg); | 1335 | kmem_cache_free(t10_pr_reg_cache, pr_reg); |
1343 | } | 1336 | } |
1344 | spin_unlock(&pr_tmpl->aptpl_reg_lock); | 1337 | spin_unlock(&pr_tmpl->aptpl_reg_lock); |
@@ -1453,7 +1446,7 @@ core_scsi3_decode_spec_i_port( | |||
1453 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; | 1446 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; |
1454 | sense_reason_t ret; | 1447 | sense_reason_t ret; |
1455 | u32 tpdl, tid_len = 0; | 1448 | u32 tpdl, tid_len = 0; |
1456 | int dest_local_nexus, prf_isid; | 1449 | int dest_local_nexus; |
1457 | u32 dest_rtpi = 0; | 1450 | u32 dest_rtpi = 0; |
1458 | 1451 | ||
1459 | memset(dest_iport, 0, 64); | 1452 | memset(dest_iport, 0, 64); |
@@ -1764,8 +1757,7 @@ core_scsi3_decode_spec_i_port( | |||
1764 | kfree(tidh); | 1757 | kfree(tidh); |
1765 | 1758 | ||
1766 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 1759 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
1767 | prf_isid = core_pr_dump_initiator_port(dest_pr_reg, &i_buf[0], | 1760 | core_pr_dump_initiator_port(dest_pr_reg, i_buf, PR_REG_ISID_ID_LEN); |
1768 | PR_REG_ISID_ID_LEN); | ||
1769 | 1761 | ||
1770 | __core_scsi3_add_registration(cmd->se_dev, dest_node_acl, | 1762 | __core_scsi3_add_registration(cmd->se_dev, dest_node_acl, |
1771 | dest_pr_reg, 0, 0); | 1763 | dest_pr_reg, 0, 0); |
@@ -1773,8 +1765,7 @@ core_scsi3_decode_spec_i_port( | |||
1773 | pr_debug("SPC-3 PR [%s] SPEC_I_PT: Successfully" | 1765 | pr_debug("SPC-3 PR [%s] SPEC_I_PT: Successfully" |
1774 | " registered Transport ID for Node: %s%s Mapped LUN:" | 1766 | " registered Transport ID for Node: %s%s Mapped LUN:" |
1775 | " %u\n", dest_tpg->se_tpg_tfo->get_fabric_name(), | 1767 | " %u\n", dest_tpg->se_tpg_tfo->get_fabric_name(), |
1776 | dest_node_acl->initiatorname, (prf_isid) ? | 1768 | dest_node_acl->initiatorname, i_buf, dest_se_deve->mapped_lun); |
1777 | &i_buf[0] : "", dest_se_deve->mapped_lun); | ||
1778 | 1769 | ||
1779 | if (dest_local_nexus) | 1770 | if (dest_local_nexus) |
1780 | continue; | 1771 | continue; |
@@ -1813,7 +1804,6 @@ out: | |||
1813 | kmem_cache_free(t10_pr_reg_cache, pr_reg_tmp); | 1804 | kmem_cache_free(t10_pr_reg_cache, pr_reg_tmp); |
1814 | } | 1805 | } |
1815 | 1806 | ||
1816 | kfree(dest_pr_reg->pr_aptpl_buf); | ||
1817 | kmem_cache_free(t10_pr_reg_cache, dest_pr_reg); | 1807 | kmem_cache_free(t10_pr_reg_cache, dest_pr_reg); |
1818 | 1808 | ||
1819 | if (dest_local_nexus) | 1809 | if (dest_local_nexus) |
@@ -1826,14 +1816,10 @@ out: | |||
1826 | return ret; | 1816 | return ret; |
1827 | } | 1817 | } |
1828 | 1818 | ||
1829 | /* | 1819 | static int core_scsi3_update_aptpl_buf( |
1830 | * Called with struct se_device->dev_reservation_lock held | ||
1831 | */ | ||
1832 | static int __core_scsi3_update_aptpl_buf( | ||
1833 | struct se_device *dev, | 1820 | struct se_device *dev, |
1834 | unsigned char *buf, | 1821 | unsigned char *buf, |
1835 | u32 pr_aptpl_buf_len, | 1822 | u32 pr_aptpl_buf_len) |
1836 | int clear_aptpl_metadata) | ||
1837 | { | 1823 | { |
1838 | struct se_lun *lun; | 1824 | struct se_lun *lun; |
1839 | struct se_portal_group *tpg; | 1825 | struct se_portal_group *tpg; |
@@ -1841,20 +1827,13 @@ static int __core_scsi3_update_aptpl_buf( | |||
1841 | unsigned char tmp[512], isid_buf[32]; | 1827 | unsigned char tmp[512], isid_buf[32]; |
1842 | ssize_t len = 0; | 1828 | ssize_t len = 0; |
1843 | int reg_count = 0; | 1829 | int reg_count = 0; |
1830 | int ret = 0; | ||
1844 | 1831 | ||
1845 | memset(buf, 0, pr_aptpl_buf_len); | 1832 | spin_lock(&dev->dev_reservation_lock); |
1846 | /* | 1833 | spin_lock(&dev->t10_pr.registration_lock); |
1847 | * Called to clear metadata once APTPL has been deactivated. | ||
1848 | */ | ||
1849 | if (clear_aptpl_metadata) { | ||
1850 | snprintf(buf, pr_aptpl_buf_len, | ||
1851 | "No Registrations or Reservations\n"); | ||
1852 | return 0; | ||
1853 | } | ||
1854 | /* | 1834 | /* |
1855 | * Walk the registration list.. | 1835 | * Walk the registration list.. |
1856 | */ | 1836 | */ |
1857 | spin_lock(&dev->t10_pr.registration_lock); | ||
1858 | list_for_each_entry(pr_reg, &dev->t10_pr.registration_list, | 1837 | list_for_each_entry(pr_reg, &dev->t10_pr.registration_list, |
1859 | pr_reg_list) { | 1838 | pr_reg_list) { |
1860 | 1839 | ||
@@ -1900,8 +1879,8 @@ static int __core_scsi3_update_aptpl_buf( | |||
1900 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { | 1879 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { |
1901 | pr_err("Unable to update renaming" | 1880 | pr_err("Unable to update renaming" |
1902 | " APTPL metadata\n"); | 1881 | " APTPL metadata\n"); |
1903 | spin_unlock(&dev->t10_pr.registration_lock); | 1882 | ret = -EMSGSIZE; |
1904 | return -EMSGSIZE; | 1883 | goto out; |
1905 | } | 1884 | } |
1906 | len += sprintf(buf+len, "%s", tmp); | 1885 | len += sprintf(buf+len, "%s", tmp); |
1907 | 1886 | ||
@@ -1918,48 +1897,32 @@ static int __core_scsi3_update_aptpl_buf( | |||
1918 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { | 1897 | if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { |
1919 | pr_err("Unable to update renaming" | 1898 | pr_err("Unable to update renaming" |
1920 | " APTPL metadata\n"); | 1899 | " APTPL metadata\n"); |
1921 | spin_unlock(&dev->t10_pr.registration_lock); | 1900 | ret = -EMSGSIZE; |
1922 | return -EMSGSIZE; | 1901 | goto out; |
1923 | } | 1902 | } |
1924 | len += sprintf(buf+len, "%s", tmp); | 1903 | len += sprintf(buf+len, "%s", tmp); |
1925 | reg_count++; | 1904 | reg_count++; |
1926 | } | 1905 | } |
1927 | spin_unlock(&dev->t10_pr.registration_lock); | ||
1928 | 1906 | ||
1929 | if (!reg_count) | 1907 | if (!reg_count) |
1930 | len += sprintf(buf+len, "No Registrations or Reservations"); | 1908 | len += sprintf(buf+len, "No Registrations or Reservations"); |
1931 | 1909 | ||
1932 | return 0; | 1910 | out: |
1933 | } | 1911 | spin_unlock(&dev->t10_pr.registration_lock); |
1934 | |||
1935 | static int core_scsi3_update_aptpl_buf( | ||
1936 | struct se_device *dev, | ||
1937 | unsigned char *buf, | ||
1938 | u32 pr_aptpl_buf_len, | ||
1939 | int clear_aptpl_metadata) | ||
1940 | { | ||
1941 | int ret; | ||
1942 | |||
1943 | spin_lock(&dev->dev_reservation_lock); | ||
1944 | ret = __core_scsi3_update_aptpl_buf(dev, buf, pr_aptpl_buf_len, | ||
1945 | clear_aptpl_metadata); | ||
1946 | spin_unlock(&dev->dev_reservation_lock); | 1912 | spin_unlock(&dev->dev_reservation_lock); |
1947 | 1913 | ||
1948 | return ret; | 1914 | return ret; |
1949 | } | 1915 | } |
1950 | 1916 | ||
1951 | /* | ||
1952 | * Called with struct se_device->aptpl_file_mutex held | ||
1953 | */ | ||
1954 | static int __core_scsi3_write_aptpl_to_file( | 1917 | static int __core_scsi3_write_aptpl_to_file( |
1955 | struct se_device *dev, | 1918 | struct se_device *dev, |
1956 | unsigned char *buf, | 1919 | unsigned char *buf) |
1957 | u32 pr_aptpl_buf_len) | ||
1958 | { | 1920 | { |
1959 | struct t10_wwn *wwn = &dev->t10_wwn; | 1921 | struct t10_wwn *wwn = &dev->t10_wwn; |
1960 | struct file *file; | 1922 | struct file *file; |
1961 | int flags = O_RDWR | O_CREAT | O_TRUNC; | 1923 | int flags = O_RDWR | O_CREAT | O_TRUNC; |
1962 | char path[512]; | 1924 | char path[512]; |
1925 | u32 pr_aptpl_buf_len; | ||
1963 | int ret; | 1926 | int ret; |
1964 | 1927 | ||
1965 | memset(path, 0, 512); | 1928 | memset(path, 0, 512); |
@@ -1978,8 +1941,7 @@ static int __core_scsi3_write_aptpl_to_file( | |||
1978 | return PTR_ERR(file); | 1941 | return PTR_ERR(file); |
1979 | } | 1942 | } |
1980 | 1943 | ||
1981 | if (!pr_aptpl_buf_len) | 1944 | pr_aptpl_buf_len = (strlen(buf) + 1); /* Add extra for NULL */ |
1982 | pr_aptpl_buf_len = (strlen(&buf[0]) + 1); /* Add extra for NULL */ | ||
1983 | 1945 | ||
1984 | ret = kernel_write(file, buf, pr_aptpl_buf_len, 0); | 1946 | ret = kernel_write(file, buf, pr_aptpl_buf_len, 0); |
1985 | 1947 | ||
@@ -1990,60 +1952,64 @@ static int __core_scsi3_write_aptpl_to_file( | |||
1990 | return ret ? -EIO : 0; | 1952 | return ret ? -EIO : 0; |
1991 | } | 1953 | } |
1992 | 1954 | ||
1993 | static int | 1955 | /* |
1994 | core_scsi3_update_and_write_aptpl(struct se_device *dev, unsigned char *in_buf, | 1956 | * Clear the APTPL metadata if APTPL has been disabled, otherwise |
1995 | u32 in_pr_aptpl_buf_len) | 1957 | * write out the updated metadata to struct file for this SCSI device. |
1958 | */ | ||
1959 | static sense_reason_t core_scsi3_update_and_write_aptpl(struct se_device *dev, bool aptpl) | ||
1996 | { | 1960 | { |
1997 | unsigned char null_buf[64], *buf; | 1961 | unsigned char *buf; |
1998 | u32 pr_aptpl_buf_len; | 1962 | int rc; |
1999 | int clear_aptpl_metadata = 0; | ||
2000 | int ret; | ||
2001 | 1963 | ||
2002 | /* | 1964 | if (!aptpl) { |
2003 | * Can be called with a NULL pointer from PROUT service action CLEAR | 1965 | char *null_buf = "No Registrations or Reservations\n"; |
2004 | */ | 1966 | |
2005 | if (!in_buf) { | 1967 | rc = __core_scsi3_write_aptpl_to_file(dev, null_buf); |
2006 | memset(null_buf, 0, 64); | 1968 | dev->t10_pr.pr_aptpl_active = 0; |
2007 | buf = &null_buf[0]; | 1969 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated\n"); |
2008 | /* | 1970 | |
2009 | * This will clear the APTPL metadata to: | 1971 | if (rc) |
2010 | * "No Registrations or Reservations" status | 1972 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2011 | */ | 1973 | |
2012 | pr_aptpl_buf_len = 64; | 1974 | return 0; |
2013 | clear_aptpl_metadata = 1; | ||
2014 | } else { | ||
2015 | buf = in_buf; | ||
2016 | pr_aptpl_buf_len = in_pr_aptpl_buf_len; | ||
2017 | } | 1975 | } |
2018 | 1976 | ||
2019 | ret = core_scsi3_update_aptpl_buf(dev, buf, pr_aptpl_buf_len, | 1977 | buf = kzalloc(PR_APTPL_BUF_LEN, GFP_KERNEL); |
2020 | clear_aptpl_metadata); | 1978 | if (!buf) |
2021 | if (ret != 0) | 1979 | return TCM_OUT_OF_RESOURCES; |
2022 | return ret; | ||
2023 | 1980 | ||
2024 | /* | 1981 | rc = core_scsi3_update_aptpl_buf(dev, buf, PR_APTPL_BUF_LEN); |
2025 | * __core_scsi3_write_aptpl_to_file() will call strlen() | 1982 | if (rc < 0) { |
2026 | * on the passed buf to determine pr_aptpl_buf_len. | 1983 | kfree(buf); |
2027 | */ | 1984 | return TCM_OUT_OF_RESOURCES; |
2028 | return __core_scsi3_write_aptpl_to_file(dev, buf, 0); | 1985 | } |
1986 | |||
1987 | rc = __core_scsi3_write_aptpl_to_file(dev, buf); | ||
1988 | if (rc != 0) { | ||
1989 | pr_err("SPC-3 PR: Could not update APTPL\n"); | ||
1990 | kfree(buf); | ||
1991 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1992 | } | ||
1993 | dev->t10_pr.pr_aptpl_active = 1; | ||
1994 | kfree(buf); | ||
1995 | pr_debug("SPC-3 PR: Set APTPL Bit Activated\n"); | ||
1996 | return 0; | ||
2029 | } | 1997 | } |
2030 | 1998 | ||
2031 | static sense_reason_t | 1999 | static sense_reason_t |
2032 | core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, | 2000 | core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, |
2033 | int aptpl, int all_tg_pt, int spec_i_pt, int ignore_key) | 2001 | bool aptpl, bool all_tg_pt, bool spec_i_pt, enum register_type register_type) |
2034 | { | 2002 | { |
2035 | struct se_session *se_sess = cmd->se_sess; | 2003 | struct se_session *se_sess = cmd->se_sess; |
2036 | struct se_device *dev = cmd->se_dev; | 2004 | struct se_device *dev = cmd->se_dev; |
2037 | struct se_dev_entry *se_deve; | 2005 | struct se_dev_entry *se_deve; |
2038 | struct se_lun *se_lun = cmd->se_lun; | 2006 | struct se_lun *se_lun = cmd->se_lun; |
2039 | struct se_portal_group *se_tpg; | 2007 | struct se_portal_group *se_tpg; |
2040 | struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_reg_tmp, *pr_reg_e; | 2008 | struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_reg_tmp; |
2041 | struct t10_reservation *pr_tmpl = &dev->t10_pr; | 2009 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2042 | /* Used for APTPL metadata w/ UNREGISTER */ | ||
2043 | unsigned char *pr_aptpl_buf = NULL; | ||
2044 | unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL; | 2010 | unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL; |
2045 | sense_reason_t ret = TCM_NO_SENSE; | 2011 | sense_reason_t ret = TCM_NO_SENSE; |
2046 | int pr_holder = 0, type; | 2012 | int pr_holder = 0; |
2047 | 2013 | ||
2048 | if (!se_sess || !se_lun) { | 2014 | if (!se_sess || !se_lun) { |
2049 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2015 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
@@ -2061,8 +2027,8 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, | |||
2061 | /* | 2027 | /* |
2062 | * Follow logic from spc4r17 Section 5.7.7, Register Behaviors Table 47 | 2028 | * Follow logic from spc4r17 Section 5.7.7, Register Behaviors Table 47 |
2063 | */ | 2029 | */ |
2064 | pr_reg_e = core_scsi3_locate_pr_reg(dev, se_sess->se_node_acl, se_sess); | 2030 | pr_reg = core_scsi3_locate_pr_reg(dev, se_sess->se_node_acl, se_sess); |
2065 | if (!pr_reg_e) { | 2031 | if (!pr_reg) { |
2066 | if (res_key) { | 2032 | if (res_key) { |
2067 | pr_warn("SPC-3 PR: Reservation Key non-zero" | 2033 | pr_warn("SPC-3 PR: Reservation Key non-zero" |
2068 | " for SA REGISTER, returning CONFLICT\n"); | 2034 | " for SA REGISTER, returning CONFLICT\n"); |
@@ -2083,7 +2049,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, | |||
2083 | if (core_scsi3_alloc_registration(cmd->se_dev, | 2049 | if (core_scsi3_alloc_registration(cmd->se_dev, |
2084 | se_sess->se_node_acl, se_deve, isid_ptr, | 2050 | se_sess->se_node_acl, se_deve, isid_ptr, |
2085 | sa_res_key, all_tg_pt, aptpl, | 2051 | sa_res_key, all_tg_pt, aptpl, |
2086 | ignore_key, 0)) { | 2052 | register_type, 0)) { |
2087 | pr_err("Unable to allocate" | 2053 | pr_err("Unable to allocate" |
2088 | " struct t10_pr_registration\n"); | 2054 | " struct t10_pr_registration\n"); |
2089 | return TCM_INVALID_PARAMETER_LIST; | 2055 | return TCM_INVALID_PARAMETER_LIST; |
@@ -2102,97 +2068,68 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, | |||
2102 | if (ret != 0) | 2068 | if (ret != 0) |
2103 | return ret; | 2069 | return ret; |
2104 | } | 2070 | } |
2105 | /* | ||
2106 | * Nothing left to do for the APTPL=0 case. | ||
2107 | */ | ||
2108 | if (!aptpl) { | ||
2109 | pr_tmpl->pr_aptpl_active = 0; | ||
2110 | core_scsi3_update_and_write_aptpl(cmd->se_dev, NULL, 0); | ||
2111 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated for" | ||
2112 | " REGISTER\n"); | ||
2113 | return 0; | ||
2114 | } | ||
2115 | /* | ||
2116 | * Locate the newly allocated local I_T Nexus *pr_reg, and | ||
2117 | * update the APTPL metadata information using its | ||
2118 | * preallocated *pr_reg->pr_aptpl_buf. | ||
2119 | */ | ||
2120 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, | ||
2121 | se_sess->se_node_acl, se_sess); | ||
2122 | |||
2123 | if (core_scsi3_update_and_write_aptpl(cmd->se_dev, | ||
2124 | &pr_reg->pr_aptpl_buf[0], | ||
2125 | pr_tmpl->pr_aptpl_buf_len)) { | ||
2126 | pr_tmpl->pr_aptpl_active = 1; | ||
2127 | pr_debug("SPC-3 PR: Set APTPL Bit Activated for REGISTER\n"); | ||
2128 | } | ||
2129 | 2071 | ||
2130 | goto out_put_pr_reg; | 2072 | return core_scsi3_update_and_write_aptpl(dev, aptpl); |
2131 | } | 2073 | } |
2132 | 2074 | ||
2133 | /* | 2075 | /* ok, existing registration */ |
2134 | * Locate the existing *pr_reg via struct se_node_acl pointers | 2076 | |
2135 | */ | 2077 | if ((register_type == REGISTER) && (res_key != pr_reg->pr_res_key)) { |
2136 | pr_reg = pr_reg_e; | 2078 | pr_err("SPC-3 PR REGISTER: Received" |
2137 | type = pr_reg->pr_res_type; | 2079 | " res_key: 0x%016Lx does not match" |
2138 | 2080 | " existing SA REGISTER res_key:" | |
2139 | if (!ignore_key) { | 2081 | " 0x%016Lx\n", res_key, |
2140 | if (res_key != pr_reg->pr_res_key) { | 2082 | pr_reg->pr_res_key); |
2141 | pr_err("SPC-3 PR REGISTER: Received" | 2083 | ret = TCM_RESERVATION_CONFLICT; |
2142 | " res_key: 0x%016Lx does not match" | 2084 | goto out; |
2143 | " existing SA REGISTER res_key:" | ||
2144 | " 0x%016Lx\n", res_key, | ||
2145 | pr_reg->pr_res_key); | ||
2146 | ret = TCM_RESERVATION_CONFLICT; | ||
2147 | goto out_put_pr_reg; | ||
2148 | } | ||
2149 | } | 2085 | } |
2150 | 2086 | ||
2151 | if (spec_i_pt) { | 2087 | if (spec_i_pt) { |
2152 | pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" | 2088 | pr_err("SPC-3 PR REGISTER: SPEC_I_PT" |
2153 | " set while sa_res_key=0\n"); | 2089 | " set on a registered nexus\n"); |
2154 | ret = TCM_INVALID_PARAMETER_LIST; | 2090 | ret = TCM_INVALID_PARAMETER_LIST; |
2155 | goto out_put_pr_reg; | 2091 | goto out; |
2156 | } | 2092 | } |
2157 | 2093 | ||
2158 | /* | 2094 | /* |
2159 | * An existing ALL_TG_PT=1 registration being released | 2095 | * An existing ALL_TG_PT=1 registration being released |
2160 | * must also set ALL_TG_PT=1 in the incoming PROUT. | 2096 | * must also set ALL_TG_PT=1 in the incoming PROUT. |
2161 | */ | 2097 | */ |
2162 | if (pr_reg->pr_reg_all_tg_pt && !(all_tg_pt)) { | 2098 | if (pr_reg->pr_reg_all_tg_pt && !all_tg_pt) { |
2163 | pr_err("SPC-3 PR UNREGISTER: ALL_TG_PT=1" | 2099 | pr_err("SPC-3 PR REGISTER: ALL_TG_PT=1" |
2164 | " registration exists, but ALL_TG_PT=1 bit not" | 2100 | " registration exists, but ALL_TG_PT=1 bit not" |
2165 | " present in received PROUT\n"); | 2101 | " present in received PROUT\n"); |
2166 | ret = TCM_INVALID_CDB_FIELD; | 2102 | ret = TCM_INVALID_CDB_FIELD; |
2167 | goto out_put_pr_reg; | 2103 | goto out; |
2168 | } | 2104 | } |
2169 | 2105 | ||
2170 | /* | 2106 | /* |
2171 | * Allocate APTPL metadata buffer used for UNREGISTER ops | 2107 | * sa_res_key=1 Change Reservation Key for registered I_T Nexus. |
2172 | */ | 2108 | */ |
2173 | if (aptpl) { | 2109 | if (sa_res_key) { |
2174 | pr_aptpl_buf = kzalloc(pr_tmpl->pr_aptpl_buf_len, | 2110 | /* |
2175 | GFP_KERNEL); | 2111 | * Increment PRgeneration counter for struct se_device" |
2176 | if (!pr_aptpl_buf) { | 2112 | * upon a successful REGISTER, see spc4r17 section 6.3.2 |
2177 | pr_err("Unable to allocate" | 2113 | * READ_KEYS service action. |
2178 | " pr_aptpl_buf\n"); | 2114 | */ |
2179 | ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2115 | pr_reg->pr_res_generation = core_scsi3_pr_generation(cmd->se_dev); |
2180 | goto out_put_pr_reg; | 2116 | pr_reg->pr_res_key = sa_res_key; |
2181 | } | 2117 | pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation" |
2182 | } | 2118 | " Key for %s to: 0x%016Lx PRgeneration:" |
2119 | " 0x%08x\n", cmd->se_tfo->get_fabric_name(), | ||
2120 | (register_type == REGISTER_AND_IGNORE_EXISTING_KEY) ? "_AND_IGNORE_EXISTING_KEY" : "", | ||
2121 | pr_reg->pr_reg_nacl->initiatorname, | ||
2122 | pr_reg->pr_res_key, pr_reg->pr_res_generation); | ||
2183 | 2123 | ||
2184 | /* | 2124 | } else { |
2185 | * sa_res_key=0 Unregister Reservation Key for registered I_T | 2125 | /* |
2186 | * Nexus sa_res_key=1 Change Reservation Key for registered I_T | 2126 | * sa_res_key=0 Unregister Reservation Key for registered I_T Nexus. |
2187 | * Nexus. | 2127 | */ |
2188 | */ | ||
2189 | if (!sa_res_key) { | ||
2190 | pr_holder = core_scsi3_check_implict_release( | 2128 | pr_holder = core_scsi3_check_implict_release( |
2191 | cmd->se_dev, pr_reg); | 2129 | cmd->se_dev, pr_reg); |
2192 | if (pr_holder < 0) { | 2130 | if (pr_holder < 0) { |
2193 | kfree(pr_aptpl_buf); | ||
2194 | ret = TCM_RESERVATION_CONFLICT; | 2131 | ret = TCM_RESERVATION_CONFLICT; |
2195 | goto out_put_pr_reg; | 2132 | goto out; |
2196 | } | 2133 | } |
2197 | 2134 | ||
2198 | spin_lock(&pr_tmpl->registration_lock); | 2135 | spin_lock(&pr_tmpl->registration_lock); |
@@ -2237,8 +2174,8 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, | |||
2237 | * RESERVATIONS RELEASED. | 2174 | * RESERVATIONS RELEASED. |
2238 | */ | 2175 | */ |
2239 | if (pr_holder && | 2176 | if (pr_holder && |
2240 | (type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY || | 2177 | (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY || |
2241 | type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY)) { | 2178 | pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY)) { |
2242 | list_for_each_entry(pr_reg_p, | 2179 | list_for_each_entry(pr_reg_p, |
2243 | &pr_tmpl->registration_list, | 2180 | &pr_tmpl->registration_list, |
2244 | pr_reg_list) { | 2181 | pr_reg_list) { |
@@ -2250,60 +2187,13 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, | |||
2250 | ASCQ_2AH_RESERVATIONS_RELEASED); | 2187 | ASCQ_2AH_RESERVATIONS_RELEASED); |
2251 | } | 2188 | } |
2252 | } | 2189 | } |
2253 | spin_unlock(&pr_tmpl->registration_lock); | ||
2254 | |||
2255 | if (!aptpl) { | ||
2256 | pr_tmpl->pr_aptpl_active = 0; | ||
2257 | core_scsi3_update_and_write_aptpl(dev, NULL, 0); | ||
2258 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated" | ||
2259 | " for UNREGISTER\n"); | ||
2260 | return 0; | ||
2261 | } | ||
2262 | 2190 | ||
2263 | if (!core_scsi3_update_and_write_aptpl(dev, &pr_aptpl_buf[0], | 2191 | spin_unlock(&pr_tmpl->registration_lock); |
2264 | pr_tmpl->pr_aptpl_buf_len)) { | ||
2265 | pr_tmpl->pr_aptpl_active = 1; | ||
2266 | pr_debug("SPC-3 PR: Set APTPL Bit Activated" | ||
2267 | " for UNREGISTER\n"); | ||
2268 | } | ||
2269 | |||
2270 | goto out_free_aptpl_buf; | ||
2271 | } | ||
2272 | |||
2273 | /* | ||
2274 | * Increment PRgeneration counter for struct se_device" | ||
2275 | * upon a successful REGISTER, see spc4r17 section 6.3.2 | ||
2276 | * READ_KEYS service action. | ||
2277 | */ | ||
2278 | pr_reg->pr_res_generation = core_scsi3_pr_generation(cmd->se_dev); | ||
2279 | pr_reg->pr_res_key = sa_res_key; | ||
2280 | pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation" | ||
2281 | " Key for %s to: 0x%016Lx PRgeneration:" | ||
2282 | " 0x%08x\n", cmd->se_tfo->get_fabric_name(), | ||
2283 | (ignore_key) ? "_AND_IGNORE_EXISTING_KEY" : "", | ||
2284 | pr_reg->pr_reg_nacl->initiatorname, | ||
2285 | pr_reg->pr_res_key, pr_reg->pr_res_generation); | ||
2286 | |||
2287 | if (!aptpl) { | ||
2288 | pr_tmpl->pr_aptpl_active = 0; | ||
2289 | core_scsi3_update_and_write_aptpl(dev, NULL, 0); | ||
2290 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated" | ||
2291 | " for REGISTER\n"); | ||
2292 | ret = 0; | ||
2293 | goto out_put_pr_reg; | ||
2294 | } | 2192 | } |
2295 | 2193 | ||
2296 | if (!core_scsi3_update_and_write_aptpl(dev, &pr_aptpl_buf[0], | 2194 | ret = core_scsi3_update_and_write_aptpl(dev, aptpl); |
2297 | pr_tmpl->pr_aptpl_buf_len)) { | ||
2298 | pr_tmpl->pr_aptpl_active = 1; | ||
2299 | pr_debug("SPC-3 PR: Set APTPL Bit Activated" | ||
2300 | " for REGISTER\n"); | ||
2301 | } | ||
2302 | 2195 | ||
2303 | out_free_aptpl_buf: | 2196 | out: |
2304 | kfree(pr_aptpl_buf); | ||
2305 | ret = 0; | ||
2306 | out_put_pr_reg: | ||
2307 | core_scsi3_put_pr_reg(pr_reg); | 2197 | core_scsi3_put_pr_reg(pr_reg); |
2308 | return ret; | 2198 | return ret; |
2309 | } | 2199 | } |
@@ -2340,7 +2230,6 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) | |||
2340 | struct t10_reservation *pr_tmpl = &dev->t10_pr; | 2230 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2341 | char i_buf[PR_REG_ISID_ID_LEN]; | 2231 | char i_buf[PR_REG_ISID_ID_LEN]; |
2342 | sense_reason_t ret; | 2232 | sense_reason_t ret; |
2343 | int prf_isid; | ||
2344 | 2233 | ||
2345 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 2234 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
2346 | 2235 | ||
@@ -2466,8 +2355,7 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) | |||
2466 | pr_reg->pr_res_type = type; | 2355 | pr_reg->pr_res_type = type; |
2467 | pr_reg->pr_res_holder = 1; | 2356 | pr_reg->pr_res_holder = 1; |
2468 | dev->dev_pr_res_holder = pr_reg; | 2357 | dev->dev_pr_res_holder = pr_reg; |
2469 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], | 2358 | core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); |
2470 | PR_REG_ISID_ID_LEN); | ||
2471 | 2359 | ||
2472 | pr_debug("SPC-3 PR [%s] Service Action: RESERVE created new" | 2360 | pr_debug("SPC-3 PR [%s] Service Action: RESERVE created new" |
2473 | " reservation holder TYPE: %s ALL_TG_PT: %d\n", | 2361 | " reservation holder TYPE: %s ALL_TG_PT: %d\n", |
@@ -2476,17 +2364,11 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) | |||
2476 | pr_debug("SPC-3 PR [%s] RESERVE Node: %s%s\n", | 2364 | pr_debug("SPC-3 PR [%s] RESERVE Node: %s%s\n", |
2477 | cmd->se_tfo->get_fabric_name(), | 2365 | cmd->se_tfo->get_fabric_name(), |
2478 | se_sess->se_node_acl->initiatorname, | 2366 | se_sess->se_node_acl->initiatorname, |
2479 | (prf_isid) ? &i_buf[0] : ""); | 2367 | i_buf); |
2480 | spin_unlock(&dev->dev_reservation_lock); | 2368 | spin_unlock(&dev->dev_reservation_lock); |
2481 | 2369 | ||
2482 | if (pr_tmpl->pr_aptpl_active) { | 2370 | if (pr_tmpl->pr_aptpl_active) |
2483 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, | 2371 | core_scsi3_update_and_write_aptpl(cmd->se_dev, true); |
2484 | &pr_reg->pr_aptpl_buf[0], | ||
2485 | pr_tmpl->pr_aptpl_buf_len)) { | ||
2486 | pr_debug("SPC-3 PR: Updated APTPL metadata" | ||
2487 | " for RESERVE\n"); | ||
2488 | } | ||
2489 | } | ||
2490 | 2372 | ||
2491 | ret = 0; | 2373 | ret = 0; |
2492 | out_put_pr_reg: | 2374 | out_put_pr_reg: |
@@ -2524,11 +2406,9 @@ static void __core_scsi3_complete_pro_release( | |||
2524 | { | 2406 | { |
2525 | struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo; | 2407 | struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo; |
2526 | char i_buf[PR_REG_ISID_ID_LEN]; | 2408 | char i_buf[PR_REG_ISID_ID_LEN]; |
2527 | int prf_isid; | ||
2528 | 2409 | ||
2529 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 2410 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
2530 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], | 2411 | core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); |
2531 | PR_REG_ISID_ID_LEN); | ||
2532 | /* | 2412 | /* |
2533 | * Go ahead and release the current PR reservation holder. | 2413 | * Go ahead and release the current PR reservation holder. |
2534 | */ | 2414 | */ |
@@ -2541,7 +2421,7 @@ static void __core_scsi3_complete_pro_release( | |||
2541 | (pr_reg->pr_reg_all_tg_pt) ? 1 : 0); | 2421 | (pr_reg->pr_reg_all_tg_pt) ? 1 : 0); |
2542 | pr_debug("SPC-3 PR [%s] RELEASE Node: %s%s\n", | 2422 | pr_debug("SPC-3 PR [%s] RELEASE Node: %s%s\n", |
2543 | tfo->get_fabric_name(), se_nacl->initiatorname, | 2423 | tfo->get_fabric_name(), se_nacl->initiatorname, |
2544 | (prf_isid) ? &i_buf[0] : ""); | 2424 | i_buf); |
2545 | /* | 2425 | /* |
2546 | * Clear TYPE and SCOPE for the next PROUT Service Action: RESERVE | 2426 | * Clear TYPE and SCOPE for the next PROUT Service Action: RESERVE |
2547 | */ | 2427 | */ |
@@ -2702,12 +2582,9 @@ core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope, | |||
2702 | spin_unlock(&pr_tmpl->registration_lock); | 2582 | spin_unlock(&pr_tmpl->registration_lock); |
2703 | 2583 | ||
2704 | write_aptpl: | 2584 | write_aptpl: |
2705 | if (pr_tmpl->pr_aptpl_active) { | 2585 | if (pr_tmpl->pr_aptpl_active) |
2706 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, | 2586 | core_scsi3_update_and_write_aptpl(cmd->se_dev, true); |
2707 | &pr_reg->pr_aptpl_buf[0], pr_tmpl->pr_aptpl_buf_len)) { | 2587 | |
2708 | pr_debug("SPC-3 PR: Updated APTPL metadata for RELEASE\n"); | ||
2709 | } | ||
2710 | } | ||
2711 | out_put_pr_reg: | 2588 | out_put_pr_reg: |
2712 | core_scsi3_put_pr_reg(pr_reg); | 2589 | core_scsi3_put_pr_reg(pr_reg); |
2713 | return ret; | 2590 | return ret; |
@@ -2791,11 +2668,7 @@ core_scsi3_emulate_pro_clear(struct se_cmd *cmd, u64 res_key) | |||
2791 | pr_debug("SPC-3 PR [%s] Service Action: CLEAR complete\n", | 2668 | pr_debug("SPC-3 PR [%s] Service Action: CLEAR complete\n", |
2792 | cmd->se_tfo->get_fabric_name()); | 2669 | cmd->se_tfo->get_fabric_name()); |
2793 | 2670 | ||
2794 | if (pr_tmpl->pr_aptpl_active) { | 2671 | core_scsi3_update_and_write_aptpl(cmd->se_dev, false); |
2795 | core_scsi3_update_and_write_aptpl(cmd->se_dev, NULL, 0); | ||
2796 | pr_debug("SPC-3 PR: Updated APTPL metadata" | ||
2797 | " for CLEAR\n"); | ||
2798 | } | ||
2799 | 2672 | ||
2800 | core_scsi3_pr_generation(dev); | 2673 | core_scsi3_pr_generation(dev); |
2801 | return 0; | 2674 | return 0; |
@@ -2810,16 +2683,14 @@ static void __core_scsi3_complete_pro_preempt( | |||
2810 | struct list_head *preempt_and_abort_list, | 2683 | struct list_head *preempt_and_abort_list, |
2811 | int type, | 2684 | int type, |
2812 | int scope, | 2685 | int scope, |
2813 | int abort) | 2686 | enum preempt_type preempt_type) |
2814 | { | 2687 | { |
2815 | struct se_node_acl *nacl = pr_reg->pr_reg_nacl; | 2688 | struct se_node_acl *nacl = pr_reg->pr_reg_nacl; |
2816 | struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; | 2689 | struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; |
2817 | char i_buf[PR_REG_ISID_ID_LEN]; | 2690 | char i_buf[PR_REG_ISID_ID_LEN]; |
2818 | int prf_isid; | ||
2819 | 2691 | ||
2820 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 2692 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
2821 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], | 2693 | core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); |
2822 | PR_REG_ISID_ID_LEN); | ||
2823 | /* | 2694 | /* |
2824 | * Do an implict RELEASE of the existing reservation. | 2695 | * Do an implict RELEASE of the existing reservation. |
2825 | */ | 2696 | */ |
@@ -2834,12 +2705,12 @@ static void __core_scsi3_complete_pro_preempt( | |||
2834 | 2705 | ||
2835 | pr_debug("SPC-3 PR [%s] Service Action: PREEMPT%s created new" | 2706 | pr_debug("SPC-3 PR [%s] Service Action: PREEMPT%s created new" |
2836 | " reservation holder TYPE: %s ALL_TG_PT: %d\n", | 2707 | " reservation holder TYPE: %s ALL_TG_PT: %d\n", |
2837 | tfo->get_fabric_name(), (abort) ? "_AND_ABORT" : "", | 2708 | tfo->get_fabric_name(), (preempt_type == PREEMPT_AND_ABORT) ? "_AND_ABORT" : "", |
2838 | core_scsi3_pr_dump_type(type), | 2709 | core_scsi3_pr_dump_type(type), |
2839 | (pr_reg->pr_reg_all_tg_pt) ? 1 : 0); | 2710 | (pr_reg->pr_reg_all_tg_pt) ? 1 : 0); |
2840 | pr_debug("SPC-3 PR [%s] PREEMPT%s from Node: %s%s\n", | 2711 | pr_debug("SPC-3 PR [%s] PREEMPT%s from Node: %s%s\n", |
2841 | tfo->get_fabric_name(), (abort) ? "_AND_ABORT" : "", | 2712 | tfo->get_fabric_name(), (preempt_type == PREEMPT_AND_ABORT) ? "_AND_ABORT" : "", |
2842 | nacl->initiatorname, (prf_isid) ? &i_buf[0] : ""); | 2713 | nacl->initiatorname, i_buf); |
2843 | /* | 2714 | /* |
2844 | * For PREEMPT_AND_ABORT, add the preempting reservation's | 2715 | * For PREEMPT_AND_ABORT, add the preempting reservation's |
2845 | * struct t10_pr_registration to the list that will be compared | 2716 | * struct t10_pr_registration to the list that will be compared |
@@ -2869,14 +2740,13 @@ static void core_scsi3_release_preempt_and_abort( | |||
2869 | 2740 | ||
2870 | pr_reg->pr_reg_deve = NULL; | 2741 | pr_reg->pr_reg_deve = NULL; |
2871 | pr_reg->pr_reg_nacl = NULL; | 2742 | pr_reg->pr_reg_nacl = NULL; |
2872 | kfree(pr_reg->pr_aptpl_buf); | ||
2873 | kmem_cache_free(t10_pr_reg_cache, pr_reg); | 2743 | kmem_cache_free(t10_pr_reg_cache, pr_reg); |
2874 | } | 2744 | } |
2875 | } | 2745 | } |
2876 | 2746 | ||
2877 | static sense_reason_t | 2747 | static sense_reason_t |
2878 | core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | 2748 | core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, |
2879 | u64 sa_res_key, int abort) | 2749 | u64 sa_res_key, enum preempt_type preempt_type) |
2880 | { | 2750 | { |
2881 | struct se_device *dev = cmd->se_dev; | 2751 | struct se_device *dev = cmd->se_dev; |
2882 | struct se_node_acl *pr_reg_nacl; | 2752 | struct se_node_acl *pr_reg_nacl; |
@@ -2896,7 +2766,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
2896 | if (!pr_reg_n) { | 2766 | if (!pr_reg_n) { |
2897 | pr_err("SPC-3 PR: Unable to locate" | 2767 | pr_err("SPC-3 PR: Unable to locate" |
2898 | " PR_REGISTERED *pr_reg for PREEMPT%s\n", | 2768 | " PR_REGISTERED *pr_reg for PREEMPT%s\n", |
2899 | (abort) ? "_AND_ABORT" : ""); | 2769 | (preempt_type == PREEMPT_AND_ABORT) ? "_AND_ABORT" : ""); |
2900 | return TCM_RESERVATION_CONFLICT; | 2770 | return TCM_RESERVATION_CONFLICT; |
2901 | } | 2771 | } |
2902 | if (pr_reg_n->pr_res_key != res_key) { | 2772 | if (pr_reg_n->pr_res_key != res_key) { |
@@ -2965,7 +2835,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
2965 | pr_reg_nacl = pr_reg->pr_reg_nacl; | 2835 | pr_reg_nacl = pr_reg->pr_reg_nacl; |
2966 | pr_res_mapped_lun = pr_reg->pr_res_mapped_lun; | 2836 | pr_res_mapped_lun = pr_reg->pr_res_mapped_lun; |
2967 | __core_scsi3_free_registration(dev, pr_reg, | 2837 | __core_scsi3_free_registration(dev, pr_reg, |
2968 | (abort) ? &preempt_and_abort_list : | 2838 | (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : |
2969 | NULL, calling_it_nexus); | 2839 | NULL, calling_it_nexus); |
2970 | released_regs++; | 2840 | released_regs++; |
2971 | } else { | 2841 | } else { |
@@ -2993,7 +2863,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
2993 | pr_reg_nacl = pr_reg->pr_reg_nacl; | 2863 | pr_reg_nacl = pr_reg->pr_reg_nacl; |
2994 | pr_res_mapped_lun = pr_reg->pr_res_mapped_lun; | 2864 | pr_res_mapped_lun = pr_reg->pr_res_mapped_lun; |
2995 | __core_scsi3_free_registration(dev, pr_reg, | 2865 | __core_scsi3_free_registration(dev, pr_reg, |
2996 | (abort) ? &preempt_and_abort_list : | 2866 | (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : |
2997 | NULL, 0); | 2867 | NULL, 0); |
2998 | released_regs++; | 2868 | released_regs++; |
2999 | } | 2869 | } |
@@ -3022,24 +2892,17 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
3022 | */ | 2892 | */ |
3023 | if (pr_res_holder && all_reg && !(sa_res_key)) { | 2893 | if (pr_res_holder && all_reg && !(sa_res_key)) { |
3024 | __core_scsi3_complete_pro_preempt(dev, pr_reg_n, | 2894 | __core_scsi3_complete_pro_preempt(dev, pr_reg_n, |
3025 | (abort) ? &preempt_and_abort_list : NULL, | 2895 | (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : NULL, |
3026 | type, scope, abort); | 2896 | type, scope, preempt_type); |
3027 | 2897 | ||
3028 | if (abort) | 2898 | if (preempt_type == PREEMPT_AND_ABORT) |
3029 | core_scsi3_release_preempt_and_abort( | 2899 | core_scsi3_release_preempt_and_abort( |
3030 | &preempt_and_abort_list, pr_reg_n); | 2900 | &preempt_and_abort_list, pr_reg_n); |
3031 | } | 2901 | } |
3032 | spin_unlock(&dev->dev_reservation_lock); | 2902 | spin_unlock(&dev->dev_reservation_lock); |
3033 | 2903 | ||
3034 | if (pr_tmpl->pr_aptpl_active) { | 2904 | if (pr_tmpl->pr_aptpl_active) |
3035 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, | 2905 | core_scsi3_update_and_write_aptpl(cmd->se_dev, true); |
3036 | &pr_reg_n->pr_aptpl_buf[0], | ||
3037 | pr_tmpl->pr_aptpl_buf_len)) { | ||
3038 | pr_debug("SPC-3 PR: Updated APTPL" | ||
3039 | " metadata for PREEMPT%s\n", (abort) ? | ||
3040 | "_AND_ABORT" : ""); | ||
3041 | } | ||
3042 | } | ||
3043 | 2906 | ||
3044 | core_scsi3_put_pr_reg(pr_reg_n); | 2907 | core_scsi3_put_pr_reg(pr_reg_n); |
3045 | core_scsi3_pr_generation(cmd->se_dev); | 2908 | core_scsi3_pr_generation(cmd->se_dev); |
@@ -3103,7 +2966,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
3103 | pr_reg_nacl = pr_reg->pr_reg_nacl; | 2966 | pr_reg_nacl = pr_reg->pr_reg_nacl; |
3104 | pr_res_mapped_lun = pr_reg->pr_res_mapped_lun; | 2967 | pr_res_mapped_lun = pr_reg->pr_res_mapped_lun; |
3105 | __core_scsi3_free_registration(dev, pr_reg, | 2968 | __core_scsi3_free_registration(dev, pr_reg, |
3106 | (abort) ? &preempt_and_abort_list : NULL, | 2969 | (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : NULL, |
3107 | calling_it_nexus); | 2970 | calling_it_nexus); |
3108 | /* | 2971 | /* |
3109 | * e) Establish a unit attention condition for the initiator | 2972 | * e) Establish a unit attention condition for the initiator |
@@ -3120,8 +2983,8 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
3120 | * I_T nexus using the contents of the SCOPE and TYPE fields; | 2983 | * I_T nexus using the contents of the SCOPE and TYPE fields; |
3121 | */ | 2984 | */ |
3122 | __core_scsi3_complete_pro_preempt(dev, pr_reg_n, | 2985 | __core_scsi3_complete_pro_preempt(dev, pr_reg_n, |
3123 | (abort) ? &preempt_and_abort_list : NULL, | 2986 | (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list : NULL, |
3124 | type, scope, abort); | 2987 | type, scope, preempt_type); |
3125 | /* | 2988 | /* |
3126 | * d) Process tasks as defined in 5.7.1; | 2989 | * d) Process tasks as defined in 5.7.1; |
3127 | * e) See above.. | 2990 | * e) See above.. |
@@ -3161,20 +3024,14 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
3161 | * been removed from the primary pr_reg list), except the | 3024 | * been removed from the primary pr_reg list), except the |
3162 | * new persistent reservation holder, the calling Initiator Port. | 3025 | * new persistent reservation holder, the calling Initiator Port. |
3163 | */ | 3026 | */ |
3164 | if (abort) { | 3027 | if (preempt_type == PREEMPT_AND_ABORT) { |
3165 | core_tmr_lun_reset(dev, NULL, &preempt_and_abort_list, cmd); | 3028 | core_tmr_lun_reset(dev, NULL, &preempt_and_abort_list, cmd); |
3166 | core_scsi3_release_preempt_and_abort(&preempt_and_abort_list, | 3029 | core_scsi3_release_preempt_and_abort(&preempt_and_abort_list, |
3167 | pr_reg_n); | 3030 | pr_reg_n); |
3168 | } | 3031 | } |
3169 | 3032 | ||
3170 | if (pr_tmpl->pr_aptpl_active) { | 3033 | if (pr_tmpl->pr_aptpl_active) |
3171 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, | 3034 | core_scsi3_update_and_write_aptpl(cmd->se_dev, true); |
3172 | &pr_reg_n->pr_aptpl_buf[0], | ||
3173 | pr_tmpl->pr_aptpl_buf_len)) { | ||
3174 | pr_debug("SPC-3 PR: Updated APTPL metadata for PREEMPT" | ||
3175 | "%s\n", abort ? "_AND_ABORT" : ""); | ||
3176 | } | ||
3177 | } | ||
3178 | 3035 | ||
3179 | core_scsi3_put_pr_reg(pr_reg_n); | 3036 | core_scsi3_put_pr_reg(pr_reg_n); |
3180 | core_scsi3_pr_generation(cmd->se_dev); | 3037 | core_scsi3_pr_generation(cmd->se_dev); |
@@ -3183,7 +3040,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key, | |||
3183 | 3040 | ||
3184 | static sense_reason_t | 3041 | static sense_reason_t |
3185 | core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope, | 3042 | core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope, |
3186 | u64 res_key, u64 sa_res_key, int abort) | 3043 | u64 res_key, u64 sa_res_key, enum preempt_type preempt_type) |
3187 | { | 3044 | { |
3188 | switch (type) { | 3045 | switch (type) { |
3189 | case PR_TYPE_WRITE_EXCLUSIVE: | 3046 | case PR_TYPE_WRITE_EXCLUSIVE: |
@@ -3193,10 +3050,10 @@ core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope, | |||
3193 | case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: | 3050 | case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: |
3194 | case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: | 3051 | case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: |
3195 | return core_scsi3_pro_preempt(cmd, type, scope, res_key, | 3052 | return core_scsi3_pro_preempt(cmd, type, scope, res_key, |
3196 | sa_res_key, abort); | 3053 | sa_res_key, preempt_type); |
3197 | default: | 3054 | default: |
3198 | pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" | 3055 | pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" |
3199 | " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); | 3056 | " Type: 0x%02x\n", (preempt_type == PREEMPT_AND_ABORT) ? "_AND_ABORT" : "", type); |
3200 | return TCM_INVALID_CDB_FIELD; | 3057 | return TCM_INVALID_CDB_FIELD; |
3201 | } | 3058 | } |
3202 | } | 3059 | } |
@@ -3220,7 +3077,7 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, | |||
3220 | unsigned char *initiator_str; | 3077 | unsigned char *initiator_str; |
3221 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; | 3078 | char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN]; |
3222 | u32 tid_len, tmp_tid_len; | 3079 | u32 tid_len, tmp_tid_len; |
3223 | int new_reg = 0, type, scope, matching_iname, prf_isid; | 3080 | int new_reg = 0, type, scope, matching_iname; |
3224 | sense_reason_t ret; | 3081 | sense_reason_t ret; |
3225 | unsigned short rtpi; | 3082 | unsigned short rtpi; |
3226 | unsigned char proto_ident; | 3083 | unsigned char proto_ident; |
@@ -3564,8 +3421,7 @@ after_iport_check: | |||
3564 | dest_pr_reg->pr_res_holder = 1; | 3421 | dest_pr_reg->pr_res_holder = 1; |
3565 | dest_pr_reg->pr_res_type = type; | 3422 | dest_pr_reg->pr_res_type = type; |
3566 | pr_reg->pr_res_scope = scope; | 3423 | pr_reg->pr_res_scope = scope; |
3567 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], | 3424 | core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); |
3568 | PR_REG_ISID_ID_LEN); | ||
3569 | /* | 3425 | /* |
3570 | * Increment PRGeneration for existing registrations.. | 3426 | * Increment PRGeneration for existing registrations.. |
3571 | */ | 3427 | */ |
@@ -3581,7 +3437,7 @@ after_iport_check: | |||
3581 | pr_debug("SPC-3 PR Successfully moved reservation from" | 3437 | pr_debug("SPC-3 PR Successfully moved reservation from" |
3582 | " %s Fabric Node: %s%s -> %s Fabric Node: %s %s\n", | 3438 | " %s Fabric Node: %s%s -> %s Fabric Node: %s %s\n", |
3583 | tf_ops->get_fabric_name(), pr_reg_nacl->initiatorname, | 3439 | tf_ops->get_fabric_name(), pr_reg_nacl->initiatorname, |
3584 | (prf_isid) ? &i_buf[0] : "", dest_tf_ops->get_fabric_name(), | 3440 | i_buf, dest_tf_ops->get_fabric_name(), |
3585 | dest_node_acl->initiatorname, (iport_ptr != NULL) ? | 3441 | dest_node_acl->initiatorname, (iport_ptr != NULL) ? |
3586 | iport_ptr : ""); | 3442 | iport_ptr : ""); |
3587 | /* | 3443 | /* |
@@ -3602,24 +3458,7 @@ after_iport_check: | |||
3602 | } else | 3458 | } else |
3603 | core_scsi3_put_pr_reg(pr_reg); | 3459 | core_scsi3_put_pr_reg(pr_reg); |
3604 | 3460 | ||
3605 | /* | 3461 | core_scsi3_update_and_write_aptpl(cmd->se_dev, aptpl); |
3606 | * Clear the APTPL metadata if APTPL has been disabled, otherwise | ||
3607 | * write out the updated metadata to struct file for this SCSI device. | ||
3608 | */ | ||
3609 | if (!aptpl) { | ||
3610 | pr_tmpl->pr_aptpl_active = 0; | ||
3611 | core_scsi3_update_and_write_aptpl(cmd->se_dev, NULL, 0); | ||
3612 | pr_debug("SPC-3 PR: Set APTPL Bit Deactivated for" | ||
3613 | " REGISTER_AND_MOVE\n"); | ||
3614 | } else { | ||
3615 | pr_tmpl->pr_aptpl_active = 1; | ||
3616 | if (!core_scsi3_update_and_write_aptpl(cmd->se_dev, | ||
3617 | &dest_pr_reg->pr_aptpl_buf[0], | ||
3618 | pr_tmpl->pr_aptpl_buf_len)) { | ||
3619 | pr_debug("SPC-3 PR: Set APTPL Bit Activated for" | ||
3620 | " REGISTER_AND_MOVE\n"); | ||
3621 | } | ||
3622 | } | ||
3623 | 3462 | ||
3624 | transport_kunmap_data_sg(cmd); | 3463 | transport_kunmap_data_sg(cmd); |
3625 | 3464 | ||
@@ -3752,7 +3591,7 @@ target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3752 | switch (sa) { | 3591 | switch (sa) { |
3753 | case PRO_REGISTER: | 3592 | case PRO_REGISTER: |
3754 | ret = core_scsi3_emulate_pro_register(cmd, | 3593 | ret = core_scsi3_emulate_pro_register(cmd, |
3755 | res_key, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 0); | 3594 | res_key, sa_res_key, aptpl, all_tg_pt, spec_i_pt, REGISTER); |
3756 | break; | 3595 | break; |
3757 | case PRO_RESERVE: | 3596 | case PRO_RESERVE: |
3758 | ret = core_scsi3_emulate_pro_reserve(cmd, type, scope, res_key); | 3597 | ret = core_scsi3_emulate_pro_reserve(cmd, type, scope, res_key); |
@@ -3765,15 +3604,15 @@ target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3765 | break; | 3604 | break; |
3766 | case PRO_PREEMPT: | 3605 | case PRO_PREEMPT: |
3767 | ret = core_scsi3_emulate_pro_preempt(cmd, type, scope, | 3606 | ret = core_scsi3_emulate_pro_preempt(cmd, type, scope, |
3768 | res_key, sa_res_key, 0); | 3607 | res_key, sa_res_key, PREEMPT); |
3769 | break; | 3608 | break; |
3770 | case PRO_PREEMPT_AND_ABORT: | 3609 | case PRO_PREEMPT_AND_ABORT: |
3771 | ret = core_scsi3_emulate_pro_preempt(cmd, type, scope, | 3610 | ret = core_scsi3_emulate_pro_preempt(cmd, type, scope, |
3772 | res_key, sa_res_key, 1); | 3611 | res_key, sa_res_key, PREEMPT_AND_ABORT); |
3773 | break; | 3612 | break; |
3774 | case PRO_REGISTER_AND_IGNORE_EXISTING_KEY: | 3613 | case PRO_REGISTER_AND_IGNORE_EXISTING_KEY: |
3775 | ret = core_scsi3_emulate_pro_register(cmd, | 3614 | ret = core_scsi3_emulate_pro_register(cmd, |
3776 | 0, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 1); | 3615 | 0, sa_res_key, aptpl, all_tg_pt, spec_i_pt, REGISTER_AND_IGNORE_EXISTING_KEY); |
3777 | break; | 3616 | break; |
3778 | case PRO_REGISTER_AND_MOVE: | 3617 | case PRO_REGISTER_AND_MOVE: |
3779 | ret = core_scsi3_emulate_pro_register_and_move(cmd, res_key, | 3618 | ret = core_scsi3_emulate_pro_register_and_move(cmd, res_key, |
diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h index b4a004247ab2..ed75cdd32cb0 100644 --- a/drivers/target/target_core_pr.h +++ b/drivers/target/target_core_pr.h | |||
@@ -45,7 +45,7 @@ | |||
45 | 45 | ||
46 | extern struct kmem_cache *t10_pr_reg_cache; | 46 | extern struct kmem_cache *t10_pr_reg_cache; |
47 | 47 | ||
48 | extern int core_pr_dump_initiator_port(struct t10_pr_registration *, | 48 | extern void core_pr_dump_initiator_port(struct t10_pr_registration *, |
49 | char *, u32); | 49 | char *, u32); |
50 | extern sense_reason_t target_scsi2_reservation_release(struct se_cmd *); | 50 | extern sense_reason_t target_scsi2_reservation_release(struct se_cmd *); |
51 | extern sense_reason_t target_scsi2_reservation_reserve(struct se_cmd *); | 51 | extern sense_reason_t target_scsi2_reservation_reserve(struct se_cmd *); |
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 0921a64b5550..51127d15d5c5 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c | |||
@@ -139,6 +139,11 @@ static int rd_build_device_space(struct rd_dev *rd_dev) | |||
139 | rd_dev->rd_page_count); | 139 | rd_dev->rd_page_count); |
140 | return -EINVAL; | 140 | return -EINVAL; |
141 | } | 141 | } |
142 | |||
143 | /* Don't need backing pages for NULLIO */ | ||
144 | if (rd_dev->rd_flags & RDF_NULLIO) | ||
145 | return 0; | ||
146 | |||
142 | total_sg_needed = rd_dev->rd_page_count; | 147 | total_sg_needed = rd_dev->rd_page_count; |
143 | 148 | ||
144 | sg_tables = (total_sg_needed / max_sg_per_table) + 1; | 149 | sg_tables = (total_sg_needed / max_sg_per_table) + 1; |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index bbc5b0ee2bdc..8a462773d0c8 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -38,11 +38,27 @@ static sense_reason_t | |||
38 | sbc_emulate_readcapacity(struct se_cmd *cmd) | 38 | sbc_emulate_readcapacity(struct se_cmd *cmd) |
39 | { | 39 | { |
40 | struct se_device *dev = cmd->se_dev; | 40 | struct se_device *dev = cmd->se_dev; |
41 | unsigned char *cdb = cmd->t_task_cdb; | ||
41 | unsigned long long blocks_long = dev->transport->get_blocks(dev); | 42 | unsigned long long blocks_long = dev->transport->get_blocks(dev); |
42 | unsigned char *rbuf; | 43 | unsigned char *rbuf; |
43 | unsigned char buf[8]; | 44 | unsigned char buf[8]; |
44 | u32 blocks; | 45 | u32 blocks; |
45 | 46 | ||
47 | /* | ||
48 | * SBC-2 says: | ||
49 | * If the PMI bit is set to zero and the LOGICAL BLOCK | ||
50 | * ADDRESS field is not set to zero, the device server shall | ||
51 | * terminate the command with CHECK CONDITION status with | ||
52 | * the sense key set to ILLEGAL REQUEST and the additional | ||
53 | * sense code set to INVALID FIELD IN CDB. | ||
54 | * | ||
55 | * In SBC-3, these fields are obsolete, but some SCSI | ||
56 | * compliance tests actually check this, so we might as well | ||
57 | * follow SBC-2. | ||
58 | */ | ||
59 | if (!(cdb[8] & 1) && !!(cdb[2] | cdb[3] | cdb[4] | cdb[5])) | ||
60 | return TCM_INVALID_CDB_FIELD; | ||
61 | |||
46 | if (blocks_long >= 0x00000000ffffffff) | 62 | if (blocks_long >= 0x00000000ffffffff) |
47 | blocks = 0xffffffff; | 63 | blocks = 0xffffffff; |
48 | else | 64 | else |
@@ -581,7 +597,7 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
581 | pr_err("cmd exceeds last lba %llu " | 597 | pr_err("cmd exceeds last lba %llu " |
582 | "(lba %llu, sectors %u)\n", | 598 | "(lba %llu, sectors %u)\n", |
583 | end_lba, cmd->t_task_lba, sectors); | 599 | end_lba, cmd->t_task_lba, sectors); |
584 | return TCM_INVALID_CDB_FIELD; | 600 | return TCM_ADDRESS_OUT_OF_RANGE; |
585 | } | 601 | } |
586 | 602 | ||
587 | size = sbc_get_size(cmd, sectors); | 603 | size = sbc_get_size(cmd, sectors); |
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index d0b4dd95b91e..0d7cacb91107 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c | |||
@@ -85,13 +85,8 @@ void core_tmr_release_req( | |||
85 | static void core_tmr_handle_tas_abort( | 85 | static void core_tmr_handle_tas_abort( |
86 | struct se_node_acl *tmr_nacl, | 86 | struct se_node_acl *tmr_nacl, |
87 | struct se_cmd *cmd, | 87 | struct se_cmd *cmd, |
88 | int tas, | 88 | int tas) |
89 | int fe_count) | ||
90 | { | 89 | { |
91 | if (!fe_count) { | ||
92 | transport_cmd_finish_abort(cmd, 1); | ||
93 | return; | ||
94 | } | ||
95 | /* | 90 | /* |
96 | * TASK ABORTED status (TAS) bit support | 91 | * TASK ABORTED status (TAS) bit support |
97 | */ | 92 | */ |
@@ -253,7 +248,6 @@ static void core_tmr_drain_state_list( | |||
253 | LIST_HEAD(drain_task_list); | 248 | LIST_HEAD(drain_task_list); |
254 | struct se_cmd *cmd, *next; | 249 | struct se_cmd *cmd, *next; |
255 | unsigned long flags; | 250 | unsigned long flags; |
256 | int fe_count; | ||
257 | 251 | ||
258 | /* | 252 | /* |
259 | * Complete outstanding commands with TASK_ABORTED SAM status. | 253 | * Complete outstanding commands with TASK_ABORTED SAM status. |
@@ -329,12 +323,10 @@ static void core_tmr_drain_state_list( | |||
329 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 323 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
330 | target_stop_cmd(cmd, &flags); | 324 | target_stop_cmd(cmd, &flags); |
331 | 325 | ||
332 | fe_count = atomic_read(&cmd->t_fe_count); | ||
333 | |||
334 | cmd->transport_state |= CMD_T_ABORTED; | 326 | cmd->transport_state |= CMD_T_ABORTED; |
335 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 327 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
336 | 328 | ||
337 | core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, fe_count); | 329 | core_tmr_handle_tas_abort(tmr_nacl, cmd, tas); |
338 | } | 330 | } |
339 | } | 331 | } |
340 | 332 | ||
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 21e315874a54..7172d005d063 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -52,6 +52,9 @@ | |||
52 | #include "target_core_pr.h" | 52 | #include "target_core_pr.h" |
53 | #include "target_core_ua.h" | 53 | #include "target_core_ua.h" |
54 | 54 | ||
55 | #define CREATE_TRACE_POINTS | ||
56 | #include <trace/events/target.h> | ||
57 | |||
55 | static struct workqueue_struct *target_completion_wq; | 58 | static struct workqueue_struct *target_completion_wq; |
56 | static struct kmem_cache *se_sess_cache; | 59 | static struct kmem_cache *se_sess_cache; |
57 | struct kmem_cache *se_ua_cache; | 60 | struct kmem_cache *se_ua_cache; |
@@ -446,11 +449,15 @@ static void target_remove_from_state_list(struct se_cmd *cmd) | |||
446 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); | 449 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); |
447 | } | 450 | } |
448 | 451 | ||
449 | static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists) | 452 | static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists, |
453 | bool write_pending) | ||
450 | { | 454 | { |
451 | unsigned long flags; | 455 | unsigned long flags; |
452 | 456 | ||
453 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 457 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
458 | if (write_pending) | ||
459 | cmd->t_state = TRANSPORT_WRITE_PENDING; | ||
460 | |||
454 | /* | 461 | /* |
455 | * Determine if IOCTL context caller in requesting the stopping of this | 462 | * Determine if IOCTL context caller in requesting the stopping of this |
456 | * command for LUN shutdown purposes. | 463 | * command for LUN shutdown purposes. |
@@ -515,7 +522,7 @@ static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists) | |||
515 | 522 | ||
516 | static int transport_cmd_check_stop_to_fabric(struct se_cmd *cmd) | 523 | static int transport_cmd_check_stop_to_fabric(struct se_cmd *cmd) |
517 | { | 524 | { |
518 | return transport_cmd_check_stop(cmd, true); | 525 | return transport_cmd_check_stop(cmd, true, false); |
519 | } | 526 | } |
520 | 527 | ||
521 | static void transport_lun_remove_cmd(struct se_cmd *cmd) | 528 | static void transport_lun_remove_cmd(struct se_cmd *cmd) |
@@ -526,13 +533,6 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd) | |||
526 | if (!lun) | 533 | if (!lun) |
527 | return; | 534 | return; |
528 | 535 | ||
529 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
530 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { | ||
531 | cmd->transport_state &= ~CMD_T_DEV_ACTIVE; | ||
532 | target_remove_from_state_list(cmd); | ||
533 | } | ||
534 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
535 | |||
536 | spin_lock_irqsave(&lun->lun_cmd_lock, flags); | 536 | spin_lock_irqsave(&lun->lun_cmd_lock, flags); |
537 | if (!list_empty(&cmd->se_lun_node)) | 537 | if (!list_empty(&cmd->se_lun_node)) |
538 | list_del_init(&cmd->se_lun_node); | 538 | list_del_init(&cmd->se_lun_node); |
@@ -1092,7 +1092,6 @@ sense_reason_t | |||
1092 | target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb) | 1092 | target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb) |
1093 | { | 1093 | { |
1094 | struct se_device *dev = cmd->se_dev; | 1094 | struct se_device *dev = cmd->se_dev; |
1095 | unsigned long flags; | ||
1096 | sense_reason_t ret; | 1095 | sense_reason_t ret; |
1097 | 1096 | ||
1098 | /* | 1097 | /* |
@@ -1127,6 +1126,8 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb) | |||
1127 | */ | 1126 | */ |
1128 | memcpy(cmd->t_task_cdb, cdb, scsi_command_size(cdb)); | 1127 | memcpy(cmd->t_task_cdb, cdb, scsi_command_size(cdb)); |
1129 | 1128 | ||
1129 | trace_target_sequencer_start(cmd); | ||
1130 | |||
1130 | /* | 1131 | /* |
1131 | * Check for an existing UNIT ATTENTION condition | 1132 | * Check for an existing UNIT ATTENTION condition |
1132 | */ | 1133 | */ |
@@ -1152,9 +1153,7 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb) | |||
1152 | if (ret) | 1153 | if (ret) |
1153 | return ret; | 1154 | return ret; |
1154 | 1155 | ||
1155 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
1156 | cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE; | 1156 | cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE; |
1157 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1158 | 1157 | ||
1159 | spin_lock(&cmd->se_lun->lun_sep_lock); | 1158 | spin_lock(&cmd->se_lun->lun_sep_lock); |
1160 | if (cmd->se_lun->lun_sep) | 1159 | if (cmd->se_lun->lun_sep) |
@@ -1552,7 +1551,8 @@ void transport_generic_request_failure(struct se_cmd *cmd, | |||
1552 | cmd->orig_fe_lun, 0x2C, | 1551 | cmd->orig_fe_lun, 0x2C, |
1553 | ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS); | 1552 | ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS); |
1554 | 1553 | ||
1555 | ret = cmd->se_tfo->queue_status(cmd); | 1554 | trace_target_cmd_complete(cmd); |
1555 | ret = cmd->se_tfo-> queue_status(cmd); | ||
1556 | if (ret == -EAGAIN || ret == -ENOMEM) | 1556 | if (ret == -EAGAIN || ret == -ENOMEM) |
1557 | goto queue_full; | 1557 | goto queue_full; |
1558 | goto check_stop; | 1558 | goto check_stop; |
@@ -1583,10 +1583,6 @@ static void __target_execute_cmd(struct se_cmd *cmd) | |||
1583 | { | 1583 | { |
1584 | sense_reason_t ret; | 1584 | sense_reason_t ret; |
1585 | 1585 | ||
1586 | spin_lock_irq(&cmd->t_state_lock); | ||
1587 | cmd->transport_state |= (CMD_T_BUSY|CMD_T_SENT); | ||
1588 | spin_unlock_irq(&cmd->t_state_lock); | ||
1589 | |||
1590 | if (cmd->execute_cmd) { | 1586 | if (cmd->execute_cmd) { |
1591 | ret = cmd->execute_cmd(cmd); | 1587 | ret = cmd->execute_cmd(cmd); |
1592 | if (ret) { | 1588 | if (ret) { |
@@ -1693,11 +1689,17 @@ void target_execute_cmd(struct se_cmd *cmd) | |||
1693 | } | 1689 | } |
1694 | 1690 | ||
1695 | cmd->t_state = TRANSPORT_PROCESSING; | 1691 | cmd->t_state = TRANSPORT_PROCESSING; |
1696 | cmd->transport_state |= CMD_T_ACTIVE; | 1692 | cmd->transport_state |= CMD_T_ACTIVE|CMD_T_BUSY|CMD_T_SENT; |
1697 | spin_unlock_irq(&cmd->t_state_lock); | 1693 | spin_unlock_irq(&cmd->t_state_lock); |
1698 | 1694 | ||
1699 | if (!target_handle_task_attr(cmd)) | 1695 | if (target_handle_task_attr(cmd)) { |
1700 | __target_execute_cmd(cmd); | 1696 | spin_lock_irq(&cmd->t_state_lock); |
1697 | cmd->transport_state &= ~CMD_T_BUSY|CMD_T_SENT; | ||
1698 | spin_unlock_irq(&cmd->t_state_lock); | ||
1699 | return; | ||
1700 | } | ||
1701 | |||
1702 | __target_execute_cmd(cmd); | ||
1701 | } | 1703 | } |
1702 | EXPORT_SYMBOL(target_execute_cmd); | 1704 | EXPORT_SYMBOL(target_execute_cmd); |
1703 | 1705 | ||
@@ -1770,6 +1772,7 @@ static void transport_complete_qf(struct se_cmd *cmd) | |||
1770 | transport_complete_task_attr(cmd); | 1772 | transport_complete_task_attr(cmd); |
1771 | 1773 | ||
1772 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { | 1774 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { |
1775 | trace_target_cmd_complete(cmd); | ||
1773 | ret = cmd->se_tfo->queue_status(cmd); | 1776 | ret = cmd->se_tfo->queue_status(cmd); |
1774 | if (ret) | 1777 | if (ret) |
1775 | goto out; | 1778 | goto out; |
@@ -1777,6 +1780,7 @@ static void transport_complete_qf(struct se_cmd *cmd) | |||
1777 | 1780 | ||
1778 | switch (cmd->data_direction) { | 1781 | switch (cmd->data_direction) { |
1779 | case DMA_FROM_DEVICE: | 1782 | case DMA_FROM_DEVICE: |
1783 | trace_target_cmd_complete(cmd); | ||
1780 | ret = cmd->se_tfo->queue_data_in(cmd); | 1784 | ret = cmd->se_tfo->queue_data_in(cmd); |
1781 | break; | 1785 | break; |
1782 | case DMA_TO_DEVICE: | 1786 | case DMA_TO_DEVICE: |
@@ -1787,6 +1791,7 @@ static void transport_complete_qf(struct se_cmd *cmd) | |||
1787 | } | 1791 | } |
1788 | /* Fall through for DMA_TO_DEVICE */ | 1792 | /* Fall through for DMA_TO_DEVICE */ |
1789 | case DMA_NONE: | 1793 | case DMA_NONE: |
1794 | trace_target_cmd_complete(cmd); | ||
1790 | ret = cmd->se_tfo->queue_status(cmd); | 1795 | ret = cmd->se_tfo->queue_status(cmd); |
1791 | break; | 1796 | break; |
1792 | default: | 1797 | default: |
@@ -1865,6 +1870,7 @@ static void target_complete_ok_work(struct work_struct *work) | |||
1865 | } | 1870 | } |
1866 | spin_unlock(&cmd->se_lun->lun_sep_lock); | 1871 | spin_unlock(&cmd->se_lun->lun_sep_lock); |
1867 | 1872 | ||
1873 | trace_target_cmd_complete(cmd); | ||
1868 | ret = cmd->se_tfo->queue_data_in(cmd); | 1874 | ret = cmd->se_tfo->queue_data_in(cmd); |
1869 | if (ret == -EAGAIN || ret == -ENOMEM) | 1875 | if (ret == -EAGAIN || ret == -ENOMEM) |
1870 | goto queue_full; | 1876 | goto queue_full; |
@@ -1893,6 +1899,7 @@ static void target_complete_ok_work(struct work_struct *work) | |||
1893 | } | 1899 | } |
1894 | /* Fall through for DMA_TO_DEVICE */ | 1900 | /* Fall through for DMA_TO_DEVICE */ |
1895 | case DMA_NONE: | 1901 | case DMA_NONE: |
1902 | trace_target_cmd_complete(cmd); | ||
1896 | ret = cmd->se_tfo->queue_status(cmd); | 1903 | ret = cmd->se_tfo->queue_status(cmd); |
1897 | if (ret == -EAGAIN || ret == -ENOMEM) | 1904 | if (ret == -EAGAIN || ret == -ENOMEM) |
1898 | goto queue_full; | 1905 | goto queue_full; |
@@ -1956,11 +1963,7 @@ static int transport_release_cmd(struct se_cmd *cmd) | |||
1956 | * If this cmd has been setup with target_get_sess_cmd(), drop | 1963 | * If this cmd has been setup with target_get_sess_cmd(), drop |
1957 | * the kref and call ->release_cmd() in kref callback. | 1964 | * the kref and call ->release_cmd() in kref callback. |
1958 | */ | 1965 | */ |
1959 | if (cmd->check_release != 0) | 1966 | return target_put_sess_cmd(cmd->se_sess, cmd); |
1960 | return target_put_sess_cmd(cmd->se_sess, cmd); | ||
1961 | |||
1962 | cmd->se_tfo->release_cmd(cmd); | ||
1963 | return 1; | ||
1964 | } | 1967 | } |
1965 | 1968 | ||
1966 | /** | 1969 | /** |
@@ -1971,21 +1974,6 @@ static int transport_release_cmd(struct se_cmd *cmd) | |||
1971 | */ | 1974 | */ |
1972 | static int transport_put_cmd(struct se_cmd *cmd) | 1975 | static int transport_put_cmd(struct se_cmd *cmd) |
1973 | { | 1976 | { |
1974 | unsigned long flags; | ||
1975 | |||
1976 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
1977 | if (atomic_read(&cmd->t_fe_count) && | ||
1978 | !atomic_dec_and_test(&cmd->t_fe_count)) { | ||
1979 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1980 | return 0; | ||
1981 | } | ||
1982 | |||
1983 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { | ||
1984 | cmd->transport_state &= ~CMD_T_DEV_ACTIVE; | ||
1985 | target_remove_from_state_list(cmd); | ||
1986 | } | ||
1987 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1988 | |||
1989 | transport_free_pages(cmd); | 1977 | transport_free_pages(cmd); |
1990 | return transport_release_cmd(cmd); | 1978 | return transport_release_cmd(cmd); |
1991 | } | 1979 | } |
@@ -2103,9 +2091,6 @@ transport_generic_new_cmd(struct se_cmd *cmd) | |||
2103 | if (ret < 0) | 2091 | if (ret < 0) |
2104 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 2092 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2105 | } | 2093 | } |
2106 | |||
2107 | atomic_inc(&cmd->t_fe_count); | ||
2108 | |||
2109 | /* | 2094 | /* |
2110 | * If this command is not a write we can execute it right here, | 2095 | * If this command is not a write we can execute it right here, |
2111 | * for write buffers we need to notify the fabric driver first | 2096 | * for write buffers we need to notify the fabric driver first |
@@ -2116,12 +2101,7 @@ transport_generic_new_cmd(struct se_cmd *cmd) | |||
2116 | target_execute_cmd(cmd); | 2101 | target_execute_cmd(cmd); |
2117 | return 0; | 2102 | return 0; |
2118 | } | 2103 | } |
2119 | 2104 | transport_cmd_check_stop(cmd, false, true); | |
2120 | spin_lock_irq(&cmd->t_state_lock); | ||
2121 | cmd->t_state = TRANSPORT_WRITE_PENDING; | ||
2122 | spin_unlock_irq(&cmd->t_state_lock); | ||
2123 | |||
2124 | transport_cmd_check_stop(cmd, false); | ||
2125 | 2105 | ||
2126 | ret = cmd->se_tfo->write_pending(cmd); | 2106 | ret = cmd->se_tfo->write_pending(cmd); |
2127 | if (ret == -EAGAIN || ret == -ENOMEM) | 2107 | if (ret == -EAGAIN || ret == -ENOMEM) |
@@ -2202,8 +2182,6 @@ int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd, | |||
2202 | goto out; | 2182 | goto out; |
2203 | } | 2183 | } |
2204 | list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list); | 2184 | list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list); |
2205 | se_cmd->check_release = 1; | ||
2206 | |||
2207 | out: | 2185 | out: |
2208 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); | 2186 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
2209 | return ret; | 2187 | return ret; |
@@ -2319,7 +2297,7 @@ static int transport_lun_wait_for_tasks(struct se_cmd *cmd, struct se_lun *lun) | |||
2319 | pr_debug("ConfigFS ITT[0x%08x] - CMD_T_STOP, skipping\n", | 2297 | pr_debug("ConfigFS ITT[0x%08x] - CMD_T_STOP, skipping\n", |
2320 | cmd->se_tfo->get_task_tag(cmd)); | 2298 | cmd->se_tfo->get_task_tag(cmd)); |
2321 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 2299 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
2322 | transport_cmd_check_stop(cmd, false); | 2300 | transport_cmd_check_stop(cmd, false, false); |
2323 | return -EPERM; | 2301 | return -EPERM; |
2324 | } | 2302 | } |
2325 | cmd->transport_state |= CMD_T_LUN_FE_STOP; | 2303 | cmd->transport_state |= CMD_T_LUN_FE_STOP; |
@@ -2427,7 +2405,7 @@ check_cond: | |||
2427 | 2405 | ||
2428 | spin_unlock_irqrestore(&cmd->t_state_lock, | 2406 | spin_unlock_irqrestore(&cmd->t_state_lock, |
2429 | cmd_flags); | 2407 | cmd_flags); |
2430 | transport_cmd_check_stop(cmd, false); | 2408 | transport_cmd_check_stop(cmd, false, false); |
2431 | complete(&cmd->transport_lun_fe_stop_comp); | 2409 | complete(&cmd->transport_lun_fe_stop_comp); |
2432 | spin_lock_irqsave(&lun->lun_cmd_lock, lun_flags); | 2410 | spin_lock_irqsave(&lun->lun_cmd_lock, lun_flags); |
2433 | continue; | 2411 | continue; |
@@ -2778,6 +2756,7 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd, | |||
2778 | cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; | 2756 | cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; |
2779 | 2757 | ||
2780 | after_reason: | 2758 | after_reason: |
2759 | trace_target_cmd_complete(cmd); | ||
2781 | return cmd->se_tfo->queue_status(cmd); | 2760 | return cmd->se_tfo->queue_status(cmd); |
2782 | } | 2761 | } |
2783 | EXPORT_SYMBOL(transport_send_check_condition_and_sense); | 2762 | EXPORT_SYMBOL(transport_send_check_condition_and_sense); |
@@ -2794,6 +2773,7 @@ int transport_check_aborted_status(struct se_cmd *cmd, int send_status) | |||
2794 | cmd->t_task_cdb[0], cmd->se_tfo->get_task_tag(cmd)); | 2773 | cmd->t_task_cdb[0], cmd->se_tfo->get_task_tag(cmd)); |
2795 | 2774 | ||
2796 | cmd->se_cmd_flags |= SCF_SENT_DELAYED_TAS; | 2775 | cmd->se_cmd_flags |= SCF_SENT_DELAYED_TAS; |
2776 | trace_target_cmd_complete(cmd); | ||
2797 | cmd->se_tfo->queue_status(cmd); | 2777 | cmd->se_tfo->queue_status(cmd); |
2798 | 2778 | ||
2799 | return 1; | 2779 | return 1; |
@@ -2831,6 +2811,7 @@ void transport_send_task_abort(struct se_cmd *cmd) | |||
2831 | " ITT: 0x%08x\n", cmd->t_task_cdb[0], | 2811 | " ITT: 0x%08x\n", cmd->t_task_cdb[0], |
2832 | cmd->se_tfo->get_task_tag(cmd)); | 2812 | cmd->se_tfo->get_task_tag(cmd)); |
2833 | 2813 | ||
2814 | trace_target_cmd_complete(cmd); | ||
2834 | cmd->se_tfo->queue_status(cmd); | 2815 | cmd->se_tfo->queue_status(cmd); |
2835 | } | 2816 | } |
2836 | 2817 | ||
diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h index eea69358ced3..0dd54a44abcf 100644 --- a/drivers/target/tcm_fc/tcm_fc.h +++ b/drivers/target/tcm_fc/tcm_fc.h | |||
@@ -161,7 +161,7 @@ int ft_write_pending(struct se_cmd *); | |||
161 | int ft_write_pending_status(struct se_cmd *); | 161 | int ft_write_pending_status(struct se_cmd *); |
162 | u32 ft_get_task_tag(struct se_cmd *); | 162 | u32 ft_get_task_tag(struct se_cmd *); |
163 | int ft_get_cmd_state(struct se_cmd *); | 163 | int ft_get_cmd_state(struct se_cmd *); |
164 | int ft_queue_tm_resp(struct se_cmd *); | 164 | void ft_queue_tm_resp(struct se_cmd *); |
165 | 165 | ||
166 | /* | 166 | /* |
167 | * other internal functions. | 167 | * other internal functions. |
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index b406f178ff39..0e5a1caed176 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c | |||
@@ -394,14 +394,14 @@ static void ft_send_tm(struct ft_cmd *cmd) | |||
394 | /* | 394 | /* |
395 | * Send status from completed task management request. | 395 | * Send status from completed task management request. |
396 | */ | 396 | */ |
397 | int ft_queue_tm_resp(struct se_cmd *se_cmd) | 397 | void ft_queue_tm_resp(struct se_cmd *se_cmd) |
398 | { | 398 | { |
399 | struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd); | 399 | struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd); |
400 | struct se_tmr_req *tmr = se_cmd->se_tmr_req; | 400 | struct se_tmr_req *tmr = se_cmd->se_tmr_req; |
401 | enum fcp_resp_rsp_codes code; | 401 | enum fcp_resp_rsp_codes code; |
402 | 402 | ||
403 | if (cmd->aborted) | 403 | if (cmd->aborted) |
404 | return 0; | 404 | return; |
405 | switch (tmr->response) { | 405 | switch (tmr->response) { |
406 | case TMR_FUNCTION_COMPLETE: | 406 | case TMR_FUNCTION_COMPLETE: |
407 | code = FCP_TMF_CMPL; | 407 | code = FCP_TMF_CMPL; |
@@ -413,10 +413,7 @@ int ft_queue_tm_resp(struct se_cmd *se_cmd) | |||
413 | code = FCP_TMF_REJECTED; | 413 | code = FCP_TMF_REJECTED; |
414 | break; | 414 | break; |
415 | case TMR_TASK_DOES_NOT_EXIST: | 415 | case TMR_TASK_DOES_NOT_EXIST: |
416 | case TMR_TASK_STILL_ALLEGIANT: | ||
417 | case TMR_TASK_FAILOVER_NOT_SUPPORTED: | ||
418 | case TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED: | 416 | case TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED: |
419 | case TMR_FUNCTION_AUTHORIZATION_FAILED: | ||
420 | default: | 417 | default: |
421 | code = FCP_TMF_FAILED; | 418 | code = FCP_TMF_FAILED; |
422 | break; | 419 | break; |
@@ -424,7 +421,6 @@ int ft_queue_tm_resp(struct se_cmd *se_cmd) | |||
424 | pr_debug("tmr fn %d resp %d fcp code %d\n", | 421 | pr_debug("tmr fn %d resp %d fcp code %d\n", |
425 | tmr->function, tmr->response, code); | 422 | tmr->function, tmr->response, code); |
426 | ft_send_resp_code(cmd, code); | 423 | ft_send_resp_code(cmd, code); |
427 | return 0; | ||
428 | } | 424 | } |
429 | 425 | ||
430 | static void ft_send_work(struct work_struct *work); | 426 | static void ft_send_work(struct work_struct *work); |
diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 7cacd6ae818e..0ff33396eef3 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c | |||
@@ -1467,9 +1467,8 @@ static int usbg_get_cmd_state(struct se_cmd *se_cmd) | |||
1467 | return 0; | 1467 | return 0; |
1468 | } | 1468 | } |
1469 | 1469 | ||
1470 | static int usbg_queue_tm_rsp(struct se_cmd *se_cmd) | 1470 | static void usbg_queue_tm_rsp(struct se_cmd *se_cmd) |
1471 | { | 1471 | { |
1472 | return 0; | ||
1473 | } | 1472 | } |
1474 | 1473 | ||
1475 | static const char *usbg_check_wwn(const char *name) | 1474 | static const char *usbg_check_wwn(const char *name) |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 4264840ef7dc..06adf31a9248 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -448,7 +448,19 @@ static u32 tcm_vhost_tpg_get_inst_index(struct se_portal_group *se_tpg) | |||
448 | 448 | ||
449 | static void tcm_vhost_release_cmd(struct se_cmd *se_cmd) | 449 | static void tcm_vhost_release_cmd(struct se_cmd *se_cmd) |
450 | { | 450 | { |
451 | return; | 451 | struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd, |
452 | struct tcm_vhost_cmd, tvc_se_cmd); | ||
453 | |||
454 | if (tv_cmd->tvc_sgl_count) { | ||
455 | u32 i; | ||
456 | for (i = 0; i < tv_cmd->tvc_sgl_count; i++) | ||
457 | put_page(sg_page(&tv_cmd->tvc_sgl[i])); | ||
458 | |||
459 | kfree(tv_cmd->tvc_sgl); | ||
460 | } | ||
461 | |||
462 | tcm_vhost_put_inflight(tv_cmd->inflight); | ||
463 | kfree(tv_cmd); | ||
452 | } | 464 | } |
453 | 465 | ||
454 | static int tcm_vhost_shutdown_session(struct se_session *se_sess) | 466 | static int tcm_vhost_shutdown_session(struct se_session *se_sess) |
@@ -518,9 +530,9 @@ static int tcm_vhost_queue_status(struct se_cmd *se_cmd) | |||
518 | return 0; | 530 | return 0; |
519 | } | 531 | } |
520 | 532 | ||
521 | static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd) | 533 | static void tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd) |
522 | { | 534 | { |
523 | return 0; | 535 | return; |
524 | } | 536 | } |
525 | 537 | ||
526 | static void tcm_vhost_free_evt(struct vhost_scsi *vs, struct tcm_vhost_evt *evt) | 538 | static void tcm_vhost_free_evt(struct vhost_scsi *vs, struct tcm_vhost_evt *evt) |
@@ -560,19 +572,13 @@ static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *cmd) | |||
560 | struct se_cmd *se_cmd = &cmd->tvc_se_cmd; | 572 | struct se_cmd *se_cmd = &cmd->tvc_se_cmd; |
561 | 573 | ||
562 | /* TODO locking against target/backend threads? */ | 574 | /* TODO locking against target/backend threads? */ |
563 | transport_generic_free_cmd(se_cmd, 1); | 575 | transport_generic_free_cmd(se_cmd, 0); |
564 | 576 | ||
565 | if (cmd->tvc_sgl_count) { | 577 | } |
566 | u32 i; | ||
567 | for (i = 0; i < cmd->tvc_sgl_count; i++) | ||
568 | put_page(sg_page(&cmd->tvc_sgl[i])); | ||
569 | |||
570 | kfree(cmd->tvc_sgl); | ||
571 | } | ||
572 | |||
573 | tcm_vhost_put_inflight(cmd->inflight); | ||
574 | 578 | ||
575 | kfree(cmd); | 579 | static int vhost_scsi_check_stop_free(struct se_cmd *se_cmd) |
580 | { | ||
581 | return target_put_sess_cmd(se_cmd->se_sess, se_cmd); | ||
576 | } | 582 | } |
577 | 583 | ||
578 | static void | 584 | static void |
@@ -856,7 +862,7 @@ static void tcm_vhost_submission_work(struct work_struct *work) | |||
856 | cmd->tvc_cdb, &cmd->tvc_sense_buf[0], | 862 | cmd->tvc_cdb, &cmd->tvc_sense_buf[0], |
857 | cmd->tvc_lun, cmd->tvc_exp_data_len, | 863 | cmd->tvc_lun, cmd->tvc_exp_data_len, |
858 | cmd->tvc_task_attr, cmd->tvc_data_direction, | 864 | cmd->tvc_task_attr, cmd->tvc_data_direction, |
859 | 0, sg_ptr, cmd->tvc_sgl_count, | 865 | TARGET_SCF_ACK_KREF, sg_ptr, cmd->tvc_sgl_count, |
860 | sg_bidi_ptr, sg_no_bidi); | 866 | sg_bidi_ptr, sg_no_bidi); |
861 | if (rc < 0) { | 867 | if (rc < 0) { |
862 | transport_send_check_condition_and_sense(se_cmd, | 868 | transport_send_check_condition_and_sense(se_cmd, |
@@ -2028,6 +2034,7 @@ static struct target_core_fabric_ops tcm_vhost_ops = { | |||
2028 | .tpg_release_fabric_acl = tcm_vhost_release_fabric_acl, | 2034 | .tpg_release_fabric_acl = tcm_vhost_release_fabric_acl, |
2029 | .tpg_get_inst_index = tcm_vhost_tpg_get_inst_index, | 2035 | .tpg_get_inst_index = tcm_vhost_tpg_get_inst_index, |
2030 | .release_cmd = tcm_vhost_release_cmd, | 2036 | .release_cmd = tcm_vhost_release_cmd, |
2037 | .check_stop_free = vhost_scsi_check_stop_free, | ||
2031 | .shutdown_session = tcm_vhost_shutdown_session, | 2038 | .shutdown_session = tcm_vhost_shutdown_session, |
2032 | .close_session = tcm_vhost_close_session, | 2039 | .close_session = tcm_vhost_close_session, |
2033 | .sess_get_index = tcm_vhost_sess_get_index, | 2040 | .sess_get_index = tcm_vhost_sess_get_index, |
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h index 23a87d0cd72c..e5d09d242ba3 100644 --- a/include/target/iscsi/iscsi_transport.h +++ b/include/target/iscsi/iscsi_transport.h | |||
@@ -34,8 +34,6 @@ extern void iscsit_put_transport(struct iscsit_transport *); | |||
34 | /* | 34 | /* |
35 | * From iscsi_target.c | 35 | * From iscsi_target.c |
36 | */ | 36 | */ |
37 | extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *, | ||
38 | struct iscsi_cmd *); | ||
39 | extern int iscsit_setup_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *, | 37 | extern int iscsit_setup_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *, |
40 | unsigned char *); | 38 | unsigned char *); |
41 | extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); | 39 | extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); |
@@ -45,18 +43,26 @@ extern int iscsit_check_dataout_hdr(struct iscsi_conn *, unsigned char *, | |||
45 | struct iscsi_cmd **); | 43 | struct iscsi_cmd **); |
46 | extern int iscsit_check_dataout_payload(struct iscsi_cmd *, struct iscsi_data *, | 44 | extern int iscsit_check_dataout_payload(struct iscsi_cmd *, struct iscsi_data *, |
47 | bool); | 45 | bool); |
48 | extern int iscsit_handle_nop_out(struct iscsi_conn *, struct iscsi_cmd *, | 46 | extern int iscsit_setup_nop_out(struct iscsi_conn *, struct iscsi_cmd *, |
49 | unsigned char *); | 47 | struct iscsi_nopout *); |
48 | extern int iscsit_process_nop_out(struct iscsi_conn *, struct iscsi_cmd *, | ||
49 | struct iscsi_nopout *); | ||
50 | extern int iscsit_handle_logout_cmd(struct iscsi_conn *, struct iscsi_cmd *, | 50 | extern int iscsit_handle_logout_cmd(struct iscsi_conn *, struct iscsi_cmd *, |
51 | unsigned char *); | 51 | unsigned char *); |
52 | extern int iscsit_handle_task_mgt_cmd(struct iscsi_conn *, struct iscsi_cmd *, | 52 | extern int iscsit_handle_task_mgt_cmd(struct iscsi_conn *, struct iscsi_cmd *, |
53 | unsigned char *); | 53 | unsigned char *); |
54 | extern int iscsit_setup_text_cmd(struct iscsi_conn *, struct iscsi_cmd *, | ||
55 | struct iscsi_text *); | ||
56 | extern int iscsit_process_text_cmd(struct iscsi_conn *, struct iscsi_cmd *, | ||
57 | struct iscsi_text *); | ||
54 | extern void iscsit_build_rsp_pdu(struct iscsi_cmd *, struct iscsi_conn *, | 58 | extern void iscsit_build_rsp_pdu(struct iscsi_cmd *, struct iscsi_conn *, |
55 | bool, struct iscsi_scsi_rsp *); | 59 | bool, struct iscsi_scsi_rsp *); |
56 | extern void iscsit_build_nopin_rsp(struct iscsi_cmd *, struct iscsi_conn *, | 60 | extern void iscsit_build_nopin_rsp(struct iscsi_cmd *, struct iscsi_conn *, |
57 | struct iscsi_nopin *, bool); | 61 | struct iscsi_nopin *, bool); |
58 | extern void iscsit_build_task_mgt_rsp(struct iscsi_cmd *, struct iscsi_conn *, | 62 | extern void iscsit_build_task_mgt_rsp(struct iscsi_cmd *, struct iscsi_conn *, |
59 | struct iscsi_tm_rsp *); | 63 | struct iscsi_tm_rsp *); |
64 | extern int iscsit_build_text_rsp(struct iscsi_cmd *, struct iscsi_conn *, | ||
65 | struct iscsi_text_rsp *); | ||
60 | extern void iscsit_build_reject(struct iscsi_cmd *, struct iscsi_conn *, | 66 | extern void iscsit_build_reject(struct iscsi_cmd *, struct iscsi_conn *, |
61 | struct iscsi_reject *); | 67 | struct iscsi_reject *); |
62 | extern int iscsit_build_logout_rsp(struct iscsi_cmd *, struct iscsi_conn *, | 68 | extern int iscsit_build_logout_rsp(struct iscsi_cmd *, struct iscsi_conn *, |
@@ -67,6 +73,10 @@ extern int iscsit_logout_post_handler(struct iscsi_cmd *, struct iscsi_conn *); | |||
67 | */ | 73 | */ |
68 | extern void iscsit_increment_maxcmdsn(struct iscsi_cmd *, struct iscsi_session *); | 74 | extern void iscsit_increment_maxcmdsn(struct iscsi_cmd *, struct iscsi_session *); |
69 | /* | 75 | /* |
76 | * From iscsi_target_erl0.c | ||
77 | */ | ||
78 | extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int); | ||
79 | /* | ||
70 | * From iscsi_target_erl1.c | 80 | * From iscsi_target_erl1.c |
71 | */ | 81 | */ |
72 | extern void iscsit_stop_dataout_timer(struct iscsi_cmd *); | 82 | extern void iscsit_stop_dataout_timer(struct iscsi_cmd *); |
@@ -80,4 +90,5 @@ extern int iscsit_tmr_post_handler(struct iscsi_cmd *, struct iscsi_conn *); | |||
80 | * From iscsi_target_util.c | 90 | * From iscsi_target_util.c |
81 | */ | 91 | */ |
82 | extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t); | 92 | extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t); |
83 | extern int iscsit_sequence_cmd(struct iscsi_conn *, struct iscsi_cmd *, __be32); | 93 | extern int iscsit_sequence_cmd(struct iscsi_conn *, struct iscsi_cmd *, |
94 | unsigned char *, __be32); | ||
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 4ea4f985f394..e34fc904f2e1 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -218,14 +218,11 @@ enum tcm_tmreq_table { | |||
218 | 218 | ||
219 | /* fabric independent task management response values */ | 219 | /* fabric independent task management response values */ |
220 | enum tcm_tmrsp_table { | 220 | enum tcm_tmrsp_table { |
221 | TMR_FUNCTION_COMPLETE = 0, | 221 | TMR_FUNCTION_COMPLETE = 1, |
222 | TMR_TASK_DOES_NOT_EXIST = 1, | 222 | TMR_TASK_DOES_NOT_EXIST = 2, |
223 | TMR_LUN_DOES_NOT_EXIST = 2, | 223 | TMR_LUN_DOES_NOT_EXIST = 3, |
224 | TMR_TASK_STILL_ALLEGIANT = 3, | 224 | TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED = 4, |
225 | TMR_TASK_FAILOVER_NOT_SUPPORTED = 4, | 225 | TMR_FUNCTION_REJECTED = 5, |
226 | TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED = 5, | ||
227 | TMR_FUNCTION_AUTHORIZATION_FAILED = 6, | ||
228 | TMR_FUNCTION_REJECTED = 255, | ||
229 | }; | 226 | }; |
230 | 227 | ||
231 | /* | 228 | /* |
@@ -339,8 +336,6 @@ struct t10_pr_registration { | |||
339 | /* Used during APTPL metadata reading */ | 336 | /* Used during APTPL metadata reading */ |
340 | #define PR_APTPL_MAX_TPORT_LEN 256 | 337 | #define PR_APTPL_MAX_TPORT_LEN 256 |
341 | unsigned char pr_tport[PR_APTPL_MAX_TPORT_LEN]; | 338 | unsigned char pr_tport[PR_APTPL_MAX_TPORT_LEN]; |
342 | /* For writing out live meta data */ | ||
343 | unsigned char *pr_aptpl_buf; | ||
344 | u16 pr_aptpl_rpti; | 339 | u16 pr_aptpl_rpti; |
345 | u16 pr_reg_tpgt; | 340 | u16 pr_reg_tpgt; |
346 | /* Reservation effects all target ports */ | 341 | /* Reservation effects all target ports */ |
@@ -374,9 +369,7 @@ struct t10_reservation { | |||
374 | /* Activate Persistence across Target Power Loss enabled | 369 | /* Activate Persistence across Target Power Loss enabled |
375 | * for SCSI device */ | 370 | * for SCSI device */ |
376 | int pr_aptpl_active; | 371 | int pr_aptpl_active; |
377 | /* Used by struct t10_reservation->pr_aptpl_buf_len */ | ||
378 | #define PR_APTPL_BUF_LEN 8192 | 372 | #define PR_APTPL_BUF_LEN 8192 |
379 | u32 pr_aptpl_buf_len; | ||
380 | u32 pr_generation; | 373 | u32 pr_generation; |
381 | spinlock_t registration_lock; | 374 | spinlock_t registration_lock; |
382 | spinlock_t aptpl_reg_lock; | 375 | spinlock_t aptpl_reg_lock; |
@@ -424,8 +417,6 @@ struct se_cmd { | |||
424 | int sam_task_attr; | 417 | int sam_task_attr; |
425 | /* Transport protocol dependent state, see transport_state_table */ | 418 | /* Transport protocol dependent state, see transport_state_table */ |
426 | enum transport_state_table t_state; | 419 | enum transport_state_table t_state; |
427 | /* Used to signal cmd->se_tfo->check_release_cmd() usage per cmd */ | ||
428 | unsigned check_release:1; | ||
429 | unsigned cmd_wait_set:1; | 420 | unsigned cmd_wait_set:1; |
430 | unsigned unknown_data_length:1; | 421 | unsigned unknown_data_length:1; |
431 | /* See se_cmd_flags_table */ | 422 | /* See se_cmd_flags_table */ |
@@ -458,7 +449,6 @@ struct se_cmd { | |||
458 | unsigned char *t_task_cdb; | 449 | unsigned char *t_task_cdb; |
459 | unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE]; | 450 | unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE]; |
460 | unsigned long long t_task_lba; | 451 | unsigned long long t_task_lba; |
461 | atomic_t t_fe_count; | ||
462 | unsigned int transport_state; | 452 | unsigned int transport_state; |
463 | #define CMD_T_ABORTED (1 << 0) | 453 | #define CMD_T_ABORTED (1 << 0) |
464 | #define CMD_T_ACTIVE (1 << 1) | 454 | #define CMD_T_ACTIVE (1 << 1) |
@@ -802,11 +792,12 @@ struct se_portal_group { | |||
802 | struct target_core_fabric_ops *se_tpg_tfo; | 792 | struct target_core_fabric_ops *se_tpg_tfo; |
803 | struct se_wwn *se_tpg_wwn; | 793 | struct se_wwn *se_tpg_wwn; |
804 | struct config_group tpg_group; | 794 | struct config_group tpg_group; |
805 | struct config_group *tpg_default_groups[6]; | 795 | struct config_group *tpg_default_groups[7]; |
806 | struct config_group tpg_lun_group; | 796 | struct config_group tpg_lun_group; |
807 | struct config_group tpg_np_group; | 797 | struct config_group tpg_np_group; |
808 | struct config_group tpg_acl_group; | 798 | struct config_group tpg_acl_group; |
809 | struct config_group tpg_attrib_group; | 799 | struct config_group tpg_attrib_group; |
800 | struct config_group tpg_auth_group; | ||
810 | struct config_group tpg_param_group; | 801 | struct config_group tpg_param_group; |
811 | }; | 802 | }; |
812 | 803 | ||
diff --git a/include/target/target_core_configfs.h b/include/target/target_core_configfs.h index 612509592ffd..713c5004f4ae 100644 --- a/include/target/target_core_configfs.h +++ b/include/target/target_core_configfs.h | |||
@@ -23,6 +23,7 @@ struct target_fabric_configfs_template { | |||
23 | struct config_item_type tfc_tpg_np_cit; | 23 | struct config_item_type tfc_tpg_np_cit; |
24 | struct config_item_type tfc_tpg_np_base_cit; | 24 | struct config_item_type tfc_tpg_np_base_cit; |
25 | struct config_item_type tfc_tpg_attrib_cit; | 25 | struct config_item_type tfc_tpg_attrib_cit; |
26 | struct config_item_type tfc_tpg_auth_cit; | ||
26 | struct config_item_type tfc_tpg_param_cit; | 27 | struct config_item_type tfc_tpg_param_cit; |
27 | struct config_item_type tfc_tpg_nacl_cit; | 28 | struct config_item_type tfc_tpg_nacl_cit; |
28 | struct config_item_type tfc_tpg_nacl_base_cit; | 29 | struct config_item_type tfc_tpg_nacl_base_cit; |
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 1dcce9cc99b9..7a16178424f9 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h | |||
@@ -61,7 +61,7 @@ struct target_core_fabric_ops { | |||
61 | int (*get_cmd_state)(struct se_cmd *); | 61 | int (*get_cmd_state)(struct se_cmd *); |
62 | int (*queue_data_in)(struct se_cmd *); | 62 | int (*queue_data_in)(struct se_cmd *); |
63 | int (*queue_status)(struct se_cmd *); | 63 | int (*queue_status)(struct se_cmd *); |
64 | int (*queue_tm_rsp)(struct se_cmd *); | 64 | void (*queue_tm_rsp)(struct se_cmd *); |
65 | /* | 65 | /* |
66 | * fabric module calls for target_core_fabric_configfs.c | 66 | * fabric module calls for target_core_fabric_configfs.c |
67 | */ | 67 | */ |
diff --git a/include/target/target_core_fabric_configfs.h b/include/target/target_core_fabric_configfs.h index a26fb7586a09..b32a14905cfa 100644 --- a/include/target/target_core_fabric_configfs.h +++ b/include/target/target_core_fabric_configfs.h | |||
@@ -62,6 +62,17 @@ static struct target_fabric_tpg_attrib_attribute _fabric##_tpg_attrib_##_name = | |||
62 | _fabric##_tpg_attrib_show_##_name, \ | 62 | _fabric##_tpg_attrib_show_##_name, \ |
63 | _fabric##_tpg_attrib_store_##_name); | 63 | _fabric##_tpg_attrib_store_##_name); |
64 | 64 | ||
65 | CONFIGFS_EATTR_STRUCT(target_fabric_tpg_auth, se_portal_group); | ||
66 | #define TF_TPG_AUTH_ATTR(_fabric, _name, _mode) \ | ||
67 | static struct target_fabric_tpg_auth_attribute _fabric##_tpg_auth_##_name = \ | ||
68 | __CONFIGFS_EATTR(_name, _mode, \ | ||
69 | _fabric##_tpg_auth_show_##_name, \ | ||
70 | _fabric##_tpg_auth_store_##_name); | ||
71 | |||
72 | #define TF_TPG_AUTH_ATTR_RO(_fabric, _name) \ | ||
73 | static struct target_fabric_tpg_auth_attribute _fabric##_tpg_auth_##_name = \ | ||
74 | __CONFIGFS_EATTR_RO(_name, \ | ||
75 | _fabric##_tpg_auth_show_##_name); | ||
65 | 76 | ||
66 | CONFIGFS_EATTR_STRUCT(target_fabric_tpg_param, se_portal_group); | 77 | CONFIGFS_EATTR_STRUCT(target_fabric_tpg_param, se_portal_group); |
67 | #define TF_TPG_PARAM_ATTR(_fabric, _name, _mode) \ | 78 | #define TF_TPG_PARAM_ATTR(_fabric, _name, _mode) \ |
diff --git a/include/trace/events/target.h b/include/trace/events/target.h new file mode 100644 index 000000000000..aef8fc354025 --- /dev/null +++ b/include/trace/events/target.h | |||
@@ -0,0 +1,214 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM target | ||
3 | |||
4 | #if !defined(_TRACE_TARGET_H) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define _TRACE_TARGET_H | ||
6 | |||
7 | #include <linux/tracepoint.h> | ||
8 | #include <linux/trace_seq.h> | ||
9 | #include <scsi/scsi.h> | ||
10 | #include <scsi/scsi_tcq.h> | ||
11 | #include <target/target_core_base.h> | ||
12 | |||
13 | /* cribbed verbatim from <trace/event/scsi.h> */ | ||
14 | #define scsi_opcode_name(opcode) { opcode, #opcode } | ||
15 | #define show_opcode_name(val) \ | ||
16 | __print_symbolic(val, \ | ||
17 | scsi_opcode_name(TEST_UNIT_READY), \ | ||
18 | scsi_opcode_name(REZERO_UNIT), \ | ||
19 | scsi_opcode_name(REQUEST_SENSE), \ | ||
20 | scsi_opcode_name(FORMAT_UNIT), \ | ||
21 | scsi_opcode_name(READ_BLOCK_LIMITS), \ | ||
22 | scsi_opcode_name(REASSIGN_BLOCKS), \ | ||
23 | scsi_opcode_name(INITIALIZE_ELEMENT_STATUS), \ | ||
24 | scsi_opcode_name(READ_6), \ | ||
25 | scsi_opcode_name(WRITE_6), \ | ||
26 | scsi_opcode_name(SEEK_6), \ | ||
27 | scsi_opcode_name(READ_REVERSE), \ | ||
28 | scsi_opcode_name(WRITE_FILEMARKS), \ | ||
29 | scsi_opcode_name(SPACE), \ | ||
30 | scsi_opcode_name(INQUIRY), \ | ||
31 | scsi_opcode_name(RECOVER_BUFFERED_DATA), \ | ||
32 | scsi_opcode_name(MODE_SELECT), \ | ||
33 | scsi_opcode_name(RESERVE), \ | ||
34 | scsi_opcode_name(RELEASE), \ | ||
35 | scsi_opcode_name(COPY), \ | ||
36 | scsi_opcode_name(ERASE), \ | ||
37 | scsi_opcode_name(MODE_SENSE), \ | ||
38 | scsi_opcode_name(START_STOP), \ | ||
39 | scsi_opcode_name(RECEIVE_DIAGNOSTIC), \ | ||
40 | scsi_opcode_name(SEND_DIAGNOSTIC), \ | ||
41 | scsi_opcode_name(ALLOW_MEDIUM_REMOVAL), \ | ||
42 | scsi_opcode_name(SET_WINDOW), \ | ||
43 | scsi_opcode_name(READ_CAPACITY), \ | ||
44 | scsi_opcode_name(READ_10), \ | ||
45 | scsi_opcode_name(WRITE_10), \ | ||
46 | scsi_opcode_name(SEEK_10), \ | ||
47 | scsi_opcode_name(POSITION_TO_ELEMENT), \ | ||
48 | scsi_opcode_name(WRITE_VERIFY), \ | ||
49 | scsi_opcode_name(VERIFY), \ | ||
50 | scsi_opcode_name(SEARCH_HIGH), \ | ||
51 | scsi_opcode_name(SEARCH_EQUAL), \ | ||
52 | scsi_opcode_name(SEARCH_LOW), \ | ||
53 | scsi_opcode_name(SET_LIMITS), \ | ||
54 | scsi_opcode_name(PRE_FETCH), \ | ||
55 | scsi_opcode_name(READ_POSITION), \ | ||
56 | scsi_opcode_name(SYNCHRONIZE_CACHE), \ | ||
57 | scsi_opcode_name(LOCK_UNLOCK_CACHE), \ | ||
58 | scsi_opcode_name(READ_DEFECT_DATA), \ | ||
59 | scsi_opcode_name(MEDIUM_SCAN), \ | ||
60 | scsi_opcode_name(COMPARE), \ | ||
61 | scsi_opcode_name(COPY_VERIFY), \ | ||
62 | scsi_opcode_name(WRITE_BUFFER), \ | ||
63 | scsi_opcode_name(READ_BUFFER), \ | ||
64 | scsi_opcode_name(UPDATE_BLOCK), \ | ||
65 | scsi_opcode_name(READ_LONG), \ | ||
66 | scsi_opcode_name(WRITE_LONG), \ | ||
67 | scsi_opcode_name(CHANGE_DEFINITION), \ | ||
68 | scsi_opcode_name(WRITE_SAME), \ | ||
69 | scsi_opcode_name(UNMAP), \ | ||
70 | scsi_opcode_name(READ_TOC), \ | ||
71 | scsi_opcode_name(LOG_SELECT), \ | ||
72 | scsi_opcode_name(LOG_SENSE), \ | ||
73 | scsi_opcode_name(XDWRITEREAD_10), \ | ||
74 | scsi_opcode_name(MODE_SELECT_10), \ | ||
75 | scsi_opcode_name(RESERVE_10), \ | ||
76 | scsi_opcode_name(RELEASE_10), \ | ||
77 | scsi_opcode_name(MODE_SENSE_10), \ | ||
78 | scsi_opcode_name(PERSISTENT_RESERVE_IN), \ | ||
79 | scsi_opcode_name(PERSISTENT_RESERVE_OUT), \ | ||
80 | scsi_opcode_name(VARIABLE_LENGTH_CMD), \ | ||
81 | scsi_opcode_name(REPORT_LUNS), \ | ||
82 | scsi_opcode_name(MAINTENANCE_IN), \ | ||
83 | scsi_opcode_name(MAINTENANCE_OUT), \ | ||
84 | scsi_opcode_name(MOVE_MEDIUM), \ | ||
85 | scsi_opcode_name(EXCHANGE_MEDIUM), \ | ||
86 | scsi_opcode_name(READ_12), \ | ||
87 | scsi_opcode_name(WRITE_12), \ | ||
88 | scsi_opcode_name(WRITE_VERIFY_12), \ | ||
89 | scsi_opcode_name(SEARCH_HIGH_12), \ | ||
90 | scsi_opcode_name(SEARCH_EQUAL_12), \ | ||
91 | scsi_opcode_name(SEARCH_LOW_12), \ | ||
92 | scsi_opcode_name(READ_ELEMENT_STATUS), \ | ||
93 | scsi_opcode_name(SEND_VOLUME_TAG), \ | ||
94 | scsi_opcode_name(WRITE_LONG_2), \ | ||
95 | scsi_opcode_name(READ_16), \ | ||
96 | scsi_opcode_name(WRITE_16), \ | ||
97 | scsi_opcode_name(VERIFY_16), \ | ||
98 | scsi_opcode_name(WRITE_SAME_16), \ | ||
99 | scsi_opcode_name(SERVICE_ACTION_IN), \ | ||
100 | scsi_opcode_name(SAI_READ_CAPACITY_16), \ | ||
101 | scsi_opcode_name(SAI_GET_LBA_STATUS), \ | ||
102 | scsi_opcode_name(MI_REPORT_TARGET_PGS), \ | ||
103 | scsi_opcode_name(MO_SET_TARGET_PGS), \ | ||
104 | scsi_opcode_name(READ_32), \ | ||
105 | scsi_opcode_name(WRITE_32), \ | ||
106 | scsi_opcode_name(WRITE_SAME_32), \ | ||
107 | scsi_opcode_name(ATA_16), \ | ||
108 | scsi_opcode_name(ATA_12)) | ||
109 | |||
110 | #define show_task_attribute_name(val) \ | ||
111 | __print_symbolic(val, \ | ||
112 | { MSG_SIMPLE_TAG, "SIMPLE" }, \ | ||
113 | { MSG_HEAD_TAG, "HEAD" }, \ | ||
114 | { MSG_ORDERED_TAG, "ORDERED" }, \ | ||
115 | { MSG_ACA_TAG, "ACA" } ) | ||
116 | |||
117 | #define show_scsi_status_name(val) \ | ||
118 | __print_symbolic(val, \ | ||
119 | { SAM_STAT_GOOD, "GOOD" }, \ | ||
120 | { SAM_STAT_CHECK_CONDITION, "CHECK CONDITION" }, \ | ||
121 | { SAM_STAT_CONDITION_MET, "CONDITION MET" }, \ | ||
122 | { SAM_STAT_BUSY, "BUSY" }, \ | ||
123 | { SAM_STAT_INTERMEDIATE, "INTERMEDIATE" }, \ | ||
124 | { SAM_STAT_INTERMEDIATE_CONDITION_MET, "INTERMEDIATE CONDITION MET" }, \ | ||
125 | { SAM_STAT_RESERVATION_CONFLICT, "RESERVATION CONFLICT" }, \ | ||
126 | { SAM_STAT_COMMAND_TERMINATED, "COMMAND TERMINATED" }, \ | ||
127 | { SAM_STAT_TASK_SET_FULL, "TASK SET FULL" }, \ | ||
128 | { SAM_STAT_ACA_ACTIVE, "ACA ACTIVE" }, \ | ||
129 | { SAM_STAT_TASK_ABORTED, "TASK ABORTED" } ) | ||
130 | |||
131 | TRACE_EVENT(target_sequencer_start, | ||
132 | |||
133 | TP_PROTO(struct se_cmd *cmd), | ||
134 | |||
135 | TP_ARGS(cmd), | ||
136 | |||
137 | TP_STRUCT__entry( | ||
138 | __field( unsigned int, unpacked_lun ) | ||
139 | __field( unsigned int, opcode ) | ||
140 | __field( unsigned int, data_length ) | ||
141 | __field( unsigned int, task_attribute ) | ||
142 | __array( unsigned char, cdb, TCM_MAX_COMMAND_SIZE ) | ||
143 | __string( initiator, cmd->se_sess->se_node_acl->initiatorname ) | ||
144 | ), | ||
145 | |||
146 | TP_fast_assign( | ||
147 | __entry->unpacked_lun = cmd->se_lun->unpacked_lun; | ||
148 | __entry->opcode = cmd->t_task_cdb[0]; | ||
149 | __entry->data_length = cmd->data_length; | ||
150 | __entry->task_attribute = cmd->sam_task_attr; | ||
151 | memcpy(__entry->cdb, cmd->t_task_cdb, TCM_MAX_COMMAND_SIZE); | ||
152 | __assign_str(initiator, cmd->se_sess->se_node_acl->initiatorname); | ||
153 | ), | ||
154 | |||
155 | TP_printk("%s -> LUN %03u %s data_length %6u CDB %s (TA:%s C:%02x)", | ||
156 | __get_str(initiator), __entry->unpacked_lun, | ||
157 | show_opcode_name(__entry->opcode), | ||
158 | __entry->data_length, __print_hex(__entry->cdb, 16), | ||
159 | show_task_attribute_name(__entry->task_attribute), | ||
160 | scsi_command_size(__entry->cdb) <= 16 ? | ||
161 | __entry->cdb[scsi_command_size(__entry->cdb) - 1] : | ||
162 | __entry->cdb[1] | ||
163 | ) | ||
164 | ); | ||
165 | |||
166 | TRACE_EVENT(target_cmd_complete, | ||
167 | |||
168 | TP_PROTO(struct se_cmd *cmd), | ||
169 | |||
170 | TP_ARGS(cmd), | ||
171 | |||
172 | TP_STRUCT__entry( | ||
173 | __field( unsigned int, unpacked_lun ) | ||
174 | __field( unsigned int, opcode ) | ||
175 | __field( unsigned int, data_length ) | ||
176 | __field( unsigned int, task_attribute ) | ||
177 | __field( unsigned char, scsi_status ) | ||
178 | __field( unsigned char, sense_length ) | ||
179 | __array( unsigned char, cdb, TCM_MAX_COMMAND_SIZE ) | ||
180 | __array( unsigned char, sense_data, 18 ) | ||
181 | __string(initiator, cmd->se_sess->se_node_acl->initiatorname) | ||
182 | ), | ||
183 | |||
184 | TP_fast_assign( | ||
185 | __entry->unpacked_lun = cmd->se_lun->unpacked_lun; | ||
186 | __entry->opcode = cmd->t_task_cdb[0]; | ||
187 | __entry->data_length = cmd->data_length; | ||
188 | __entry->task_attribute = cmd->sam_task_attr; | ||
189 | __entry->scsi_status = cmd->scsi_status; | ||
190 | __entry->sense_length = cmd->scsi_status == SAM_STAT_CHECK_CONDITION ? | ||
191 | min(18, ((u8 *) cmd->sense_buffer)[SPC_ADD_SENSE_LEN_OFFSET] + 8) : 0; | ||
192 | memcpy(__entry->cdb, cmd->t_task_cdb, TCM_MAX_COMMAND_SIZE); | ||
193 | memcpy(__entry->sense_data, cmd->sense_buffer, __entry->sense_length); | ||
194 | __assign_str(initiator, cmd->se_sess->se_node_acl->initiatorname); | ||
195 | ), | ||
196 | |||
197 | TP_printk("%s <- LUN %03u status %s (sense len %d%s%s) %s data_length %6u CDB %s (TA:%s C:%02x)", | ||
198 | __get_str(initiator), __entry->unpacked_lun, | ||
199 | show_scsi_status_name(__entry->scsi_status), | ||
200 | __entry->sense_length, __entry->sense_length ? " / " : "", | ||
201 | __print_hex(__entry->sense_data, __entry->sense_length), | ||
202 | show_opcode_name(__entry->opcode), | ||
203 | __entry->data_length, __print_hex(__entry->cdb, 16), | ||
204 | show_task_attribute_name(__entry->task_attribute), | ||
205 | scsi_command_size(__entry->cdb) <= 16 ? | ||
206 | __entry->cdb[scsi_command_size(__entry->cdb) - 1] : | ||
207 | __entry->cdb[1] | ||
208 | ) | ||
209 | ); | ||
210 | |||
211 | #endif /* _TRACE_TARGET_H */ | ||
212 | |||
213 | /* This part must be outside protection */ | ||
214 | #include <trace/define_trace.h> | ||