]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: new cap message flags indicate if there is pending capsnap
authorYan, Zheng <zyan@redhat.com>
Mon, 24 Jul 2017 12:32:00 +0000 (20:32 +0800)
committerYan, Zheng <zyan@redhat.com>
Fri, 18 Aug 2017 07:11:17 +0000 (15:11 +0800)
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" <zyan@redhat.com>
src/client/Client.cc
src/mds/Locker.cc
src/messages/MClientCaps.h

index e461ab4a59eb2157f20e0db8c7441858d511e84a..c7a7d70e7ee997fdb3173118557bcb12b8a31ca7 100644 (file)
@@ -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;
index 6460972fe993b6e32df9e9ef7afcf5df4d2775e8..f76c698d8beb03b9bc67b54896db53dcd8b8e787 100644 (file)
@@ -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())) {
index e973b63413818eadcf5e0f55557841a077a43f8c..acc6242ccf78f298c2d26846aa543222ff0114a1 100644 (file)
 #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;