aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2015-02-04 01:26:22 -0500
committerIlya Dryomov <idryomov@gmail.com>2015-02-19 05:31:40 -0500
commit3de22be6771353241eaec237fe594dfea3daf30f (patch)
tree3710a3d0bd5c4883a51ed189ad4b763ec4cd82be /fs
parent2a0b61cefcd52ad63ff03aacae6d4113cdf46812 (diff)
ceph: re-send requests when MDS enters reconnecting stage
So that MDS can check if any request is already completed and process completed requests in clientreplay stage. When completed requests are processed in clientreplay stage, MDS can avoid sending traceless replies. Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ceph/mds_client.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 03482c0974b6..4c1e36a171af 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2184,6 +2184,8 @@ static void kick_requests(struct ceph_mds_client *mdsc, int mds)
2184 p = rb_next(p); 2184 p = rb_next(p);
2185 if (req->r_got_unsafe) 2185 if (req->r_got_unsafe)
2186 continue; 2186 continue;
2187 if (req->r_attempts > 0)
2188 continue; /* only new requests */
2187 if (req->r_session && 2189 if (req->r_session &&
2188 req->r_session->s_mds == mds) { 2190 req->r_session->s_mds == mds) {
2189 dout(" kicking tid %llu\n", req->r_tid); 2191 dout(" kicking tid %llu\n", req->r_tid);
@@ -2517,6 +2519,7 @@ static void handle_forward(struct ceph_mds_client *mdsc,
2517 dout("forward tid %llu to mds%d (we resend)\n", tid, next_mds); 2519 dout("forward tid %llu to mds%d (we resend)\n", tid, next_mds);
2518 BUG_ON(req->r_err); 2520 BUG_ON(req->r_err);
2519 BUG_ON(req->r_got_result); 2521 BUG_ON(req->r_got_result);
2522 req->r_attempts = 0;
2520 req->r_num_fwd = fwd_seq; 2523 req->r_num_fwd = fwd_seq;
2521 req->r_resend_mds = next_mds; 2524 req->r_resend_mds = next_mds;
2522 put_request_session(req); 2525 put_request_session(req);
@@ -2648,6 +2651,7 @@ static void replay_unsafe_requests(struct ceph_mds_client *mdsc,
2648 struct ceph_mds_session *session) 2651 struct ceph_mds_session *session)
2649{ 2652{
2650 struct ceph_mds_request *req, *nreq; 2653 struct ceph_mds_request *req, *nreq;
2654 struct rb_node *p;
2651 int err; 2655 int err;
2652 2656
2653 dout("replay_unsafe_requests mds%d\n", session->s_mds); 2657 dout("replay_unsafe_requests mds%d\n", session->s_mds);
@@ -2660,6 +2664,28 @@ static void replay_unsafe_requests(struct ceph_mds_client *mdsc,
2660 ceph_con_send(&session->s_con, req->r_request); 2664 ceph_con_send(&session->s_con, req->r_request);
2661 } 2665 }
2662 } 2666 }
2667
2668 /*
2669 * also re-send old requests when MDS enters reconnect stage. So that MDS
2670 * can process completed request in clientreplay stage.
2671 */
2672 p = rb_first(&mdsc->request_tree);
2673 while (p) {
2674 req = rb_entry(p, struct ceph_mds_request, r_node);
2675 p = rb_next(p);
2676 if (req->r_got_unsafe)
2677 continue;
2678 if (req->r_attempts == 0)
2679 continue; /* only old requests */
2680 if (req->r_session &&
2681 req->r_session->s_mds == session->s_mds) {
2682 err = __prepare_send_request(mdsc, req, session->s_mds);
2683 if (!err) {
2684 ceph_msg_get(req->r_request);
2685 ceph_con_send(&session->s_con, req->r_request);
2686 }
2687 }
2688 }
2663 mutex_unlock(&mdsc->mutex); 2689 mutex_unlock(&mdsc->mutex);
2664} 2690}
2665 2691
@@ -2977,9 +3003,6 @@ static void check_new_map(struct ceph_mds_client *mdsc,
2977 mutex_unlock(&s->s_mutex); 3003 mutex_unlock(&s->s_mutex);
2978 s->s_state = CEPH_MDS_SESSION_RESTARTING; 3004 s->s_state = CEPH_MDS_SESSION_RESTARTING;
2979 } 3005 }
2980
2981 /* kick any requests waiting on the recovering mds */
2982 kick_requests(mdsc, i);
2983 } else if (oldstate == newstate) { 3006 } else if (oldstate == newstate) {
2984 continue; /* nothing new with this mds */ 3007 continue; /* nothing new with this mds */
2985 } 3008 }