aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-02-15 19:22:28 -0500
committerSage Weil <sage@newdream.net>2010-02-17 01:01:11 -0500
commit5ce6e9dbe6805ab8ee67e21936d17f431adc63c6 (patch)
tree9aca0fdc38afc5755d59eb3ba84c86f26df44012 /fs/ceph
parent85ff03f6bfef7d5b59ab3aefd4773f497ffad8a4 (diff)
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)
96} 96}
97 97
98/* 98/*
99 * Send an auth request.
100 */
101static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len)
102{
103 monc->pending_auth = 1;
104 monc->m_auth->front.iov_len = len;
105 monc->m_auth->hdr.front_len = cpu_to_le32(len);
106 ceph_msg_get(monc->m_auth); /* keep our ref */
107 ceph_con_send(monc->con, monc->m_auth);
108}
109
110/*
99 * Close monitor session, if any. 111 * Close monitor session, if any.
100 */ 112 */
101static void __close_session(struct ceph_mon_client *monc) 113static void __close_session(struct ceph_mon_client *monc)
@@ -137,10 +149,7 @@ static int __open_session(struct ceph_mon_client *monc)
137 ret = ceph_auth_build_hello(monc->auth, 149 ret = ceph_auth_build_hello(monc->auth,
138 monc->m_auth->front.iov_base, 150 monc->m_auth->front.iov_base,
139 monc->m_auth->front_max); 151 monc->m_auth->front_max);
140 monc->m_auth->front.iov_len = ret; 152 __send_prepared_auth_request(monc, ret);
141 monc->m_auth->hdr.front_len = cpu_to_le32(ret);
142 ceph_msg_get(monc->m_auth); /* keep our ref */
143 ceph_con_send(monc->con, monc->m_auth);
144 } else { 153 } else {
145 dout("open_session mon%d already open\n", monc->cur_mon); 154 dout("open_session mon%d already open\n", monc->cur_mon);
146 } 155 }
@@ -507,11 +516,9 @@ static void delayed_work(struct work_struct *work)
507 __open_session(monc); /* continue hunting */ 516 __open_session(monc); /* continue hunting */
508 } else { 517 } else {
509 ceph_con_keepalive(monc->con); 518 ceph_con_keepalive(monc->con);
510 mutex_unlock(&monc->mutex);
511 519
512 __validate_auth(monc); 520 __validate_auth(monc);
513 521
514 mutex_lock(&monc->mutex);
515 if (monc->auth->ops->is_authenticated(monc->auth)) 522 if (monc->auth->ops->is_authenticated(monc->auth))
516 __send_subscribe(monc); 523 __send_subscribe(monc);
517 } 524 }
@@ -650,16 +657,6 @@ void ceph_monc_stop(struct ceph_mon_client *monc)
650 kfree(monc->monmap); 657 kfree(monc->monmap);
651} 658}
652 659
653static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len)
654{
655 monc->pending_auth = 1;
656 monc->m_auth->front.iov_len = len;
657 monc->m_auth->hdr.front_len = cpu_to_le32(len);
658 ceph_msg_get(monc->m_auth); /* keep our ref */
659 ceph_con_send(monc->con, monc->m_auth);
660}
661
662
663static void handle_auth_reply(struct ceph_mon_client *monc, 660static void handle_auth_reply(struct ceph_mon_client *monc,
664 struct ceph_msg *msg) 661 struct ceph_msg *msg)
665{ 662{