aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-05-11 00:58:38 -0400
committerSage Weil <sage@newdream.net>2010-05-11 12:53:57 -0400
commit9abf82b8bc93dd904738a71ca69aa5df356d4d24 (patch)
tree208c5112173832092f93b8d91b8e8ec6f36209aa
parentd85b705663905b3dae30007f824355bdcfcf3f00 (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.c29
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
2221out:
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
2230fail: 2229fail:
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);
2232fail_nomsg: 2234fail_nomsg:
2233 ceph_pagelist_release(pagelist); 2235 ceph_pagelist_release(pagelist);
2234 kfree(pagelist); 2236 kfree(pagelist);
2235fail_nopagelist: 2237fail_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