]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: skip updating 'wanted' caps if caps are already issued
authorYan, Zheng <zyan@redhat.com>
Thu, 22 Nov 2018 07:02:36 +0000 (15:02 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 5 Feb 2019 08:53:22 +0000 (16:53 +0800)
When reading cached inode that already has Fscr caps, this can avoid
two cap messages (one updats 'wanted' caps, one clears 'wanted' caps).

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
(cherry picked from commit d20b260ecf3f323c87ad1e6865f87e2381444546)

 Conflicts:
src/client/Client.cc

src/client/Client.cc

index 324c468edefbcc44cf28bf4f2fd989ba79811f26..000ed48ca0d3dac1d4d275a9f102baa9cab4bf70 100644 (file)
@@ -3527,9 +3527,8 @@ void Client::check_caps(Inode *in, unsigned flags)
     if (!revoking && unmounting && (cap_used == 0))
       goto ack;
 
-    if (wanted == cap->wanted &&         // mds knows what we want.
-       ((cap->issued & ~retain) == 0) &&// and we don't have anything we wouldn't like
-       !in->dirty_caps)                 // and we have no dirty caps
+    if ((cap->issued & ~retain) == 0 && // and we don't have anything we wouldn't like
+       !in->dirty_caps)               // and we have no dirty caps
       continue;
 
     if (now < in->hold_caps_until) {
@@ -5115,6 +5114,7 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, MClient
 
   const int old_caps = cap->issued;
   const int new_caps = m->get_caps();
+  const bool was_stale = session->cap_gen > cap->gen;
   ldout(cct, 5) << "handle_cap_grant on in " << m->get_ino() 
                << " mds." << mds << " seq " << m->get_seq()
                << " caps now " << ccap_string(new_caps)
@@ -5188,8 +5188,17 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, MClient
   }
 
   bool check = false;
-  if (m->get_op() == CEPH_CAP_OP_IMPORT && m->get_wanted() != wanted)
+  if ((was_stale || m->get_op() == CEPH_CAP_OP_IMPORT) &&
+      (wanted & ~(cap->wanted | new_caps))) {
+    // If mds is importing cap, prior cap messages that update 'wanted'
+    // may get dropped by mds (migrate seq mismatch).
+    //
+    // We don't send cap message to update 'wanted' if what we want are
+    // already issued. If mds revokes caps, cap message that releases caps
+    // also tells mds what we want. But if caps got revoked by mds forcedly
+    // (session stale). We may haven't told mds what we want.
     check = true;
+  }
 
   check_cap_issue(in, cap, new_caps);