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 | |
| 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>
| -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 | ||
