From: Yan, Zheng Date: Thu, 14 Nov 2019 12:15:14 +0000 (+0800) Subject: mds: fix revoking caps after after stale->resume circle X-Git-Tag: v14.2.8~62^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6d1ce3faa679355440c322ba0f261c5cba6a4e65;p=ceph.git mds: fix revoking caps after after stale->resume circle 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" 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" --- diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 4880fc6bf3fd..3b3b0c8cb361 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -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);