]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix revoking caps after after stale->resume circle 32909/head
authorYan, Zheng <zyan@redhat.com>
Thu, 14 Nov 2019 12:15:14 +0000 (20:15 +0800)
committerNathan Cutler <ncutler@suse.com>
Mon, 27 Jan 2020 16:43:02 +0000 (17:43 +0100)
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
(cherry picked from commit b6898d65a8e5f044a7bd46005d7a8e8a3d258742)

Conflicts:
src/mds/Locker.cc
- nautilus uses MClientCaps::create where master has "make_message<MClientCaps>"

src/mds/Locker.cc

index 4880fc6bf3fd9f99be2fb1f812874ae90ed751c0..3b3b0c8cb361d677e08205bd214889189f30f2ef 100644 (file)
@@ -2034,6 +2034,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 = MClientCaps::create(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.
@@ -2072,10 +2090,8 @@ int Locker::issue_caps(CInode *in, Capability *only_cap)
 
       auto m = MClientCaps::create(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);