libceph: move ceph_con_send() closed check under the con mutex
Sage Weil [Fri, 20 Jul 2012 22:34:04 +0000 (15:34 -0700)]
Take the con mutex before checking whether the connection is closed to
avoid racing with someone else closing it.

Signed-off-by: Sage Weil <sage@inktank.com>

net/ceph/messenger.c

index 1a3cb4a..20e60a8 100644 (file)
@@ -2453,22 +2453,20 @@ static void clear_standby(struct ceph_connection *con)
  */
 void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg)
 {
-       if (test_bit(CLOSED, &con->state)) {
-               dout("con_send %p closed, dropping %p\n", con, msg);
-               ceph_msg_put(msg);
-               return;
-       }
-
        /* set src+dst */
        msg->hdr.src = con->msgr->inst.name;
-
        BUG_ON(msg->front.iov_len != le32_to_cpu(msg->hdr.front_len));
-
        msg->needs_out_seq = true;
 
-       /* queue */
        mutex_lock(&con->mutex);
 
+       if (test_bit(CLOSED, &con->state)) {
+               dout("con_send %p closed, dropping %p\n", con, msg);
+               ceph_msg_put(msg);
+               mutex_unlock(&con->mutex);
+               return;
+       }
+
        BUG_ON(msg->con != NULL);
        msg->con = con->ops->get(con);
        BUG_ON(msg->con == NULL);