diff options
author | Sage Weil <sage@newdream.net> | 2010-05-11 00:58:38 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-05-11 12:53:57 -0400 |
commit | 9abf82b8bc93dd904738a71ca69aa5df356d4d24 (patch) | |
tree | 208c5112173832092f93b8d91b8e8ec6f36209aa /fs/ceph | |
parent | d85b705663905b3dae30007f824355bdcfcf3f00 (diff) |
ceph: fix locking for waking session requests after reconnect
The session->s_waiting list is protected by mdsc->mutex, not s_mutex. This
was causing (rare) s_waiting list corruption.
Fix errors paths too, while we're here. A more thorough cleanup of this
function is coming soon.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/mds_client.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 60a9a4ae47be..eccc0ecad1a2 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -2136,7 +2136,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) | |||
2136 | struct ceph_mds_session *session = NULL; | 2136 | struct ceph_mds_session *session = NULL; |
2137 | struct ceph_msg *reply; | 2137 | struct ceph_msg *reply; |
2138 | struct rb_node *p; | 2138 | struct rb_node *p; |
2139 | int err; | 2139 | int err = -ENOMEM; |
2140 | struct ceph_pagelist *pagelist; | 2140 | struct ceph_pagelist *pagelist; |
2141 | 2141 | ||
2142 | pr_info("reconnect to recovering mds%d\n", mds); | 2142 | pr_info("reconnect to recovering mds%d\n", mds); |
@@ -2185,7 +2185,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) | |||
2185 | goto fail; | 2185 | goto fail; |
2186 | err = iterate_session_caps(session, encode_caps_cb, pagelist); | 2186 | err = iterate_session_caps(session, encode_caps_cb, pagelist); |
2187 | if (err < 0) | 2187 | if (err < 0) |
2188 | goto out; | 2188 | goto fail; |
2189 | 2189 | ||
2190 | /* | 2190 | /* |
2191 | * snaprealms. we provide mds with the ino, seq (version), and | 2191 | * snaprealms. we provide mds with the ino, seq (version), and |
@@ -2213,28 +2213,31 @@ send: | |||
2213 | reply->nr_pages = calc_pages_for(0, pagelist->length); | 2213 | reply->nr_pages = calc_pages_for(0, pagelist->length); |
2214 | ceph_con_send(&session->s_con, reply); | 2214 | ceph_con_send(&session->s_con, reply); |
2215 | 2215 | ||
2216 | if (session) { | 2216 | session->s_state = CEPH_MDS_SESSION_OPEN; |
2217 | session->s_state = CEPH_MDS_SESSION_OPEN; | 2217 | mutex_unlock(&session->s_mutex); |
2218 | __wake_requests(mdsc, &session->s_waiting); | 2218 | |
2219 | } | 2219 | mutex_lock(&mdsc->mutex); |
2220 | __wake_requests(mdsc, &session->s_waiting); | ||
2221 | mutex_unlock(&mdsc->mutex); | ||
2222 | |||
2223 | ceph_put_mds_session(session); | ||
2220 | 2224 | ||
2221 | out: | ||
2222 | up_read(&mdsc->snap_rwsem); | 2225 | up_read(&mdsc->snap_rwsem); |
2223 | if (session) { | ||
2224 | mutex_unlock(&session->s_mutex); | ||
2225 | ceph_put_mds_session(session); | ||
2226 | } | ||
2227 | mutex_lock(&mdsc->mutex); | 2226 | mutex_lock(&mdsc->mutex); |
2228 | return; | 2227 | return; |
2229 | 2228 | ||
2230 | fail: | 2229 | fail: |
2231 | ceph_msg_put(reply); | 2230 | ceph_msg_put(reply); |
2231 | up_read(&mdsc->snap_rwsem); | ||
2232 | mutex_unlock(&session->s_mutex); | ||
2233 | ceph_put_mds_session(session); | ||
2232 | fail_nomsg: | 2234 | fail_nomsg: |
2233 | ceph_pagelist_release(pagelist); | 2235 | ceph_pagelist_release(pagelist); |
2234 | kfree(pagelist); | 2236 | kfree(pagelist); |
2235 | fail_nopagelist: | 2237 | fail_nopagelist: |
2236 | pr_err("ENOMEM preparing reconnect for mds%d\n", mds); | 2238 | pr_err("error %d preparing reconnect for mds%d\n", err, mds); |
2237 | goto out; | 2239 | mutex_lock(&mdsc->mutex); |
2240 | return; | ||
2238 | } | 2241 | } |
2239 | 2242 | ||
2240 | 2243 | ||