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.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 e461ab4a59eb..c7a7d70e7ee9 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 6460972fe993..f76c698d8beb 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 e973b6341381..acc6242ccf78 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;