summaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-02-15 16:22:28 -0800
committerSage Weil <sage@newdream.net>2010-02-16 22:01:11 -0800
commit5ce6e9dbe6805ab8ee67e21936d17f431adc63c6 (patch)
tree9aca0fdc38afc5755d59eb3ba84c86f26df44012 /fs/ceph
parent85ff03f6bfef7d5b59ab3aefd4773f497ffad8a4 (diff)
downloadlinux-5ce6e9dbe6805ab8ee67e21936d17f431adc63c6.tar.bz2
ceph: fix authentication races, auth_none oops
Call __validate_auth() under monc->mutex, and use helper for initial hello so that the pending_auth flag is set. This fixes possible races in which we have an authentication request (hello or otherwise) pending and send another one. In particular, with auth_none, we _never_ want to call ceph_build_auth() from __validate_auth(), since the ->build_request() method is NULL. Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/mon_client.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c
index 542276e60798..40d7d90bbed1 100644
--- a/fs/ceph/mon_client.c
+++ b/fs/ceph/mon_client.c
@@ -96,6 +96,18 @@ int ceph_monmap_contains(struct ceph_monmap *m, struct ceph_entity_addr *addr)
}
/*
+ * Send an auth request.
+ */
+static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len)
+{
+ monc->pending_auth = 1;
+ monc->m_auth->front.iov_len = len;
+ monc->m_auth->hdr.front_len = cpu_to_le32(len);
+ ceph_msg_get(monc->m_auth); /* keep our ref */
+ ceph_con_send(monc->con, monc->m_auth);
+}
+
+/*
* Close monitor session, if any.
*/
static void __close_session(struct ceph_mon_client *monc)
@@ -137,10 +149,7 @@ static int __open_session(struct ceph_mon_client *monc)
ret = ceph_auth_build_hello(monc->auth,
monc->m_auth->front.iov_base,
monc->m_auth->front_max);
- monc->m_auth->front.iov_len = ret;
- monc->m_auth->hdr.front_len = cpu_to_le32(ret);
- ceph_msg_get(monc->m_auth); /* keep our ref */
- ceph_con_send(monc->con, monc->m_auth);
+ __send_prepared_auth_request(monc, ret);
} else {
dout("open_session mon%d already open\n", monc->cur_mon);
}
@@ -507,11 +516,9 @@ static void delayed_work(struct work_struct *work)
__open_session(monc); /* continue hunting */
} else {
ceph_con_keepalive(monc->con);
- mutex_unlock(&monc->mutex);
__validate_auth(monc);
- mutex_lock(&monc->mutex);
if (monc->auth->ops->is_authenticated(monc->auth))
__send_subscribe(monc);
}
@@ -650,16 +657,6 @@ void ceph_monc_stop(struct ceph_mon_client *monc)
kfree(monc->monmap);
}
-static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len)
-{
- monc->pending_auth = 1;
- monc->m_auth->front.iov_len = len;
- monc->m_auth->hdr.front_len = cpu_to_le32(len);
- ceph_msg_get(monc->m_auth); /* keep our ref */
- ceph_con_send(monc->con, monc->m_auth);
-}
-
-
static void handle_auth_reply(struct ceph_mon_client *monc,
struct ceph_msg *msg)
{