]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix revoking caps after after stale->resume circle 31662/head
authorYan, Zheng <zyan@redhat.com>
Thu, 14 Nov 2019 12:15:14 +0000 (20:15 +0800)
committerYan, Zheng <zyan@redhat.com>
Fri, 15 Nov 2019 03:49:43 +0000 (11:49 +0800)
After session stale->resume circle, client thinks its caps get lost. But
MDS may keep some client caps untouched. To revoke untouched caps, MDS
needs to re-issue them to client, then do revocation. If MDS skips the
're-issue' step, client will not response to the cap revoke.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Fixes: https://tracker.ceph.com/issues/42826
src/mds/Locker.cc

index 27d8a16eb57f0e37730c03633349d77f23895712..0a6455e360860a7f7793d91ef09fddc090d15190 100644 (file)
@@ -2022,6 +2022,24 @@ int Locker::issue_caps(CInode *in, Capability *only_cap)
        mds->queue_waiter_front(new C_Locker_RevokeStaleCap(this, in, it->first));
        continue;
       }
+
+      if (!cap->is_valid() && (pending & ~CEPH_CAP_PIN)) {
+       // After stale->resume circle, client thinks it only has CEPH_CAP_PIN.
+       // mds needs to re-issue caps, then do revocation.
+       long seq = cap->issue(pending, true);
+
+       dout(7) << "   sending MClientCaps to client." << it->first
+               << " seq " << seq << " re-issue " << ccap_string(pending) << dendl;
+
+       auto m = make_message<MClientCaps>(CEPH_CAP_OP_GRANT, in->ino(),
+                                          in->find_snaprealm()->inode->ino(),
+                                          cap->get_cap_id(), cap->get_last_seq(),
+                                          pending, wanted, 0, cap->get_mseq(),
+                                          mds->get_osd_epoch_barrier());
+       in->encode_cap_message(m, cap);
+
+       mds->send_message_client_counted(m, cap->get_session());
+      }
     }
 
     // notify clients about deleted inode, to make sure they release caps ASAP.
@@ -2060,10 +2078,8 @@ int Locker::issue_caps(CInode *in, Capability *only_cap)
 
       auto m = make_message<MClientCaps>(op, in->ino(),
                                         in->find_snaprealm()->inode->ino(),
-                                        cap->get_cap_id(),
-                                        cap->get_last_seq(),
-                                        after, wanted, 0,
-                                        cap->get_mseq(),
+                                        cap->get_cap_id(), cap->get_last_seq(),
+                                        after, wanted, 0, cap->get_mseq(),
                                         mds->get_osd_epoch_barrier());
       in->encode_cap_message(m, cap);