]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - fs/ceph/messenger.c
ceph: invalidate_authorizer without con->mutex held
[mirror_ubuntu-artful-kernel.git] / fs / ceph / messenger.c
index 44bdaf4399245e90c82d603b64287b11dc55082e..9ea7b763c8dce3346ec530b1f726c1c5d1b63e74 100644 (file)
@@ -344,6 +344,7 @@ void ceph_con_close(struct ceph_connection *con)
        clear_bit(STANDBY, &con->state);  /* avoid connect_seq bump */
        mutex_lock(&con->mutex);
        reset_connection(con);
+       cancel_delayed_work(&con->work);
        mutex_unlock(&con->mutex);
        queue_con(con);
 }
@@ -1360,7 +1361,7 @@ static int read_partial_message(struct ceph_connection *con)
                con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip);
                if (skip) {
                        /* skip this message */
-                       pr_err("alloc_msg returned NULL, skipping message\n");
+                       dout("alloc_msg returned NULL, skipping message\n");
                        con->in_base_pos = -front_len - middle_len - data_len -
                                sizeof(m->footer);
                        con->in_tag = CEPH_MSGR_TAG_READY;
@@ -1369,7 +1370,8 @@ static int read_partial_message(struct ceph_connection *con)
                if (IS_ERR(con->in_msg)) {
                        ret = PTR_ERR(con->in_msg);
                        con->in_msg = NULL;
-                       con->error_msg = "error allocating memory for incoming message";
+                       con->error_msg =
+                               "error allocating memory for incoming message";
                        return ret;
                }
                m = con->in_msg;
@@ -1808,7 +1810,7 @@ done:
        clear_bit(BUSY, &con->state);
        dout("con->state=%lu\n", con->state);
        if (test_bit(QUEUED, &con->state)) {
-               if (!backoff) {
+               if (!backoff || test_bit(OPENING, &con->state)) {
                        dout("con_work %p QUEUED reset, looping\n", con);
                        goto more;
                }
@@ -1841,6 +1843,8 @@ static void ceph_fault(struct ceph_connection *con)
        clear_bit(BUSY, &con->state);  /* to avoid an improbable race */
 
        mutex_lock(&con->mutex);
+       if (test_bit(CLOSED, &con->state))
+               goto out_unlock;
 
        con_close_socket(con);
 
@@ -1849,14 +1853,6 @@ static void ceph_fault(struct ceph_connection *con)
                con->in_msg = NULL;
        }
 
-       /*
-        * in case we faulted due to authentication, invalidate our
-        * current tickets so that we can get new ones.
-         */
-       if (con->auth_retry && con->ops->invalidate_authorizer) {
-               dout("calling invalidate_authorizer()\n");
-               con->ops->invalidate_authorizer(con);
-       }
 
        /* If there are no messages in the queue, place the connection
         * in a STANDBY state (i.e., don't try to reconnect just yet). */
@@ -1876,8 +1872,6 @@ static void ceph_fault(struct ceph_connection *con)
        else if (con->delay < MAX_DELAY_INTERVAL)
                con->delay *= 2;
 
-       mutex_unlock(&con->mutex);
-
        /* explicitly schedule work to try to reconnect again later. */
        dout("fault queueing %p delay %lu\n", con, con->delay);
        con->ops->get(con);
@@ -1885,7 +1879,18 @@ static void ceph_fault(struct ceph_connection *con)
                               round_jiffies_relative(con->delay)) == 0)
                con->ops->put(con);
 
+out_unlock:
+       mutex_unlock(&con->mutex);
 out:
+       /*
+        * in case we faulted due to authentication, invalidate our
+        * current tickets so that we can get new ones.
+         */
+       if (con->auth_retry && con->ops->invalidate_authorizer) {
+               dout("calling invalidate_authorizer()\n");
+               con->ops->invalidate_authorizer(con);
+       }
+
        if (con->ops->fault)
                con->ops->fault(con);
 }