got_mds_push(session.get());
+ bool do_cap_release = false;
Inode *in;
vinodeno_t vino(m->get_ino(), CEPH_NOSNAP);
if (auto it = inode_map.find(vino); it != inode_map.end()) {
in = it->second;
+
+ /* MDS maybe waiting for cap release with increased seq */
+ switch (m->get_op()) {
+ case CEPH_CAP_OP_REVOKE:
+ case CEPH_CAP_OP_GRANT:
+ if (!in->caps.count(mds)) {
+ do_cap_release = true;
+ ldout(cct, 5) << __func__ << " vino " << vino << " don't have cap "
+ << m->get_cap_id() << " op " << m->get_op()
+ << ", immediately releasing" << dendl;
+ }
+ }
} else {
- if (m->get_op() == CEPH_CAP_OP_IMPORT) {
- ldout(cct, 5) << __func__ << " don't have vino " << vino << " on IMPORT, immediately releasing" << dendl;
- session->enqueue_cap_release(
- m->get_ino(),
- m->get_cap_id(),
- m->get_seq(),
- m->get_mseq(),
- cap_epoch_barrier);
- } else {
- ldout(cct, 5) << __func__ << " don't have vino " << vino << ", dropping" << dendl;
+ /* MDS maybe waiting for cap release with increased seq */
+ switch (m->get_op()) {
+ case CEPH_CAP_OP_IMPORT:
+ case CEPH_CAP_OP_REVOKE:
+ case CEPH_CAP_OP_GRANT:
+ do_cap_release = true;
+ ldout(cct, 5) << __func__ << " don't have vino " << vino << " op "
+ << m->get_op() << ", immediately releasing" << dendl;
+ break;
+ default:
+ ldout(cct, 5) << __func__ << " don't have vino " << vino << ", dropping" << dendl;
+ return;
}
+ }
+
+ // In case the mds is waiting on e.g. a revocation
+ if (do_cap_release) {
+ session->enqueue_cap_release(
+ m->get_ino(),
+ m->get_cap_id(),
+ m->get_seq(),
+ m->get_mseq(),
+ cap_epoch_barrier);
- // in case the mds is waiting on e.g. a revocation
flush_cap_releases();
return;
}