From: Yan, Zheng Date: Mon, 24 Jul 2017 12:32:00 +0000 (+0800) Subject: mds: new cap message flags indicate if there is pending capsnap X-Git-Tag: v13.0.1~1021^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ecde54faa601eaba1e2b25989360ccba1e936bd8;p=ceph-ci.git mds: new cap message flags indicate if there is pending capsnap These flags tell mds if there is pending capsnap explictly. Without this explict notification, mds can only conclude if client has pending capsnap. The method mds use is inefficient and error-prone. Fixes: http://tracker.ceph.com/issues/20752 Signed-off-by: "Yan, Zheng" --- diff --git a/src/client/Client.cc b/src/client/Client.cc index e461ab4a59e..c7a7d70e7ee 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3323,7 +3323,11 @@ void Client::send_cap(Inode *in, MetaSession *session, Cap *cap, m->time_warp_seq = in->time_warp_seq; m->change_attr = in->change_attr; if (sync) - m->flags |= CLIENT_CAPS_SYNC; + m->flags |= MClientCaps::FLAG_SYNC; + if (in->cap_snaps.empty()) + m->flags |= MClientCaps::FLAG_NO_CAPSNAP; + else + m->flags |= MClientCaps::FLAG_PENDING_CAPSNAP; if (flush & CEPH_CAP_FILE_WR) { m->inline_version = in->inline_version; diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 6460972fe99..f76c698d8be 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -2587,10 +2587,10 @@ void Locker::handle_client_caps(MClientCaps *m) snapid_t follows = m->get_snap_follows(); dout(7) << "handle_client_caps " - << ((m->flags & CLIENT_CAPS_SYNC) ? "sync" : "async") << " on " << m->get_ino() << " tid " << m->get_client_tid() << " follows " << follows - << " op " << ceph_cap_op_name(m->get_op()) << dendl; + << " op " << ceph_cap_op_name(m->get_op()) + << " flags 0x" << hex << m->flags << dendl; if (!mds->is_clientreplay() && !mds->is_active() && !mds->is_stopping()) { if (!session) { @@ -2812,7 +2812,9 @@ void Locker::handle_client_caps(MClientCaps *m) // released all WR/EXCL caps (the FLUSHSNAP always comes before the cap // update/release). if (!head_in->client_need_snapflush.empty()) { - if ((cap->issued() & CEPH_CAP_ANY_FILE_WR) == 0) { + if ((m->flags & MClientCaps::FLAG_NO_CAPSNAP) || + (!(cap->issued() & CEPH_CAP_ANY_FILE_WR) && + !(m->flags & MClientCaps::FLAG_PENDING_CAPSNAP))) { head_in->auth_pin(this); // prevent subtree frozen need_unpin = true; _do_null_snapflush(head_in, client); @@ -2831,7 +2833,7 @@ void Locker::handle_client_caps(MClientCaps *m) } // filter wanted based on what we could ever give out (given auth/replica status) - bool need_flush = m->flags & CLIENT_CAPS_SYNC; + bool need_flush = m->flags & MClientCaps::FLAG_SYNC; int new_wanted = m->get_wanted() & head_in->get_caps_allowed_ever(); if (new_wanted != cap->wanted()) { if (!need_flush && (new_wanted & ~cap->pending())) { diff --git a/src/messages/MClientCaps.h b/src/messages/MClientCaps.h index e973b634138..acc6242ccf7 100644 --- a/src/messages/MClientCaps.h +++ b/src/messages/MClientCaps.h @@ -18,13 +18,15 @@ #include "msg/Message.h" #include "include/ceph_features.h" -#define CLIENT_CAPS_SYNC (0x1) - class MClientCaps : public Message { static const int HEAD_VERSION = 10; static const int COMPAT_VERSION = 1; public: + static const unsigned FLAG_SYNC = (1<<0); + static const unsigned FLAG_NO_CAPSNAP = (1<<1); + static const unsigned FLAG_PENDING_CAPSNAP = (1<<2); + struct ceph_mds_caps_head head; uint64_t size, max_size, truncate_size, change_attr;