diff options
author | Sage Weil <sage@newdream.net> | 2010-02-16 03:22:28 +0300 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-02-17 09:01:11 +0300 |
commit | 5ce6e9dbe6805ab8ee67e21936d17f431adc63c6 (patch) | |
tree | 9aca0fdc38afc5755d59eb3ba84c86f26df44012 /fs/ceph/mon_client.c | |
parent | 85ff03f6bfef7d5b59ab3aefd4773f497ffad8a4 (diff) | |
download | linux-5ce6e9dbe6805ab8ee67e21936d17f431adc63c6.tar.xz |
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/mon_client.c')
-rw-r--r-- | fs/ceph/mon_client.c | 29 |
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) { |