]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: do not defer releasing caps when revoking 43782/head
authorXiubo Li <xiubli@redhat.com>
Wed, 20 Oct 2021 04:03:07 +0000 (12:03 +0800)
committerXiubo Li <xiubli@redhat.com>
Wed, 3 Nov 2021 01:55:31 +0000 (09:55 +0800)
When revoking caps the if we queue to defer releasing them after 5s
or client_caps_release_delay. What if when the client keeps doing
mark_caps_dirty() for that inode in some use cases, the inode will
always be pushed back to the end of dirty_list. And in the tick()
it will check the dirty_list from front and will skip looping it
when it finds current one is not out of date.

This may cause the revocation in the MDS side stuck for a long
time.

Fixes: https://tracker.ceph.com/issues/52994
Signed-off-by: Xiubo Li <xiubli@redhat.com>
(cherry picked from commit 66098eeb1dbd0ffb4478c866ab4208e471d709f1)

src/client/Client.cc

index 3f344c3fa378ea33eb43e3426b90b650239925b5..f30c9d09a8af96818ac4455ed8797d6a2401fe6d 100644 (file)
@@ -5456,6 +5456,7 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, const M
   mds_rank_t mds = session->mds_num;
   int used = get_caps_used(in);
   int wanted = in->caps_wanted();
+  int flags = 0;
 
   const unsigned new_caps = m->get_caps();
   const bool was_stale = session->cap_gen > cap->gen;
@@ -5569,11 +5570,14 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, const M
        !_flush(in, new C_Client_FlushComplete(this, in))) {
       // waitin' for flush
     } else if (used & revoked & (CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO)) {
-      if (_release(in))
-       check = true;
+      if (_release(in)) {
+        check = true;
+        flags = CHECK_CAPS_NODELAY;
+      }
     } else {
       cap->wanted = 0; // don't let check_caps skip sending a response to MDS
       check = true;
+      flags = CHECK_CAPS_NODELAY;
     }
   } else if (cap->issued == new_caps) {
     ldout(cct, 10) << "  caps unchanged at " << ccap_string(cap->issued) << dendl;
@@ -5596,7 +5600,7 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, const M
   }
 
   if (check)
-    check_caps(in, 0);
+    check_caps(in, flags);
 
   // wake up waiters
   if (new_caps)