return ret;
continue;
}
- if ((mds_wanted & file_wanted) ==
- (file_wanted & (CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR))) {
+ if (!(file_wanted & ~mds_wanted))
in->flags &= ~I_CAP_DROPPED;
- }
}
if (waitfor_caps)
if (reconnect) {
in.requested_max_size = 0;
in.wanted_max_size = 0;
+ } else {
+ if (cap->gen < s->cap_gen) {
+ // mds did not re-issue stale cap.
+ cap->issued = cap->implemented = CEPH_CAP_PIN;
+ // make sure mds knows what we want.
+ if (in.caps_file_wanted() & ~cap->wanted)
+ in.flags |= I_CAP_DROPPED;
+ }
}
signal_cond_list(in.waitfor_caps);
}
const auto &capem = in->caps.emplace(std::piecewise_construct, std::forward_as_tuple(mds), std::forward_as_tuple(*in, mds_session));
Cap &cap = capem.first->second;
if (!capem.second) {
+ if (cap.gen < mds_session->cap_gen)
+ cap.issued = cap.implemented = CEPH_CAP_PIN;
+
/*
* auth mds of the inode changed. we received the cap export
* message, but still haven't received the cap import message.
dirty_caps = in->dirty_caps | in->flushing_caps;
in->wanted_max_size = 0;
in->requested_max_size = 0;
- in->flags |= I_CAP_DROPPED;
}
+ if (cap->wanted | cap->issued)
+ in->flags |= I_CAP_DROPPED;
remove_cap(cap, false);
- signal_cond_list(in->waitfor_caps);
if (cap_snaps) {
in->cap_snaps.clear();
}
in->mark_caps_clean();
put_inode(in.get());
}
+ signal_cond_list(in->waitfor_caps);
}
s->flushing_caps_tids.clear();
sync_cond.Signal();
auto it = in->caps.find(mds);
if (it != in->caps.end()) {
Cap &cap = it->second;
- const mds_rank_t peer_mds = mds_rank_t(m->peer.mds);
-
if (cap.cap_id == m->get_cap_id()) {
if (m->peer.cap_id) {
+ const auto peer_mds = mds_rank_t(m->peer.mds);
MetaSession *tsession = _get_or_open_mds_session(peer_mds);
auto it = in->caps.find(peer_mds);
if (it != in->caps.end()) {
cap.latest_perms);
}
} else {
- if (&cap == in->auth_cap)
+ if (cap.wanted | cap.issued)
in->flags |= I_CAP_DROPPED;
}
int used = get_caps_used(in);
int wanted = in->caps_wanted();
- const int old_caps = cap->issued;
- const int new_caps = m->get_caps();
+ const unsigned new_caps = m->get_caps();
const bool was_stale = session->cap_gen > cap->gen;
ldout(cct, 5) << __func__ << " on in " << m->get_ino()
<< " mds." << mds << " seq " << m->get_seq()
<< " caps now " << ccap_string(new_caps)
- << " was " << ccap_string(old_caps) << dendl;
+ << " was " << ccap_string(cap->issued)
+ << (was_stale ? "" : " (stale)") << dendl;
+
+ if (was_stale)
+ cap->issued = cap->implemented = CEPH_CAP_PIN;
cap->seq = m->get_seq();
cap->gen = session->cap_gen;
+ check_cap_issue(in, cap, new_caps);
+
// update inode
int issued;
in->caps_issued(&issued);
check = true;
}
- check_cap_issue(in, cap, new_caps);
// update caps
- int revoked = old_caps & ~new_caps;
+ auto revoked = cap->issued & ~new_caps;
if (revoked) {
ldout(cct, 10) << " revocation of " << ccap_string(revoked) << dendl;
cap->issued = new_caps;
cap->wanted = 0; // don't let check_caps skip sending a response to MDS
check = true;
}
- } else if (old_caps == new_caps) {
- ldout(cct, 10) << " caps unchanged at " << ccap_string(old_caps) << dendl;
+ } else if (cap->issued == new_caps) {
+ ldout(cct, 10) << " caps unchanged at " << ccap_string(cap->issued) << dendl;
} else {
- ldout(cct, 10) << " grant, new caps are " << ccap_string(new_caps & ~old_caps) << dendl;
+ ldout(cct, 10) << " grant, new caps are " << ccap_string(new_caps & ~cap->issued) << dendl;
cap->issued = new_caps;
cap->implemented |= new_caps;