aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/mds_client.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2013-09-21 22:28:10 -0400
committerSage Weil <sage@inktank.com>2013-11-23 14:01:01 -0500
commit44c99757fae80e9db058e1f1d7419cf6472e9af1 (patch)
tree9bf7bbb62d915a26b9cee8b52b7d5f6649adca13 /fs/ceph/mds_client.c
parenta096b09aeec6ff99edfdfd8cee24d6f25377d585 (diff)
ceph: set caps count after composing cap reconnect message
It's possible that some caps get released while composing the cap reconnect message. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com> Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'fs/ceph/mds_client.c')
-rw-r--r--fs/ceph/mds_client.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 8f8f5c043c37..4a93d69abc8b 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -43,6 +43,7 @@
43 */ 43 */
44 44
45struct ceph_reconnect_state { 45struct ceph_reconnect_state {
46 int nr_caps;
46 struct ceph_pagelist *pagelist; 47 struct ceph_pagelist *pagelist;
47 bool flock; 48 bool flock;
48}; 49};
@@ -2549,6 +2550,8 @@ encode_again:
2549 } else { 2550 } else {
2550 err = ceph_pagelist_append(pagelist, &rec, reclen); 2551 err = ceph_pagelist_append(pagelist, &rec, reclen);
2551 } 2552 }
2553
2554 recon_state->nr_caps++;
2552out_free: 2555out_free:
2553 kfree(path); 2556 kfree(path);
2554out_dput: 2557out_dput:
@@ -2576,6 +2579,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
2576 struct rb_node *p; 2579 struct rb_node *p;
2577 int mds = session->s_mds; 2580 int mds = session->s_mds;
2578 int err = -ENOMEM; 2581 int err = -ENOMEM;
2582 int s_nr_caps;
2579 struct ceph_pagelist *pagelist; 2583 struct ceph_pagelist *pagelist;
2580 struct ceph_reconnect_state recon_state; 2584 struct ceph_reconnect_state recon_state;
2581 2585
@@ -2611,10 +2615,12 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
2611 discard_cap_releases(mdsc, session); 2615 discard_cap_releases(mdsc, session);
2612 2616
2613 /* traverse this session's caps */ 2617 /* traverse this session's caps */
2614 err = ceph_pagelist_encode_32(pagelist, session->s_nr_caps); 2618 s_nr_caps = session->s_nr_caps;
2619 err = ceph_pagelist_encode_32(pagelist, s_nr_caps);
2615 if (err) 2620 if (err)
2616 goto fail; 2621 goto fail;
2617 2622
2623 recon_state.nr_caps = 0;
2618 recon_state.pagelist = pagelist; 2624 recon_state.pagelist = pagelist;
2619 recon_state.flock = session->s_con.peer_features & CEPH_FEATURE_FLOCK; 2625 recon_state.flock = session->s_con.peer_features & CEPH_FEATURE_FLOCK;
2620 err = iterate_session_caps(session, encode_caps_cb, &recon_state); 2626 err = iterate_session_caps(session, encode_caps_cb, &recon_state);
@@ -2643,11 +2649,18 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
2643 2649
2644 if (recon_state.flock) 2650 if (recon_state.flock)
2645 reply->hdr.version = cpu_to_le16(2); 2651 reply->hdr.version = cpu_to_le16(2);
2646 if (pagelist->length) { 2652
2647 /* set up outbound data if we have any */ 2653 /* raced with cap release? */
2648 reply->hdr.data_len = cpu_to_le32(pagelist->length); 2654 if (s_nr_caps != recon_state.nr_caps) {
2649 ceph_msg_data_add_pagelist(reply, pagelist); 2655 struct page *page = list_first_entry(&pagelist->head,
2656 struct page, lru);
2657 __le32 *addr = kmap_atomic(page);
2658 *addr = cpu_to_le32(recon_state.nr_caps);
2659 kunmap_atomic(addr);
2650 } 2660 }
2661
2662 reply->hdr.data_len = cpu_to_le32(pagelist->length);
2663 ceph_msg_data_add_pagelist(reply, pagelist);
2651 ceph_con_send(&session->s_con, reply); 2664 ceph_con_send(&session->s_con, reply);
2652 2665
2653 mutex_unlock(&session->s_mutex); 2666 mutex_unlock(&session->s_mutex);