diff options
| -rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.c | 293 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.h | 21 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_parameters.c | 5 | ||||
| -rw-r--r-- | drivers/target/target_core_device.c | 45 | ||||
| -rw-r--r-- | drivers/target/target_core_hba.c | 2 | ||||
| -rw-r--r-- | drivers/target/target_core_iblock.c | 2 | ||||
| -rw-r--r-- | drivers/target/target_core_pr.c | 91 | ||||
| -rw-r--r-- | drivers/target/target_core_tpg.c | 5 | ||||
| -rw-r--r-- | include/target/target_core_base.h | 1 |
9 files changed, 299 insertions, 166 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 403bd29443b8..aa59037d7504 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
| @@ -238,8 +238,6 @@ isert_alloc_rx_descriptors(struct isert_conn *isert_conn) | |||
| 238 | rx_sg->lkey = device->pd->local_dma_lkey; | 238 | rx_sg->lkey = device->pd->local_dma_lkey; |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | isert_conn->rx_desc_head = 0; | ||
| 242 | |||
| 243 | return 0; | 241 | return 0; |
| 244 | 242 | ||
| 245 | dma_map_fail: | 243 | dma_map_fail: |
| @@ -634,7 +632,7 @@ static void | |||
| 634 | isert_init_conn(struct isert_conn *isert_conn) | 632 | isert_init_conn(struct isert_conn *isert_conn) |
| 635 | { | 633 | { |
| 636 | isert_conn->state = ISER_CONN_INIT; | 634 | isert_conn->state = ISER_CONN_INIT; |
| 637 | INIT_LIST_HEAD(&isert_conn->accept_node); | 635 | INIT_LIST_HEAD(&isert_conn->node); |
| 638 | init_completion(&isert_conn->login_comp); | 636 | init_completion(&isert_conn->login_comp); |
| 639 | init_completion(&isert_conn->login_req_comp); | 637 | init_completion(&isert_conn->login_req_comp); |
| 640 | init_completion(&isert_conn->wait); | 638 | init_completion(&isert_conn->wait); |
| @@ -762,28 +760,15 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
| 762 | ret = isert_rdma_post_recvl(isert_conn); | 760 | ret = isert_rdma_post_recvl(isert_conn); |
| 763 | if (ret) | 761 | if (ret) |
| 764 | goto out_conn_dev; | 762 | goto out_conn_dev; |
| 765 | /* | ||
| 766 | * Obtain the second reference now before isert_rdma_accept() to | ||
| 767 | * ensure that any initiator generated REJECT CM event that occurs | ||
| 768 | * asynchronously won't drop the last reference until the error path | ||
| 769 | * in iscsi_target_login_sess_out() does it's ->iscsit_free_conn() -> | ||
| 770 | * isert_free_conn() -> isert_put_conn() -> kref_put(). | ||
| 771 | */ | ||
| 772 | if (!kref_get_unless_zero(&isert_conn->kref)) { | ||
| 773 | isert_warn("conn %p connect_release is running\n", isert_conn); | ||
| 774 | goto out_conn_dev; | ||
| 775 | } | ||
| 776 | 763 | ||
| 777 | ret = isert_rdma_accept(isert_conn); | 764 | ret = isert_rdma_accept(isert_conn); |
| 778 | if (ret) | 765 | if (ret) |
| 779 | goto out_conn_dev; | 766 | goto out_conn_dev; |
| 780 | 767 | ||
| 781 | mutex_lock(&isert_np->np_accept_mutex); | 768 | mutex_lock(&isert_np->mutex); |
| 782 | list_add_tail(&isert_conn->accept_node, &isert_np->np_accept_list); | 769 | list_add_tail(&isert_conn->node, &isert_np->accepted); |
| 783 | mutex_unlock(&isert_np->np_accept_mutex); | 770 | mutex_unlock(&isert_np->mutex); |
| 784 | 771 | ||
| 785 | isert_info("np %p: Allow accept_np to continue\n", np); | ||
| 786 | up(&isert_np->np_sem); | ||
| 787 | return 0; | 772 | return 0; |
| 788 | 773 | ||
| 789 | out_conn_dev: | 774 | out_conn_dev: |
| @@ -831,13 +816,21 @@ static void | |||
| 831 | isert_connected_handler(struct rdma_cm_id *cma_id) | 816 | isert_connected_handler(struct rdma_cm_id *cma_id) |
| 832 | { | 817 | { |
| 833 | struct isert_conn *isert_conn = cma_id->qp->qp_context; | 818 | struct isert_conn *isert_conn = cma_id->qp->qp_context; |
| 819 | struct isert_np *isert_np = cma_id->context; | ||
| 834 | 820 | ||
| 835 | isert_info("conn %p\n", isert_conn); | 821 | isert_info("conn %p\n", isert_conn); |
| 836 | 822 | ||
| 837 | mutex_lock(&isert_conn->mutex); | 823 | mutex_lock(&isert_conn->mutex); |
| 838 | if (isert_conn->state != ISER_CONN_FULL_FEATURE) | 824 | isert_conn->state = ISER_CONN_UP; |
| 839 | isert_conn->state = ISER_CONN_UP; | 825 | kref_get(&isert_conn->kref); |
| 840 | mutex_unlock(&isert_conn->mutex); | 826 | mutex_unlock(&isert_conn->mutex); |
| 827 | |||
| 828 | mutex_lock(&isert_np->mutex); | ||
| 829 | list_move_tail(&isert_conn->node, &isert_np->pending); | ||
| 830 | mutex_unlock(&isert_np->mutex); | ||
| 831 | |||
| 832 | isert_info("np %p: Allow accept_np to continue\n", isert_np); | ||
| 833 | up(&isert_np->sem); | ||
| 841 | } | 834 | } |
| 842 | 835 | ||
| 843 | static void | 836 | static void |
| @@ -903,14 +896,14 @@ isert_np_cma_handler(struct isert_np *isert_np, | |||
| 903 | 896 | ||
| 904 | switch (event) { | 897 | switch (event) { |
| 905 | case RDMA_CM_EVENT_DEVICE_REMOVAL: | 898 | case RDMA_CM_EVENT_DEVICE_REMOVAL: |
| 906 | isert_np->np_cm_id = NULL; | 899 | isert_np->cm_id = NULL; |
| 907 | break; | 900 | break; |
| 908 | case RDMA_CM_EVENT_ADDR_CHANGE: | 901 | case RDMA_CM_EVENT_ADDR_CHANGE: |
| 909 | isert_np->np_cm_id = isert_setup_id(isert_np); | 902 | isert_np->cm_id = isert_setup_id(isert_np); |
| 910 | if (IS_ERR(isert_np->np_cm_id)) { | 903 | if (IS_ERR(isert_np->cm_id)) { |
| 911 | isert_err("isert np %p setup id failed: %ld\n", | 904 | isert_err("isert np %p setup id failed: %ld\n", |
| 912 | isert_np, PTR_ERR(isert_np->np_cm_id)); | 905 | isert_np, PTR_ERR(isert_np->cm_id)); |
| 913 | isert_np->np_cm_id = NULL; | 906 | isert_np->cm_id = NULL; |
| 914 | } | 907 | } |
| 915 | break; | 908 | break; |
| 916 | default: | 909 | default: |
| @@ -929,7 +922,7 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id, | |||
| 929 | struct isert_conn *isert_conn; | 922 | struct isert_conn *isert_conn; |
| 930 | bool terminating = false; | 923 | bool terminating = false; |
| 931 | 924 | ||
| 932 | if (isert_np->np_cm_id == cma_id) | 925 | if (isert_np->cm_id == cma_id) |
| 933 | return isert_np_cma_handler(cma_id->context, event); | 926 | return isert_np_cma_handler(cma_id->context, event); |
| 934 | 927 | ||
| 935 | isert_conn = cma_id->qp->qp_context; | 928 | isert_conn = cma_id->qp->qp_context; |
| @@ -945,13 +938,13 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id, | |||
| 945 | if (terminating) | 938 | if (terminating) |
| 946 | goto out; | 939 | goto out; |
| 947 | 940 | ||
| 948 | mutex_lock(&isert_np->np_accept_mutex); | 941 | mutex_lock(&isert_np->mutex); |
| 949 | if (!list_empty(&isert_conn->accept_node)) { | 942 | if (!list_empty(&isert_conn->node)) { |
| 950 | list_del_init(&isert_conn->accept_node); | 943 | list_del_init(&isert_conn->node); |
| 951 | isert_put_conn(isert_conn); | 944 | isert_put_conn(isert_conn); |
| 952 | queue_work(isert_release_wq, &isert_conn->release_work); | 945 | queue_work(isert_release_wq, &isert_conn->release_work); |
| 953 | } | 946 | } |
| 954 | mutex_unlock(&isert_np->np_accept_mutex); | 947 | mutex_unlock(&isert_np->mutex); |
| 955 | 948 | ||
| 956 | out: | 949 | out: |
| 957 | return 0; | 950 | return 0; |
| @@ -962,6 +955,7 @@ isert_connect_error(struct rdma_cm_id *cma_id) | |||
| 962 | { | 955 | { |
| 963 | struct isert_conn *isert_conn = cma_id->qp->qp_context; | 956 | struct isert_conn *isert_conn = cma_id->qp->qp_context; |
| 964 | 957 | ||
| 958 | list_del_init(&isert_conn->node); | ||
| 965 | isert_conn->cm_id = NULL; | 959 | isert_conn->cm_id = NULL; |
| 966 | isert_put_conn(isert_conn); | 960 | isert_put_conn(isert_conn); |
| 967 | 961 | ||
| @@ -1006,35 +1000,51 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
| 1006 | } | 1000 | } |
| 1007 | 1001 | ||
| 1008 | static int | 1002 | static int |
| 1009 | isert_post_recv(struct isert_conn *isert_conn, u32 count) | 1003 | isert_post_recvm(struct isert_conn *isert_conn, u32 count) |
| 1010 | { | 1004 | { |
| 1011 | struct ib_recv_wr *rx_wr, *rx_wr_failed; | 1005 | struct ib_recv_wr *rx_wr, *rx_wr_failed; |
| 1012 | int i, ret; | 1006 | int i, ret; |
| 1013 | unsigned int rx_head = isert_conn->rx_desc_head; | ||
| 1014 | struct iser_rx_desc *rx_desc; | 1007 | struct iser_rx_desc *rx_desc; |
| 1015 | 1008 | ||
| 1016 | for (rx_wr = isert_conn->rx_wr, i = 0; i < count; i++, rx_wr++) { | 1009 | for (rx_wr = isert_conn->rx_wr, i = 0; i < count; i++, rx_wr++) { |
| 1017 | rx_desc = &isert_conn->rx_descs[rx_head]; | 1010 | rx_desc = &isert_conn->rx_descs[i]; |
| 1018 | rx_wr->wr_id = (uintptr_t)rx_desc; | 1011 | rx_wr->wr_id = (uintptr_t)rx_desc; |
| 1019 | rx_wr->sg_list = &rx_desc->rx_sg; | 1012 | rx_wr->sg_list = &rx_desc->rx_sg; |
| 1020 | rx_wr->num_sge = 1; | 1013 | rx_wr->num_sge = 1; |
| 1021 | rx_wr->next = rx_wr + 1; | 1014 | rx_wr->next = rx_wr + 1; |
| 1022 | rx_head = (rx_head + 1) & (ISERT_QP_MAX_RECV_DTOS - 1); | ||
| 1023 | } | 1015 | } |
| 1024 | |||
| 1025 | rx_wr--; | 1016 | rx_wr--; |
| 1026 | rx_wr->next = NULL; /* mark end of work requests list */ | 1017 | rx_wr->next = NULL; /* mark end of work requests list */ |
| 1027 | 1018 | ||
| 1028 | isert_conn->post_recv_buf_count += count; | 1019 | isert_conn->post_recv_buf_count += count; |
| 1029 | ret = ib_post_recv(isert_conn->qp, isert_conn->rx_wr, | 1020 | ret = ib_post_recv(isert_conn->qp, isert_conn->rx_wr, |
| 1030 | &rx_wr_failed); | 1021 | &rx_wr_failed); |
| 1031 | if (ret) { | 1022 | if (ret) { |
| 1032 | isert_err("ib_post_recv() failed with ret: %d\n", ret); | 1023 | isert_err("ib_post_recv() failed with ret: %d\n", ret); |
| 1033 | isert_conn->post_recv_buf_count -= count; | 1024 | isert_conn->post_recv_buf_count -= count; |
| 1034 | } else { | ||
| 1035 | isert_dbg("Posted %d RX buffers\n", count); | ||
| 1036 | isert_conn->rx_desc_head = rx_head; | ||
| 1037 | } | 1025 | } |
| 1026 | |||
| 1027 | return ret; | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | static int | ||
| 1031 | isert_post_recv(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc) | ||
| 1032 | { | ||
| 1033 | struct ib_recv_wr *rx_wr_failed, rx_wr; | ||
| 1034 | int ret; | ||
| 1035 | |||
| 1036 | rx_wr.wr_id = (uintptr_t)rx_desc; | ||
| 1037 | rx_wr.sg_list = &rx_desc->rx_sg; | ||
| 1038 | rx_wr.num_sge = 1; | ||
| 1039 | rx_wr.next = NULL; | ||
| 1040 | |||
| 1041 | isert_conn->post_recv_buf_count++; | ||
| 1042 | ret = ib_post_recv(isert_conn->qp, &rx_wr, &rx_wr_failed); | ||
| 1043 | if (ret) { | ||
| 1044 | isert_err("ib_post_recv() failed with ret: %d\n", ret); | ||
| 1045 | isert_conn->post_recv_buf_count--; | ||
| 1046 | } | ||
| 1047 | |||
| 1038 | return ret; | 1048 | return ret; |
| 1039 | } | 1049 | } |
| 1040 | 1050 | ||
| @@ -1205,7 +1215,8 @@ isert_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login, | |||
| 1205 | if (ret) | 1215 | if (ret) |
| 1206 | return ret; | 1216 | return ret; |
| 1207 | 1217 | ||
| 1208 | ret = isert_post_recv(isert_conn, ISERT_MIN_POSTED_RX); | 1218 | ret = isert_post_recvm(isert_conn, |
| 1219 | ISERT_QP_MAX_RECV_DTOS); | ||
| 1209 | if (ret) | 1220 | if (ret) |
| 1210 | return ret; | 1221 | return ret; |
| 1211 | 1222 | ||
| @@ -1278,7 +1289,7 @@ isert_rx_login_req(struct isert_conn *isert_conn) | |||
| 1278 | } | 1289 | } |
| 1279 | 1290 | ||
| 1280 | static struct iscsi_cmd | 1291 | static struct iscsi_cmd |
| 1281 | *isert_allocate_cmd(struct iscsi_conn *conn) | 1292 | *isert_allocate_cmd(struct iscsi_conn *conn, struct iser_rx_desc *rx_desc) |
| 1282 | { | 1293 | { |
| 1283 | struct isert_conn *isert_conn = conn->context; | 1294 | struct isert_conn *isert_conn = conn->context; |
| 1284 | struct isert_cmd *isert_cmd; | 1295 | struct isert_cmd *isert_cmd; |
| @@ -1292,6 +1303,7 @@ static struct iscsi_cmd | |||
| 1292 | isert_cmd = iscsit_priv_cmd(cmd); | 1303 | isert_cmd = iscsit_priv_cmd(cmd); |
| 1293 | isert_cmd->conn = isert_conn; | 1304 | isert_cmd->conn = isert_conn; |
| 1294 | isert_cmd->iscsi_cmd = cmd; | 1305 | isert_cmd->iscsi_cmd = cmd; |
| 1306 | isert_cmd->rx_desc = rx_desc; | ||
| 1295 | 1307 | ||
| 1296 | return cmd; | 1308 | return cmd; |
| 1297 | } | 1309 | } |
| @@ -1303,9 +1315,9 @@ isert_handle_scsi_cmd(struct isert_conn *isert_conn, | |||
| 1303 | { | 1315 | { |
| 1304 | struct iscsi_conn *conn = isert_conn->conn; | 1316 | struct iscsi_conn *conn = isert_conn->conn; |
| 1305 | struct iscsi_scsi_req *hdr = (struct iscsi_scsi_req *)buf; | 1317 | struct iscsi_scsi_req *hdr = (struct iscsi_scsi_req *)buf; |
| 1306 | struct scatterlist *sg; | ||
| 1307 | int imm_data, imm_data_len, unsol_data, sg_nents, rc; | 1318 | int imm_data, imm_data_len, unsol_data, sg_nents, rc; |
| 1308 | bool dump_payload = false; | 1319 | bool dump_payload = false; |
| 1320 | unsigned int data_len; | ||
| 1309 | 1321 | ||
| 1310 | rc = iscsit_setup_scsi_cmd(conn, cmd, buf); | 1322 | rc = iscsit_setup_scsi_cmd(conn, cmd, buf); |
| 1311 | if (rc < 0) | 1323 | if (rc < 0) |
| @@ -1314,7 +1326,10 @@ isert_handle_scsi_cmd(struct isert_conn *isert_conn, | |||
| 1314 | imm_data = cmd->immediate_data; | 1326 | imm_data = cmd->immediate_data; |
| 1315 | imm_data_len = cmd->first_burst_len; | 1327 | imm_data_len = cmd->first_burst_len; |
| 1316 | unsol_data = cmd->unsolicited_data; | 1328 | unsol_data = cmd->unsolicited_data; |
| 1329 | data_len = cmd->se_cmd.data_length; | ||
| 1317 | 1330 | ||
| 1331 | if (imm_data && imm_data_len == data_len) | ||
| 1332 | cmd->se_cmd.se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC; | ||
| 1318 | rc = iscsit_process_scsi_cmd(conn, cmd, hdr); | 1333 | rc = iscsit_process_scsi_cmd(conn, cmd, hdr); |
| 1319 | if (rc < 0) { | 1334 | if (rc < 0) { |
| 1320 | return 0; | 1335 | return 0; |
| @@ -1326,13 +1341,20 @@ isert_handle_scsi_cmd(struct isert_conn *isert_conn, | |||
| 1326 | if (!imm_data) | 1341 | if (!imm_data) |
| 1327 | return 0; | 1342 | return 0; |
| 1328 | 1343 | ||
| 1329 | sg = &cmd->se_cmd.t_data_sg[0]; | 1344 | if (imm_data_len != data_len) { |
| 1330 | sg_nents = max(1UL, DIV_ROUND_UP(imm_data_len, PAGE_SIZE)); | 1345 | sg_nents = max(1UL, DIV_ROUND_UP(imm_data_len, PAGE_SIZE)); |
| 1331 | 1346 | sg_copy_from_buffer(cmd->se_cmd.t_data_sg, sg_nents, | |
| 1332 | isert_dbg("Copying Immediate SG: %p sg_nents: %u from %p imm_data_len: %d\n", | 1347 | &rx_desc->data[0], imm_data_len); |
| 1333 | sg, sg_nents, &rx_desc->data[0], imm_data_len); | 1348 | isert_dbg("Copy Immediate sg_nents: %u imm_data_len: %d\n", |
| 1334 | 1349 | sg_nents, imm_data_len); | |
| 1335 | sg_copy_from_buffer(sg, sg_nents, &rx_desc->data[0], imm_data_len); | 1350 | } else { |
| 1351 | sg_init_table(&isert_cmd->sg, 1); | ||
| 1352 | cmd->se_cmd.t_data_sg = &isert_cmd->sg; | ||
| 1353 | cmd->se_cmd.t_data_nents = 1; | ||
| 1354 | sg_set_buf(&isert_cmd->sg, &rx_desc->data[0], imm_data_len); | ||
| 1355 | isert_dbg("Transfer Immediate imm_data_len: %d\n", | ||
| 1356 | imm_data_len); | ||
| 1357 | } | ||
| 1336 | 1358 | ||
| 1337 | cmd->write_data_done += imm_data_len; | 1359 | cmd->write_data_done += imm_data_len; |
| 1338 | 1360 | ||
| @@ -1407,6 +1429,15 @@ isert_handle_iscsi_dataout(struct isert_conn *isert_conn, | |||
| 1407 | if (rc < 0) | 1429 | if (rc < 0) |
| 1408 | return rc; | 1430 | return rc; |
| 1409 | 1431 | ||
| 1432 | /* | ||
| 1433 | * multiple data-outs on the same command can arrive - | ||
| 1434 | * so post the buffer before hand | ||
| 1435 | */ | ||
| 1436 | rc = isert_post_recv(isert_conn, rx_desc); | ||
| 1437 | if (rc) { | ||
| 1438 | isert_err("ib_post_recv failed with %d\n", rc); | ||
| 1439 | return rc; | ||
| 1440 | } | ||
| 1410 | return 0; | 1441 | return 0; |
| 1411 | } | 1442 | } |
| 1412 | 1443 | ||
| @@ -1479,7 +1510,7 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, | |||
| 1479 | 1510 | ||
| 1480 | switch (opcode) { | 1511 | switch (opcode) { |
| 1481 | case ISCSI_OP_SCSI_CMD: | 1512 | case ISCSI_OP_SCSI_CMD: |
| 1482 | cmd = isert_allocate_cmd(conn); | 1513 | cmd = isert_allocate_cmd(conn, rx_desc); |
| 1483 | if (!cmd) | 1514 | if (!cmd) |
| 1484 | break; | 1515 | break; |
| 1485 | 1516 | ||
| @@ -1493,7 +1524,7 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, | |||
| 1493 | rx_desc, (unsigned char *)hdr); | 1524 | rx_desc, (unsigned char *)hdr); |
| 1494 | break; | 1525 | break; |
| 1495 | case ISCSI_OP_NOOP_OUT: | 1526 | case ISCSI_OP_NOOP_OUT: |
| 1496 | cmd = isert_allocate_cmd(conn); | 1527 | cmd = isert_allocate_cmd(conn, rx_desc); |
| 1497 | if (!cmd) | 1528 | if (!cmd) |
| 1498 | break; | 1529 | break; |
| 1499 | 1530 | ||
| @@ -1506,7 +1537,7 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, | |||
| 1506 | (unsigned char *)hdr); | 1537 | (unsigned char *)hdr); |
| 1507 | break; | 1538 | break; |
| 1508 | case ISCSI_OP_SCSI_TMFUNC: | 1539 | case ISCSI_OP_SCSI_TMFUNC: |
| 1509 | cmd = isert_allocate_cmd(conn); | 1540 | cmd = isert_allocate_cmd(conn, rx_desc); |
| 1510 | if (!cmd) | 1541 | if (!cmd) |
| 1511 | break; | 1542 | break; |
| 1512 | 1543 | ||
| @@ -1514,22 +1545,20 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc, | |||
| 1514 | (unsigned char *)hdr); | 1545 | (unsigned char *)hdr); |
| 1515 | break; | 1546 | break; |
| 1516 | case ISCSI_OP_LOGOUT: | 1547 | case ISCSI_OP_LOGOUT: |
| 1517 | cmd = isert_allocate_cmd(conn); | 1548 | cmd = isert_allocate_cmd(conn, rx_desc); |
| 1518 | if (!cmd) | 1549 | if (!cmd) |
| 1519 | break; | 1550 | break; |
| 1520 | 1551 | ||
| 1521 | ret = iscsit_handle_logout_cmd(conn, cmd, (unsigned char *)hdr); | 1552 | ret = iscsit_handle_logout_cmd(conn, cmd, (unsigned char *)hdr); |
| 1522 | break; | 1553 | break; |
| 1523 | case ISCSI_OP_TEXT: | 1554 | case ISCSI_OP_TEXT: |
| 1524 | if (be32_to_cpu(hdr->ttt) != 0xFFFFFFFF) { | 1555 | if (be32_to_cpu(hdr->ttt) != 0xFFFFFFFF) |
| 1525 | cmd = iscsit_find_cmd_from_itt(conn, hdr->itt); | 1556 | cmd = iscsit_find_cmd_from_itt(conn, hdr->itt); |
| 1526 | if (!cmd) | 1557 | else |
| 1527 | break; | 1558 | cmd = isert_allocate_cmd(conn, rx_desc); |
| 1528 | } else { | 1559 | |
| 1529 | cmd = isert_allocate_cmd(conn); | 1560 | if (!cmd) |
| 1530 | if (!cmd) | 1561 | break; |
| 1531 | break; | ||
| 1532 | } | ||
| 1533 | 1562 | ||
| 1534 | isert_cmd = iscsit_priv_cmd(cmd); | 1563 | isert_cmd = iscsit_priv_cmd(cmd); |
| 1535 | ret = isert_handle_text_cmd(isert_conn, isert_cmd, cmd, | 1564 | ret = isert_handle_text_cmd(isert_conn, isert_cmd, cmd, |
| @@ -1589,7 +1618,7 @@ isert_rcv_completion(struct iser_rx_desc *desc, | |||
| 1589 | struct ib_device *ib_dev = isert_conn->cm_id->device; | 1618 | struct ib_device *ib_dev = isert_conn->cm_id->device; |
| 1590 | struct iscsi_hdr *hdr; | 1619 | struct iscsi_hdr *hdr; |
| 1591 | u64 rx_dma; | 1620 | u64 rx_dma; |
| 1592 | int rx_buflen, outstanding; | 1621 | int rx_buflen; |
| 1593 | 1622 | ||
| 1594 | if ((char *)desc == isert_conn->login_req_buf) { | 1623 | if ((char *)desc == isert_conn->login_req_buf) { |
| 1595 | rx_dma = isert_conn->login_req_dma; | 1624 | rx_dma = isert_conn->login_req_dma; |
| @@ -1629,22 +1658,6 @@ isert_rcv_completion(struct iser_rx_desc *desc, | |||
| 1629 | DMA_FROM_DEVICE); | 1658 | DMA_FROM_DEVICE); |
| 1630 | 1659 | ||
| 1631 | isert_conn->post_recv_buf_count--; | 1660 | isert_conn->post_recv_buf_count--; |
| 1632 | isert_dbg("Decremented post_recv_buf_count: %d\n", | ||
| 1633 | isert_conn->post_recv_buf_count); | ||
| 1634 | |||
| 1635 | if ((char *)desc == isert_conn->login_req_buf) | ||
| 1636 | return; | ||
| 1637 | |||
| 1638 | outstanding = isert_conn->post_recv_buf_count; | ||
| 1639 | if (outstanding + ISERT_MIN_POSTED_RX <= ISERT_QP_MAX_RECV_DTOS) { | ||
| 1640 | int err, count = min(ISERT_QP_MAX_RECV_DTOS - outstanding, | ||
| 1641 | ISERT_MIN_POSTED_RX); | ||
| 1642 | err = isert_post_recv(isert_conn, count); | ||
| 1643 | if (err) { | ||
| 1644 | isert_err("isert_post_recv() count: %d failed, %d\n", | ||
| 1645 | count, err); | ||
| 1646 | } | ||
| 1647 | } | ||
| 1648 | } | 1661 | } |
| 1649 | 1662 | ||
| 1650 | static int | 1663 | static int |
| @@ -2156,6 +2169,12 @@ isert_post_response(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd) | |||
| 2156 | struct ib_send_wr *wr_failed; | 2169 | struct ib_send_wr *wr_failed; |
| 2157 | int ret; | 2170 | int ret; |
| 2158 | 2171 | ||
| 2172 | ret = isert_post_recv(isert_conn, isert_cmd->rx_desc); | ||
| 2173 | if (ret) { | ||
| 2174 | isert_err("ib_post_recv failed with %d\n", ret); | ||
| 2175 | return ret; | ||
| 2176 | } | ||
| 2177 | |||
| 2159 | ret = ib_post_send(isert_conn->qp, &isert_cmd->tx_desc.send_wr, | 2178 | ret = ib_post_send(isert_conn->qp, &isert_cmd->tx_desc.send_wr, |
| 2160 | &wr_failed); | 2179 | &wr_failed); |
| 2161 | if (ret) { | 2180 | if (ret) { |
| @@ -2950,6 +2969,12 @@ isert_put_datain(struct iscsi_conn *conn, struct iscsi_cmd *cmd) | |||
| 2950 | &isert_cmd->tx_desc.send_wr); | 2969 | &isert_cmd->tx_desc.send_wr); |
| 2951 | isert_cmd->rdma_wr.s_send_wr.next = &isert_cmd->tx_desc.send_wr; | 2970 | isert_cmd->rdma_wr.s_send_wr.next = &isert_cmd->tx_desc.send_wr; |
| 2952 | wr->send_wr_num += 1; | 2971 | wr->send_wr_num += 1; |
| 2972 | |||
| 2973 | rc = isert_post_recv(isert_conn, isert_cmd->rx_desc); | ||
| 2974 | if (rc) { | ||
| 2975 | isert_err("ib_post_recv failed with %d\n", rc); | ||
| 2976 | return rc; | ||
| 2977 | } | ||
| 2953 | } | 2978 | } |
| 2954 | 2979 | ||
| 2955 | rc = ib_post_send(isert_conn->qp, wr->send_wr, &wr_failed); | 2980 | rc = ib_post_send(isert_conn->qp, wr->send_wr, &wr_failed); |
| @@ -2999,9 +3024,16 @@ isert_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, bool recovery) | |||
| 2999 | static int | 3024 | static int |
| 3000 | isert_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) | 3025 | isert_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) |
| 3001 | { | 3026 | { |
| 3002 | int ret; | 3027 | struct isert_cmd *isert_cmd = iscsit_priv_cmd(cmd); |
| 3028 | int ret = 0; | ||
| 3003 | 3029 | ||
| 3004 | switch (state) { | 3030 | switch (state) { |
| 3031 | case ISTATE_REMOVE: | ||
| 3032 | spin_lock_bh(&conn->cmd_lock); | ||
| 3033 | list_del_init(&cmd->i_conn_node); | ||
| 3034 | spin_unlock_bh(&conn->cmd_lock); | ||
| 3035 | isert_put_cmd(isert_cmd, true); | ||
| 3036 | break; | ||
| 3005 | case ISTATE_SEND_NOPIN_WANT_RESPONSE: | 3037 | case ISTATE_SEND_NOPIN_WANT_RESPONSE: |
| 3006 | ret = isert_put_nopin(cmd, conn, false); | 3038 | ret = isert_put_nopin(cmd, conn, false); |
| 3007 | break; | 3039 | break; |
| @@ -3106,10 +3138,10 @@ isert_setup_np(struct iscsi_np *np, | |||
| 3106 | isert_err("Unable to allocate struct isert_np\n"); | 3138 | isert_err("Unable to allocate struct isert_np\n"); |
| 3107 | return -ENOMEM; | 3139 | return -ENOMEM; |
| 3108 | } | 3140 | } |
| 3109 | sema_init(&isert_np->np_sem, 0); | 3141 | sema_init(&isert_np->sem, 0); |
| 3110 | mutex_init(&isert_np->np_accept_mutex); | 3142 | mutex_init(&isert_np->mutex); |
| 3111 | INIT_LIST_HEAD(&isert_np->np_accept_list); | 3143 | INIT_LIST_HEAD(&isert_np->accepted); |
| 3112 | init_completion(&isert_np->np_login_comp); | 3144 | INIT_LIST_HEAD(&isert_np->pending); |
| 3113 | isert_np->np = np; | 3145 | isert_np->np = np; |
| 3114 | 3146 | ||
| 3115 | /* | 3147 | /* |
| @@ -3125,7 +3157,7 @@ isert_setup_np(struct iscsi_np *np, | |||
| 3125 | goto out; | 3157 | goto out; |
| 3126 | } | 3158 | } |
| 3127 | 3159 | ||
| 3128 | isert_np->np_cm_id = isert_lid; | 3160 | isert_np->cm_id = isert_lid; |
| 3129 | np->np_context = isert_np; | 3161 | np->np_context = isert_np; |
| 3130 | 3162 | ||
| 3131 | return 0; | 3163 | return 0; |
| @@ -3214,7 +3246,7 @@ isert_accept_np(struct iscsi_np *np, struct iscsi_conn *conn) | |||
| 3214 | int ret; | 3246 | int ret; |
| 3215 | 3247 | ||
| 3216 | accept_wait: | 3248 | accept_wait: |
| 3217 | ret = down_interruptible(&isert_np->np_sem); | 3249 | ret = down_interruptible(&isert_np->sem); |
| 3218 | if (ret) | 3250 | if (ret) |
| 3219 | return -ENODEV; | 3251 | return -ENODEV; |
| 3220 | 3252 | ||
| @@ -3231,15 +3263,15 @@ accept_wait: | |||
| 3231 | } | 3263 | } |
| 3232 | spin_unlock_bh(&np->np_thread_lock); | 3264 | spin_unlock_bh(&np->np_thread_lock); |
| 3233 | 3265 | ||
| 3234 | mutex_lock(&isert_np->np_accept_mutex); | 3266 | mutex_lock(&isert_np->mutex); |
| 3235 | if (list_empty(&isert_np->np_accept_list)) { | 3267 | if (list_empty(&isert_np->pending)) { |
| 3236 | mutex_unlock(&isert_np->np_accept_mutex); | 3268 | mutex_unlock(&isert_np->mutex); |
| 3237 | goto accept_wait; | 3269 | goto accept_wait; |
| 3238 | } | 3270 | } |
| 3239 | isert_conn = list_first_entry(&isert_np->np_accept_list, | 3271 | isert_conn = list_first_entry(&isert_np->pending, |
| 3240 | struct isert_conn, accept_node); | 3272 | struct isert_conn, node); |
| 3241 | list_del_init(&isert_conn->accept_node); | 3273 | list_del_init(&isert_conn->node); |
| 3242 | mutex_unlock(&isert_np->np_accept_mutex); | 3274 | mutex_unlock(&isert_np->mutex); |
| 3243 | 3275 | ||
| 3244 | conn->context = isert_conn; | 3276 | conn->context = isert_conn; |
| 3245 | isert_conn->conn = conn; | 3277 | isert_conn->conn = conn; |
| @@ -3257,28 +3289,39 @@ isert_free_np(struct iscsi_np *np) | |||
| 3257 | struct isert_np *isert_np = np->np_context; | 3289 | struct isert_np *isert_np = np->np_context; |
| 3258 | struct isert_conn *isert_conn, *n; | 3290 | struct isert_conn *isert_conn, *n; |
| 3259 | 3291 | ||
| 3260 | if (isert_np->np_cm_id) | 3292 | if (isert_np->cm_id) |
| 3261 | rdma_destroy_id(isert_np->np_cm_id); | 3293 | rdma_destroy_id(isert_np->cm_id); |
| 3262 | 3294 | ||
| 3263 | /* | 3295 | /* |
| 3264 | * FIXME: At this point we don't have a good way to insure | 3296 | * FIXME: At this point we don't have a good way to insure |
| 3265 | * that at this point we don't have hanging connections that | 3297 | * that at this point we don't have hanging connections that |
| 3266 | * completed RDMA establishment but didn't start iscsi login | 3298 | * completed RDMA establishment but didn't start iscsi login |
| 3267 | * process. So work-around this by cleaning up what ever piled | 3299 | * process. So work-around this by cleaning up what ever piled |
| 3268 | * up in np_accept_list. | 3300 | * up in accepted and pending lists. |
| 3269 | */ | 3301 | */ |
| 3270 | mutex_lock(&isert_np->np_accept_mutex); | 3302 | mutex_lock(&isert_np->mutex); |
| 3271 | if (!list_empty(&isert_np->np_accept_list)) { | 3303 | if (!list_empty(&isert_np->pending)) { |
| 3272 | isert_info("Still have isert connections, cleaning up...\n"); | 3304 | isert_info("Still have isert pending connections\n"); |
| 3305 | list_for_each_entry_safe(isert_conn, n, | ||
| 3306 | &isert_np->pending, | ||
| 3307 | node) { | ||
| 3308 | isert_info("cleaning isert_conn %p state (%d)\n", | ||
| 3309 | isert_conn, isert_conn->state); | ||
| 3310 | isert_connect_release(isert_conn); | ||
| 3311 | } | ||
| 3312 | } | ||
| 3313 | |||
| 3314 | if (!list_empty(&isert_np->accepted)) { | ||
| 3315 | isert_info("Still have isert accepted connections\n"); | ||
| 3273 | list_for_each_entry_safe(isert_conn, n, | 3316 | list_for_each_entry_safe(isert_conn, n, |
| 3274 | &isert_np->np_accept_list, | 3317 | &isert_np->accepted, |
| 3275 | accept_node) { | 3318 | node) { |
| 3276 | isert_info("cleaning isert_conn %p state (%d)\n", | 3319 | isert_info("cleaning isert_conn %p state (%d)\n", |
| 3277 | isert_conn, isert_conn->state); | 3320 | isert_conn, isert_conn->state); |
| 3278 | isert_connect_release(isert_conn); | 3321 | isert_connect_release(isert_conn); |
| 3279 | } | 3322 | } |
| 3280 | } | 3323 | } |
| 3281 | mutex_unlock(&isert_np->np_accept_mutex); | 3324 | mutex_unlock(&isert_np->mutex); |
| 3282 | 3325 | ||
| 3283 | np->np_context = NULL; | 3326 | np->np_context = NULL; |
| 3284 | kfree(isert_np); | 3327 | kfree(isert_np); |
| @@ -3345,6 +3388,41 @@ isert_wait4flush(struct isert_conn *isert_conn) | |||
| 3345 | wait_for_completion(&isert_conn->wait_comp_err); | 3388 | wait_for_completion(&isert_conn->wait_comp_err); |
| 3346 | } | 3389 | } |
| 3347 | 3390 | ||
| 3391 | /** | ||
| 3392 | * isert_put_unsol_pending_cmds() - Drop commands waiting for | ||
| 3393 | * unsolicitate dataout | ||
| 3394 | * @conn: iscsi connection | ||
| 3395 | * | ||
| 3396 | * We might still have commands that are waiting for unsolicited | ||
| 3397 | * dataouts messages. We must put the extra reference on those | ||
| 3398 | * before blocking on the target_wait_for_session_cmds | ||
| 3399 | */ | ||
| 3400 | static void | ||
| 3401 | isert_put_unsol_pending_cmds(struct iscsi_conn *conn) | ||
| 3402 | { | ||
| 3403 | struct iscsi_cmd *cmd, *tmp; | ||
| 3404 | static LIST_HEAD(drop_cmd_list); | ||
| 3405 | |||
| 3406 | spin_lock_bh(&conn->cmd_lock); | ||
| 3407 | list_for_each_entry_safe(cmd, tmp, &conn->conn_cmd_list, i_conn_node) { | ||
| 3408 | if ((cmd->cmd_flags & ICF_NON_IMMEDIATE_UNSOLICITED_DATA) && | ||
| 3409 | (cmd->write_data_done < conn->sess->sess_ops->FirstBurstLength) && | ||
| 3410 | (cmd->write_data_done < cmd->se_cmd.data_length)) | ||
| 3411 | list_move_tail(&cmd->i_conn_node, &drop_cmd_list); | ||
| 3412 | } | ||
| 3413 | spin_unlock_bh(&conn->cmd_lock); | ||
| 3414 | |||
| 3415 | list_for_each_entry_safe(cmd, tmp, &drop_cmd_list, i_conn_node) { | ||
| 3416 | list_del_init(&cmd->i_conn_node); | ||
| 3417 | if (cmd->i_state != ISTATE_REMOVE) { | ||
| 3418 | struct isert_cmd *isert_cmd = iscsit_priv_cmd(cmd); | ||
| 3419 | |||
| 3420 | isert_info("conn %p dropping cmd %p\n", conn, cmd); | ||
| 3421 | isert_put_cmd(isert_cmd, true); | ||
| 3422 | } | ||
| 3423 | } | ||
| 3424 | } | ||
| 3425 | |||
| 3348 | static void isert_wait_conn(struct iscsi_conn *conn) | 3426 | static void isert_wait_conn(struct iscsi_conn *conn) |
| 3349 | { | 3427 | { |
| 3350 | struct isert_conn *isert_conn = conn->context; | 3428 | struct isert_conn *isert_conn = conn->context; |
| @@ -3363,8 +3441,9 @@ static void isert_wait_conn(struct iscsi_conn *conn) | |||
| 3363 | isert_conn_terminate(isert_conn); | 3441 | isert_conn_terminate(isert_conn); |
| 3364 | mutex_unlock(&isert_conn->mutex); | 3442 | mutex_unlock(&isert_conn->mutex); |
| 3365 | 3443 | ||
| 3366 | isert_wait4cmds(conn); | ||
| 3367 | isert_wait4flush(isert_conn); | 3444 | isert_wait4flush(isert_conn); |
| 3445 | isert_put_unsol_pending_cmds(conn); | ||
| 3446 | isert_wait4cmds(conn); | ||
| 3368 | isert_wait4logout(isert_conn); | 3447 | isert_wait4logout(isert_conn); |
| 3369 | 3448 | ||
| 3370 | queue_work(isert_release_wq, &isert_conn->release_work); | 3449 | queue_work(isert_release_wq, &isert_conn->release_work); |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index 6a04ba3c0f72..c5b99bcecbcf 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h | |||
| @@ -113,7 +113,6 @@ enum { | |||
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| 115 | struct isert_rdma_wr { | 115 | struct isert_rdma_wr { |
| 116 | struct list_head wr_list; | ||
| 117 | struct isert_cmd *isert_cmd; | 116 | struct isert_cmd *isert_cmd; |
| 118 | enum iser_ib_op_code iser_ib_op; | 117 | enum iser_ib_op_code iser_ib_op; |
| 119 | struct ib_sge *ib_sge; | 118 | struct ib_sge *ib_sge; |
| @@ -134,14 +133,13 @@ struct isert_cmd { | |||
| 134 | uint64_t write_va; | 133 | uint64_t write_va; |
| 135 | u64 pdu_buf_dma; | 134 | u64 pdu_buf_dma; |
| 136 | u32 pdu_buf_len; | 135 | u32 pdu_buf_len; |
| 137 | u32 read_va_off; | ||
| 138 | u32 write_va_off; | ||
| 139 | u32 rdma_wr_num; | ||
| 140 | struct isert_conn *conn; | 136 | struct isert_conn *conn; |
| 141 | struct iscsi_cmd *iscsi_cmd; | 137 | struct iscsi_cmd *iscsi_cmd; |
| 142 | struct iser_tx_desc tx_desc; | 138 | struct iser_tx_desc tx_desc; |
| 139 | struct iser_rx_desc *rx_desc; | ||
| 143 | struct isert_rdma_wr rdma_wr; | 140 | struct isert_rdma_wr rdma_wr; |
| 144 | struct work_struct comp_work; | 141 | struct work_struct comp_work; |
| 142 | struct scatterlist sg; | ||
| 145 | }; | 143 | }; |
| 146 | 144 | ||
| 147 | struct isert_device; | 145 | struct isert_device; |
| @@ -159,11 +157,10 @@ struct isert_conn { | |||
| 159 | u64 login_req_dma; | 157 | u64 login_req_dma; |
| 160 | int login_req_len; | 158 | int login_req_len; |
| 161 | u64 login_rsp_dma; | 159 | u64 login_rsp_dma; |
| 162 | unsigned int rx_desc_head; | ||
| 163 | struct iser_rx_desc *rx_descs; | 160 | struct iser_rx_desc *rx_descs; |
| 164 | struct ib_recv_wr rx_wr[ISERT_MIN_POSTED_RX]; | 161 | struct ib_recv_wr rx_wr[ISERT_QP_MAX_RECV_DTOS]; |
| 165 | struct iscsi_conn *conn; | 162 | struct iscsi_conn *conn; |
| 166 | struct list_head accept_node; | 163 | struct list_head node; |
| 167 | struct completion login_comp; | 164 | struct completion login_comp; |
| 168 | struct completion login_req_comp; | 165 | struct completion login_req_comp; |
| 169 | struct iser_tx_desc login_tx_desc; | 166 | struct iser_tx_desc login_tx_desc; |
| @@ -222,9 +219,9 @@ struct isert_device { | |||
| 222 | 219 | ||
| 223 | struct isert_np { | 220 | struct isert_np { |
| 224 | struct iscsi_np *np; | 221 | struct iscsi_np *np; |
| 225 | struct semaphore np_sem; | 222 | struct semaphore sem; |
| 226 | struct rdma_cm_id *np_cm_id; | 223 | struct rdma_cm_id *cm_id; |
| 227 | struct mutex np_accept_mutex; | 224 | struct mutex mutex; |
| 228 | struct list_head np_accept_list; | 225 | struct list_head accepted; |
| 229 | struct completion np_login_comp; | 226 | struct list_head pending; |
| 230 | }; | 227 | }; |
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index e8a52f7d6204..51d1734d5390 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c | |||
| @@ -407,6 +407,7 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr) | |||
| 407 | TYPERANGE_UTF8, USE_INITIAL_ONLY); | 407 | TYPERANGE_UTF8, USE_INITIAL_ONLY); |
| 408 | if (!param) | 408 | if (!param) |
| 409 | goto out; | 409 | goto out; |
| 410 | |||
| 410 | /* | 411 | /* |
| 411 | * Extra parameters for ISER from RFC-5046 | 412 | * Extra parameters for ISER from RFC-5046 |
| 412 | */ | 413 | */ |
| @@ -496,9 +497,9 @@ int iscsi_set_keys_to_negotiate( | |||
| 496 | } else if (!strcmp(param->name, SESSIONTYPE)) { | 497 | } else if (!strcmp(param->name, SESSIONTYPE)) { |
| 497 | SET_PSTATE_NEGOTIATE(param); | 498 | SET_PSTATE_NEGOTIATE(param); |
| 498 | } else if (!strcmp(param->name, IFMARKER)) { | 499 | } else if (!strcmp(param->name, IFMARKER)) { |
| 499 | SET_PSTATE_NEGOTIATE(param); | 500 | SET_PSTATE_REJECT(param); |
| 500 | } else if (!strcmp(param->name, OFMARKER)) { | 501 | } else if (!strcmp(param->name, OFMARKER)) { |
| 501 | SET_PSTATE_NEGOTIATE(param); | 502 | SET_PSTATE_REJECT(param); |
| 502 | } else if (!strcmp(param->name, IFMARKINT)) { | 503 | } else if (!strcmp(param->name, IFMARKINT)) { |
| 503 | SET_PSTATE_REJECT(param); | 504 | SET_PSTATE_REJECT(param); |
| 504 | } else if (!strcmp(param->name, OFMARKINT)) { | 505 | } else if (!strcmp(param->name, OFMARKINT)) { |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index dcc424ac35d4..88ea4e4f124b 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
| @@ -62,22 +62,13 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) | |||
| 62 | struct se_session *se_sess = se_cmd->se_sess; | 62 | struct se_session *se_sess = se_cmd->se_sess; |
| 63 | struct se_node_acl *nacl = se_sess->se_node_acl; | 63 | struct se_node_acl *nacl = se_sess->se_node_acl; |
| 64 | struct se_dev_entry *deve; | 64 | struct se_dev_entry *deve; |
| 65 | sense_reason_t ret = TCM_NO_SENSE; | ||
| 65 | 66 | ||
| 66 | rcu_read_lock(); | 67 | rcu_read_lock(); |
| 67 | deve = target_nacl_find_deve(nacl, unpacked_lun); | 68 | deve = target_nacl_find_deve(nacl, unpacked_lun); |
| 68 | if (deve) { | 69 | if (deve) { |
| 69 | atomic_long_inc(&deve->total_cmds); | 70 | atomic_long_inc(&deve->total_cmds); |
| 70 | 71 | ||
| 71 | if ((se_cmd->data_direction == DMA_TO_DEVICE) && | ||
| 72 | (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { | ||
| 73 | pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" | ||
| 74 | " Access for 0x%08llx\n", | ||
| 75 | se_cmd->se_tfo->get_fabric_name(), | ||
| 76 | unpacked_lun); | ||
| 77 | rcu_read_unlock(); | ||
| 78 | return TCM_WRITE_PROTECTED; | ||
| 79 | } | ||
| 80 | |||
| 81 | if (se_cmd->data_direction == DMA_TO_DEVICE) | 72 | if (se_cmd->data_direction == DMA_TO_DEVICE) |
| 82 | atomic_long_add(se_cmd->data_length, | 73 | atomic_long_add(se_cmd->data_length, |
| 83 | &deve->write_bytes); | 74 | &deve->write_bytes); |
| @@ -93,6 +84,17 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) | |||
| 93 | 84 | ||
| 94 | percpu_ref_get(&se_lun->lun_ref); | 85 | percpu_ref_get(&se_lun->lun_ref); |
| 95 | se_cmd->lun_ref_active = true; | 86 | se_cmd->lun_ref_active = true; |
| 87 | |||
| 88 | if ((se_cmd->data_direction == DMA_TO_DEVICE) && | ||
| 89 | (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { | ||
| 90 | pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" | ||
| 91 | " Access for 0x%08llx\n", | ||
| 92 | se_cmd->se_tfo->get_fabric_name(), | ||
| 93 | unpacked_lun); | ||
| 94 | rcu_read_unlock(); | ||
| 95 | ret = TCM_WRITE_PROTECTED; | ||
| 96 | goto ref_dev; | ||
| 97 | } | ||
| 96 | } | 98 | } |
| 97 | rcu_read_unlock(); | 99 | rcu_read_unlock(); |
| 98 | 100 | ||
| @@ -109,12 +111,6 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) | |||
| 109 | unpacked_lun); | 111 | unpacked_lun); |
| 110 | return TCM_NON_EXISTENT_LUN; | 112 | return TCM_NON_EXISTENT_LUN; |
| 111 | } | 113 | } |
| 112 | /* | ||
| 113 | * Force WRITE PROTECT for virtual LUN 0 | ||
| 114 | */ | ||
| 115 | if ((se_cmd->data_direction != DMA_FROM_DEVICE) && | ||
| 116 | (se_cmd->data_direction != DMA_NONE)) | ||
| 117 | return TCM_WRITE_PROTECTED; | ||
| 118 | 114 | ||
| 119 | se_lun = se_sess->se_tpg->tpg_virt_lun0; | 115 | se_lun = se_sess->se_tpg->tpg_virt_lun0; |
| 120 | se_cmd->se_lun = se_sess->se_tpg->tpg_virt_lun0; | 116 | se_cmd->se_lun = se_sess->se_tpg->tpg_virt_lun0; |
| @@ -123,6 +119,15 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) | |||
| 123 | 119 | ||
| 124 | percpu_ref_get(&se_lun->lun_ref); | 120 | percpu_ref_get(&se_lun->lun_ref); |
| 125 | se_cmd->lun_ref_active = true; | 121 | se_cmd->lun_ref_active = true; |
| 122 | |||
| 123 | /* | ||
| 124 | * Force WRITE PROTECT for virtual LUN 0 | ||
| 125 | */ | ||
| 126 | if ((se_cmd->data_direction != DMA_FROM_DEVICE) && | ||
| 127 | (se_cmd->data_direction != DMA_NONE)) { | ||
| 128 | ret = TCM_WRITE_PROTECTED; | ||
| 129 | goto ref_dev; | ||
| 130 | } | ||
| 126 | } | 131 | } |
| 127 | /* | 132 | /* |
| 128 | * RCU reference protected by percpu se_lun->lun_ref taken above that | 133 | * RCU reference protected by percpu se_lun->lun_ref taken above that |
| @@ -130,6 +135,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) | |||
| 130 | * pointer can be kfree_rcu() by the final se_lun->lun_group put via | 135 | * pointer can be kfree_rcu() by the final se_lun->lun_group put via |
| 131 | * target_core_fabric_configfs.c:target_fabric_port_release | 136 | * target_core_fabric_configfs.c:target_fabric_port_release |
| 132 | */ | 137 | */ |
| 138 | ref_dev: | ||
| 133 | se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev); | 139 | se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev); |
| 134 | atomic_long_inc(&se_cmd->se_dev->num_cmds); | 140 | atomic_long_inc(&se_cmd->se_dev->num_cmds); |
| 135 | 141 | ||
| @@ -140,7 +146,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) | |||
| 140 | atomic_long_add(se_cmd->data_length, | 146 | atomic_long_add(se_cmd->data_length, |
| 141 | &se_cmd->se_dev->read_bytes); | 147 | &se_cmd->se_dev->read_bytes); |
| 142 | 148 | ||
| 143 | return 0; | 149 | return ret; |
| 144 | } | 150 | } |
| 145 | EXPORT_SYMBOL(transport_lookup_cmd_lun); | 151 | EXPORT_SYMBOL(transport_lookup_cmd_lun); |
| 146 | 152 | ||
| @@ -427,8 +433,6 @@ void core_disable_device_list_for_node( | |||
| 427 | 433 | ||
| 428 | hlist_del_rcu(&orig->link); | 434 | hlist_del_rcu(&orig->link); |
| 429 | clear_bit(DEF_PR_REG_ACTIVE, &orig->deve_flags); | 435 | clear_bit(DEF_PR_REG_ACTIVE, &orig->deve_flags); |
| 430 | rcu_assign_pointer(orig->se_lun, NULL); | ||
| 431 | rcu_assign_pointer(orig->se_lun_acl, NULL); | ||
| 432 | orig->lun_flags = 0; | 436 | orig->lun_flags = 0; |
| 433 | orig->creation_time = 0; | 437 | orig->creation_time = 0; |
| 434 | orig->attach_count--; | 438 | orig->attach_count--; |
| @@ -439,6 +443,9 @@ void core_disable_device_list_for_node( | |||
| 439 | kref_put(&orig->pr_kref, target_pr_kref_release); | 443 | kref_put(&orig->pr_kref, target_pr_kref_release); |
| 440 | wait_for_completion(&orig->pr_comp); | 444 | wait_for_completion(&orig->pr_comp); |
| 441 | 445 | ||
| 446 | rcu_assign_pointer(orig->se_lun, NULL); | ||
| 447 | rcu_assign_pointer(orig->se_lun_acl, NULL); | ||
| 448 | |||
| 442 | kfree_rcu(orig, rcu_head); | 449 | kfree_rcu(orig, rcu_head); |
| 443 | 450 | ||
| 444 | core_scsi3_free_pr_reg_from_nacl(dev, nacl); | 451 | core_scsi3_free_pr_reg_from_nacl(dev, nacl); |
diff --git a/drivers/target/target_core_hba.c b/drivers/target/target_core_hba.c index 9522960c7fdd..22390e0e046c 100644 --- a/drivers/target/target_core_hba.c +++ b/drivers/target/target_core_hba.c | |||
| @@ -187,5 +187,5 @@ core_delete_hba(struct se_hba *hba) | |||
| 187 | 187 | ||
| 188 | bool target_sense_desc_format(struct se_device *dev) | 188 | bool target_sense_desc_format(struct se_device *dev) |
| 189 | { | 189 | { |
| 190 | return dev->transport->get_blocks(dev) > U32_MAX; | 190 | return (dev) ? dev->transport->get_blocks(dev) > U32_MAX : false; |
| 191 | } | 191 | } |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 5a9982f5d5d6..0f19e11acac2 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
| @@ -105,6 +105,8 @@ static int iblock_configure_device(struct se_device *dev) | |||
| 105 | mode = FMODE_READ|FMODE_EXCL; | 105 | mode = FMODE_READ|FMODE_EXCL; |
| 106 | if (!ib_dev->ibd_readonly) | 106 | if (!ib_dev->ibd_readonly) |
| 107 | mode |= FMODE_WRITE; | 107 | mode |= FMODE_WRITE; |
| 108 | else | ||
| 109 | dev->dev_flags |= DF_READ_ONLY; | ||
| 108 | 110 | ||
| 109 | bd = blkdev_get_by_path(ib_dev->ibd_udev_path, mode, ib_dev); | 111 | bd = blkdev_get_by_path(ib_dev->ibd_udev_path, mode, ib_dev); |
| 110 | if (IS_ERR(bd)) { | 112 | if (IS_ERR(bd)) { |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 5ab7100de17e..e7933115087a 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
| @@ -618,7 +618,7 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration( | |||
| 618 | struct se_device *dev, | 618 | struct se_device *dev, |
| 619 | struct se_node_acl *nacl, | 619 | struct se_node_acl *nacl, |
| 620 | struct se_lun *lun, | 620 | struct se_lun *lun, |
| 621 | struct se_dev_entry *deve, | 621 | struct se_dev_entry *dest_deve, |
| 622 | u64 mapped_lun, | 622 | u64 mapped_lun, |
| 623 | unsigned char *isid, | 623 | unsigned char *isid, |
| 624 | u64 sa_res_key, | 624 | u64 sa_res_key, |
| @@ -640,7 +640,29 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration( | |||
| 640 | INIT_LIST_HEAD(&pr_reg->pr_reg_atp_mem_list); | 640 | INIT_LIST_HEAD(&pr_reg->pr_reg_atp_mem_list); |
| 641 | atomic_set(&pr_reg->pr_res_holders, 0); | 641 | atomic_set(&pr_reg->pr_res_holders, 0); |
| 642 | pr_reg->pr_reg_nacl = nacl; | 642 | pr_reg->pr_reg_nacl = nacl; |
| 643 | pr_reg->pr_reg_deve = deve; | 643 | /* |
| 644 | * For destination registrations for ALL_TG_PT=1 and SPEC_I_PT=1, | ||
| 645 | * the se_dev_entry->pr_ref will have been already obtained by | ||
| 646 | * core_get_se_deve_from_rtpi() or __core_scsi3_alloc_registration(). | ||
| 647 | * | ||
| 648 | * Otherwise, locate se_dev_entry now and obtain a reference until | ||
| 649 | * registration completes in __core_scsi3_add_registration(). | ||
| 650 | */ | ||
| 651 | if (dest_deve) { | ||
| 652 | pr_reg->pr_reg_deve = dest_deve; | ||
| 653 | } else { | ||
| 654 | rcu_read_lock(); | ||
| 655 | pr_reg->pr_reg_deve = target_nacl_find_deve(nacl, mapped_lun); | ||
| 656 | if (!pr_reg->pr_reg_deve) { | ||
| 657 | rcu_read_unlock(); | ||
| 658 | pr_err("Unable to locate PR deve %s mapped_lun: %llu\n", | ||
| 659 | nacl->initiatorname, mapped_lun); | ||
| 660 | kmem_cache_free(t10_pr_reg_cache, pr_reg); | ||
| 661 | return NULL; | ||
| 662 | } | ||
| 663 | kref_get(&pr_reg->pr_reg_deve->pr_kref); | ||
| 664 | rcu_read_unlock(); | ||
| 665 | } | ||
| 644 | pr_reg->pr_res_mapped_lun = mapped_lun; | 666 | pr_reg->pr_res_mapped_lun = mapped_lun; |
| 645 | pr_reg->pr_aptpl_target_lun = lun->unpacked_lun; | 667 | pr_reg->pr_aptpl_target_lun = lun->unpacked_lun; |
| 646 | pr_reg->tg_pt_sep_rtpi = lun->lun_rtpi; | 668 | pr_reg->tg_pt_sep_rtpi = lun->lun_rtpi; |
| @@ -936,17 +958,29 @@ static int __core_scsi3_check_aptpl_registration( | |||
| 936 | !(strcmp(pr_reg->pr_tport, t_port)) && | 958 | !(strcmp(pr_reg->pr_tport, t_port)) && |
| 937 | (pr_reg->pr_reg_tpgt == tpgt) && | 959 | (pr_reg->pr_reg_tpgt == tpgt) && |
| 938 | (pr_reg->pr_aptpl_target_lun == target_lun)) { | 960 | (pr_reg->pr_aptpl_target_lun == target_lun)) { |
| 961 | /* | ||
| 962 | * Obtain the ->pr_reg_deve pointer + reference, that | ||
| 963 | * is released by __core_scsi3_add_registration() below. | ||
| 964 | */ | ||
| 965 | rcu_read_lock(); | ||
| 966 | pr_reg->pr_reg_deve = target_nacl_find_deve(nacl, mapped_lun); | ||
| 967 | if (!pr_reg->pr_reg_deve) { | ||
| 968 | pr_err("Unable to locate PR APTPL %s mapped_lun:" | ||
| 969 | " %llu\n", nacl->initiatorname, mapped_lun); | ||
| 970 | rcu_read_unlock(); | ||
| 971 | continue; | ||
| 972 | } | ||
| 973 | kref_get(&pr_reg->pr_reg_deve->pr_kref); | ||
| 974 | rcu_read_unlock(); | ||
| 939 | 975 | ||
| 940 | pr_reg->pr_reg_nacl = nacl; | 976 | pr_reg->pr_reg_nacl = nacl; |
| 941 | pr_reg->tg_pt_sep_rtpi = lun->lun_rtpi; | 977 | pr_reg->tg_pt_sep_rtpi = lun->lun_rtpi; |
| 942 | |||
| 943 | list_del(&pr_reg->pr_reg_aptpl_list); | 978 | list_del(&pr_reg->pr_reg_aptpl_list); |
| 944 | spin_unlock(&pr_tmpl->aptpl_reg_lock); | 979 | spin_unlock(&pr_tmpl->aptpl_reg_lock); |
| 945 | /* | 980 | /* |
| 946 | * At this point all of the pointers in *pr_reg will | 981 | * At this point all of the pointers in *pr_reg will |
| 947 | * be setup, so go ahead and add the registration. | 982 | * be setup, so go ahead and add the registration. |
| 948 | */ | 983 | */ |
| 949 | |||
| 950 | __core_scsi3_add_registration(dev, nacl, pr_reg, 0, 0); | 984 | __core_scsi3_add_registration(dev, nacl, pr_reg, 0, 0); |
| 951 | /* | 985 | /* |
| 952 | * If this registration is the reservation holder, | 986 | * If this registration is the reservation holder, |
| @@ -1044,18 +1078,11 @@ static void __core_scsi3_add_registration( | |||
| 1044 | 1078 | ||
| 1045 | __core_scsi3_dump_registration(tfo, dev, nacl, pr_reg, register_type); | 1079 | __core_scsi3_dump_registration(tfo, dev, nacl, pr_reg, register_type); |
| 1046 | spin_unlock(&pr_tmpl->registration_lock); | 1080 | spin_unlock(&pr_tmpl->registration_lock); |
| 1047 | |||
| 1048 | rcu_read_lock(); | ||
| 1049 | deve = pr_reg->pr_reg_deve; | ||
| 1050 | if (deve) | ||
| 1051 | set_bit(DEF_PR_REG_ACTIVE, &deve->deve_flags); | ||
| 1052 | rcu_read_unlock(); | ||
| 1053 | |||
| 1054 | /* | 1081 | /* |
| 1055 | * Skip extra processing for ALL_TG_PT=0 or REGISTER_AND_MOVE. | 1082 | * Skip extra processing for ALL_TG_PT=0 or REGISTER_AND_MOVE. |
| 1056 | */ | 1083 | */ |
| 1057 | if (!pr_reg->pr_reg_all_tg_pt || register_move) | 1084 | if (!pr_reg->pr_reg_all_tg_pt || register_move) |
| 1058 | return; | 1085 | goto out; |
| 1059 | /* | 1086 | /* |
| 1060 | * Walk pr_reg->pr_reg_atp_list and add registrations for ALL_TG_PT=1 | 1087 | * Walk pr_reg->pr_reg_atp_list and add registrations for ALL_TG_PT=1 |
| 1061 | * allocated in __core_scsi3_alloc_registration() | 1088 | * allocated in __core_scsi3_alloc_registration() |
| @@ -1075,19 +1102,31 @@ static void __core_scsi3_add_registration( | |||
| 1075 | __core_scsi3_dump_registration(tfo, dev, nacl_tmp, pr_reg_tmp, | 1102 | __core_scsi3_dump_registration(tfo, dev, nacl_tmp, pr_reg_tmp, |
| 1076 | register_type); | 1103 | register_type); |
| 1077 | spin_unlock(&pr_tmpl->registration_lock); | 1104 | spin_unlock(&pr_tmpl->registration_lock); |
| 1078 | 1105 | /* | |
| 1106 | * Drop configfs group dependency reference and deve->pr_kref | ||
| 1107 | * obtained from __core_scsi3_alloc_registration() code. | ||
| 1108 | */ | ||
| 1079 | rcu_read_lock(); | 1109 | rcu_read_lock(); |
| 1080 | deve = pr_reg_tmp->pr_reg_deve; | 1110 | deve = pr_reg_tmp->pr_reg_deve; |
| 1081 | if (deve) | 1111 | if (deve) { |
| 1082 | set_bit(DEF_PR_REG_ACTIVE, &deve->deve_flags); | 1112 | set_bit(DEF_PR_REG_ACTIVE, &deve->deve_flags); |
| 1113 | core_scsi3_lunacl_undepend_item(deve); | ||
| 1114 | pr_reg_tmp->pr_reg_deve = NULL; | ||
| 1115 | } | ||
| 1083 | rcu_read_unlock(); | 1116 | rcu_read_unlock(); |
| 1084 | |||
| 1085 | /* | ||
| 1086 | * Drop configfs group dependency reference from | ||
| 1087 | * __core_scsi3_alloc_registration() | ||
| 1088 | */ | ||
| 1089 | core_scsi3_lunacl_undepend_item(pr_reg_tmp->pr_reg_deve); | ||
| 1090 | } | 1117 | } |
| 1118 | out: | ||
| 1119 | /* | ||
| 1120 | * Drop deve->pr_kref obtained in __core_scsi3_do_alloc_registration() | ||
| 1121 | */ | ||
| 1122 | rcu_read_lock(); | ||
| 1123 | deve = pr_reg->pr_reg_deve; | ||
| 1124 | if (deve) { | ||
| 1125 | set_bit(DEF_PR_REG_ACTIVE, &deve->deve_flags); | ||
| 1126 | kref_put(&deve->pr_kref, target_pr_kref_release); | ||
| 1127 | pr_reg->pr_reg_deve = NULL; | ||
| 1128 | } | ||
| 1129 | rcu_read_unlock(); | ||
| 1091 | } | 1130 | } |
| 1092 | 1131 | ||
| 1093 | static int core_scsi3_alloc_registration( | 1132 | static int core_scsi3_alloc_registration( |
| @@ -1785,9 +1824,11 @@ core_scsi3_decode_spec_i_port( | |||
| 1785 | dest_node_acl->initiatorname, i_buf, (dest_se_deve) ? | 1824 | dest_node_acl->initiatorname, i_buf, (dest_se_deve) ? |
| 1786 | dest_se_deve->mapped_lun : 0); | 1825 | dest_se_deve->mapped_lun : 0); |
| 1787 | 1826 | ||
| 1788 | if (!dest_se_deve) | 1827 | if (!dest_se_deve) { |
| 1828 | kref_put(&local_pr_reg->pr_reg_deve->pr_kref, | ||
| 1829 | target_pr_kref_release); | ||
| 1789 | continue; | 1830 | continue; |
| 1790 | 1831 | } | |
| 1791 | core_scsi3_lunacl_undepend_item(dest_se_deve); | 1832 | core_scsi3_lunacl_undepend_item(dest_se_deve); |
| 1792 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1833 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
| 1793 | core_scsi3_tpg_undepend_item(dest_tpg); | 1834 | core_scsi3_tpg_undepend_item(dest_tpg); |
| @@ -1823,9 +1864,11 @@ out: | |||
| 1823 | 1864 | ||
| 1824 | kmem_cache_free(t10_pr_reg_cache, dest_pr_reg); | 1865 | kmem_cache_free(t10_pr_reg_cache, dest_pr_reg); |
| 1825 | 1866 | ||
| 1826 | if (!dest_se_deve) | 1867 | if (!dest_se_deve) { |
| 1868 | kref_put(&local_pr_reg->pr_reg_deve->pr_kref, | ||
| 1869 | target_pr_kref_release); | ||
| 1827 | continue; | 1870 | continue; |
| 1828 | 1871 | } | |
| 1829 | core_scsi3_lunacl_undepend_item(dest_se_deve); | 1872 | core_scsi3_lunacl_undepend_item(dest_se_deve); |
| 1830 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1873 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
| 1831 | core_scsi3_tpg_undepend_item(dest_tpg); | 1874 | core_scsi3_tpg_undepend_item(dest_tpg); |
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 2d0381dd105c..5fb9dd7f08bb 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c | |||
| @@ -668,7 +668,10 @@ int core_tpg_add_lun( | |||
| 668 | list_add_tail(&lun->lun_dev_link, &dev->dev_sep_list); | 668 | list_add_tail(&lun->lun_dev_link, &dev->dev_sep_list); |
| 669 | spin_unlock(&dev->se_port_lock); | 669 | spin_unlock(&dev->se_port_lock); |
| 670 | 670 | ||
| 671 | lun->lun_access = lun_access; | 671 | if (dev->dev_flags & DF_READ_ONLY) |
| 672 | lun->lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; | ||
| 673 | else | ||
| 674 | lun->lun_access = lun_access; | ||
| 672 | if (!(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) | 675 | if (!(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) |
| 673 | hlist_add_head_rcu(&lun->link, &tpg->tpg_lun_hlist); | 676 | hlist_add_head_rcu(&lun->link, &tpg->tpg_lun_hlist); |
| 674 | mutex_unlock(&tpg->tpg_lun_mutex); | 677 | mutex_unlock(&tpg->tpg_lun_mutex); |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index ac9bf1c0e42d..5f48754dc36a 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
| @@ -730,6 +730,7 @@ struct se_device { | |||
| 730 | #define DF_EMULATED_VPD_UNIT_SERIAL 0x00000004 | 730 | #define DF_EMULATED_VPD_UNIT_SERIAL 0x00000004 |
| 731 | #define DF_USING_UDEV_PATH 0x00000008 | 731 | #define DF_USING_UDEV_PATH 0x00000008 |
| 732 | #define DF_USING_ALIAS 0x00000010 | 732 | #define DF_USING_ALIAS 0x00000010 |
| 733 | #define DF_READ_ONLY 0x00000020 | ||
| 733 | /* Physical device queue depth */ | 734 | /* Physical device queue depth */ |
| 734 | u32 queue_depth; | 735 | u32 queue_depth; |
| 735 | /* Used for SPC-2 reservations enforce of ISIDs */ | 736 | /* Used for SPC-2 reservations enforce of ISIDs */ |
