diff options
author | Sage Weil <sage@newdream.net> | 2010-02-15 19:22:28 -0500 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-02-17 01:01:11 -0500 |
commit | 5ce6e9dbe6805ab8ee67e21936d17f431adc63c6 (patch) | |
tree | 9aca0fdc38afc5755d59eb3ba84c86f26df44012 | |
parent | 85ff03f6bfef7d5b59ab3aefd4773f497ffad8a4 (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>
-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) | |||
96 | } | 96 | } |
97 | 97 | ||
98 | /* | 98 | /* |
99 | * Send an auth request. | ||
100 | */ | ||
101 | static 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 | */ |
101 | static void __close_session(struct ceph_mon_client *monc) | 113 | static 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 | ||
653 | static 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 | |||
663 | static void handle_auth_reply(struct ceph_mon_client *monc, | 660 | static void handle_auth_reply(struct ceph_mon_client *monc, |
664 | struct ceph_msg *msg) | 661 | struct ceph_msg *msg) |
665 | { | 662 | { |