Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
[cascardo/linux.git] / drivers / infiniband / ulp / isert / ib_isert.c
index b9d6474..d4c7928 100644 (file)
@@ -663,8 +663,9 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
 
        pi_support = np->tpg_np->tpg->tpg_attrib.t10_pi;
        if (pi_support && !device->pi_capable) {
-               pr_err("Protection information requested but not supported\n");
-               ret = -EINVAL;
+               pr_err("Protection information requested but not supported, "
+                      "rejecting connect request\n");
+               ret = rdma_reject(cma_id, NULL, 0);
                goto out_mr;
        }
 
@@ -787,14 +788,12 @@ isert_disconnect_work(struct work_struct *work)
                isert_put_conn(isert_conn);
                return;
        }
-       if (!isert_conn->logout_posted) {
-               pr_debug("Calling rdma_disconnect for !logout_posted from"
-                        " isert_disconnect_work\n");
+
+       if (isert_conn->disconnect) {
+               /* Send DREQ/DREP towards our initiator */
                rdma_disconnect(isert_conn->conn_cm_id);
-               mutex_unlock(&isert_conn->conn_mutex);
-               iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
-               goto wake_up;
        }
+
        mutex_unlock(&isert_conn->conn_mutex);
 
 wake_up:
@@ -803,10 +802,11 @@ wake_up:
 }
 
 static void
-isert_disconnected_handler(struct rdma_cm_id *cma_id)
+isert_disconnected_handler(struct rdma_cm_id *cma_id, bool disconnect)
 {
        struct isert_conn *isert_conn = (struct isert_conn *)cma_id->context;
 
+       isert_conn->disconnect = disconnect;
        INIT_WORK(&isert_conn->conn_logout_work, isert_disconnect_work);
        schedule_work(&isert_conn->conn_logout_work);
 }
@@ -815,29 +815,28 @@ static int
 isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
 {
        int ret = 0;
+       bool disconnect = false;
 
        pr_debug("isert_cma_handler: event %d status %d conn %p id %p\n",
                 event->event, event->status, cma_id->context, cma_id);
 
        switch (event->event) {
        case RDMA_CM_EVENT_CONNECT_REQUEST:
-               pr_debug("RDMA_CM_EVENT_CONNECT_REQUEST: >>>>>>>>>>>>>>>\n");
                ret = isert_connect_request(cma_id, event);
                break;
        case RDMA_CM_EVENT_ESTABLISHED:
-               pr_debug("RDMA_CM_EVENT_ESTABLISHED >>>>>>>>>>>>>>\n");
                isert_connected_handler(cma_id);
                break;
-       case RDMA_CM_EVENT_DISCONNECTED:
-               pr_debug("RDMA_CM_EVENT_DISCONNECTED: >>>>>>>>>>>>>>\n");
-               isert_disconnected_handler(cma_id);
-               break;
-       case RDMA_CM_EVENT_DEVICE_REMOVAL:
-       case RDMA_CM_EVENT_ADDR_CHANGE:
+       case RDMA_CM_EVENT_ADDR_CHANGE:    /* FALLTHRU */
+       case RDMA_CM_EVENT_DISCONNECTED:   /* FALLTHRU */
+       case RDMA_CM_EVENT_DEVICE_REMOVAL: /* FALLTHRU */
+               disconnect = true;
+       case RDMA_CM_EVENT_TIMEWAIT_EXIT:  /* FALLTHRU */
+               isert_disconnected_handler(cma_id, disconnect);
                break;
        case RDMA_CM_EVENT_CONNECT_ERROR:
        default:
-               pr_err("Unknown RDMA CMA event: %d\n", event->event);
+               pr_err("Unhandled RDMA CMA event: %d\n", event->event);
                break;
        }
 
@@ -1054,7 +1053,9 @@ isert_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login,
        }
        if (!login->login_failed) {
                if (login->login_complete) {
-                       if (isert_conn->conn_device->use_fastreg) {
+                       if (!conn->sess->sess_ops->SessionType &&
+                           isert_conn->conn_device->use_fastreg) {
+                               /* Normal Session and fastreg is used */
                                u8 pi_support = login->np->tpg_np->tpg->tpg_attrib.t10_pi;
 
                                ret = isert_conn_create_fastreg_pool(isert_conn,
@@ -1824,11 +1825,8 @@ isert_do_control_comp(struct work_struct *work)
                break;
        case ISTATE_SEND_LOGOUTRSP:
                pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n");
-               /*
-                * Call atomic_dec(&isert_conn->post_send_buf_count)
-                * from isert_wait_conn()
-                */
-               isert_conn->logout_posted = true;
+
+               atomic_dec(&isert_conn->post_send_buf_count);
                iscsit_logout_post_handler(cmd, cmd->conn);
                break;
        case ISTATE_SEND_TEXTRSP:
@@ -2034,6 +2032,8 @@ isert_cq_rx_comp_err(struct isert_conn *isert_conn)
        isert_conn->state = ISER_CONN_DOWN;
        mutex_unlock(&isert_conn->conn_mutex);
 
+       iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+
        complete(&isert_conn->conn_wait_comp_err);
 }
 
@@ -2320,7 +2320,7 @@ isert_put_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
        int rc;
 
        isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc);
-       rc = iscsit_build_text_rsp(cmd, conn, hdr);
+       rc = iscsit_build_text_rsp(cmd, conn, hdr, ISCSI_INFINIBAND);
        if (rc < 0)
                return rc;
 
@@ -3156,9 +3156,14 @@ accept_wait:
                return -ENODEV;
 
        spin_lock_bh(&np->np_thread_lock);
-       if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
+       if (np->np_thread_state >= ISCSI_NP_THREAD_RESET) {
                spin_unlock_bh(&np->np_thread_lock);
-               pr_debug("ISCSI_NP_THREAD_RESET for isert_accept_np\n");
+               pr_debug("np_thread_state %d for isert_accept_np\n",
+                        np->np_thread_state);
+               /**
+                * No point in stalling here when np_thread
+                * is in state RESET/SHUTDOWN/EXIT - bail
+                **/
                return -ENODEV;
        }
        spin_unlock_bh(&np->np_thread_lock);
@@ -3208,15 +3213,9 @@ static void isert_wait_conn(struct iscsi_conn *conn)
        struct isert_conn *isert_conn = conn->context;
 
        pr_debug("isert_wait_conn: Starting \n");
-       /*
-        * Decrement post_send_buf_count for special case when called
-        * from isert_do_control_comp() -> iscsit_logout_post_handler()
-        */
-       mutex_lock(&isert_conn->conn_mutex);
-       if (isert_conn->logout_posted)
-               atomic_dec(&isert_conn->post_send_buf_count);
 
-       if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) {
+       mutex_lock(&isert_conn->conn_mutex);
+       if (isert_conn->conn_cm_id) {
                pr_debug("Calling rdma_disconnect from isert_wait_conn\n");
                rdma_disconnect(isert_conn->conn_cm_id);
        }
@@ -3293,6 +3292,7 @@ destroy_rx_wq:
 
 static void __exit isert_exit(void)
 {
+       flush_scheduled_work();
        destroy_workqueue(isert_comp_wq);
        destroy_workqueue(isert_rx_wq);
        iscsit_unregister_transport(&iser_target_transport);