if (mds->is_reconnect() &&
m->get_dirty() && m->get_client_tid() > 0 &&
!session->have_completed_flush(m->get_client_tid())) {
- mdcache->set_reconnect_dirty_caps(m->get_ino(), m->get_dirty());
+ mdcache->set_reconnected_dirty_caps(client, m->get_ino(), m->get_dirty());
}
mds->wait_for_replay(new C_MDS_RetryMessage(mds, m));
return;
assert(session);
for (auto r = q->second.begin(); r != q->second.end(); ++r) {
Capability *cap = in->reconnect_cap(q->first, r->second, session);
- add_reconnected_cap(in, q->first, r->second);
+ add_reconnected_cap(q->first, in->ino(), r->second);
if (r->first >= 0) {
if (cap->get_last_seq() == 0) // don't increase mseq if cap already exists
cap->inc_mseq();
if (in->is_auth() && !in->is_base() && in->inode.is_dirty_rstat())
in->mark_dirty_rstat();
+ auto p = reconnected_caps.find(in->ino());
+
int dirty_caps = 0;
- map<inodeno_t, int>::iterator it = cap_imports_dirty.find(in->ino());
- if (it != cap_imports_dirty.end())
- dirty_caps = it->second;
+ if (p != reconnected_caps.end()) {
+ for (const auto &it : p->second)
+ dirty_caps |= it.second.dirty_caps;
+ }
in->choose_lock_states(dirty_caps);
dout(15) << " chose lock states on " << *in << dendl;
check_realm_past_parents(realm);
- auto p = reconnected_caps.find(in);
if (p != reconnected_caps.end()) {
bool missing_snap_parent = false;
// also, make sure client's cap is in the correct snaprealm.
mds->queue_waiters(p->second);
cap_imports.clear();
- cap_imports_dirty.clear();
cap_reconnect_waiters.clear();
if (warn_str.peek() != EOF) {
mds->locker->try_eval(in, CEPH_CAP_LOCKS);
} else {
int dirty_caps = 0;
- map<inodeno_t, int>::iterator it = cap_imports_dirty.find(in->ino());
- if (it != cap_imports_dirty.end())
- dirty_caps = it->second;
+ auto p = reconnected_caps.find(in->ino());
+ if (p != reconnected_caps.end()) {
+ auto q = p->second.find(client);
+ if (q != p->second.end())
+ dirty_caps = q->second.dirty_caps;
+ }
in->choose_lock_states(dirty_caps);
dout(15) << " chose lock states on " << *in << dendl;
}
dout(10) << " past parents now open on " << *in << dendl;
for (CInode *child : p->second) {
- auto q = reconnected_caps.find(child);
+ auto q = reconnected_caps.find(child->ino());
assert(q != reconnected_caps.end());
for (auto r = q->second.begin(); r != q->second.end(); ++r) {
if (r->second.snap_follows > 0 && r->second.snap_follows < in->first - 1) {
map<inodeno_t,mds_rank_t> cap_export_targets; // ino -> auth mds
map<inodeno_t,map<client_t,map<mds_rank_t,cap_reconnect_t> > > cap_imports; // ino -> client -> frommds -> capex
- map<inodeno_t,int> cap_imports_dirty;
set<inodeno_t> cap_imports_missing;
map<inodeno_t, list<MDSInternalContextBase*> > cap_reconnect_waiters;
int cap_imports_num_opening;
assert(cap_imports[ino][client].size() == 1);
cap_imports.erase(ino);
}
- void set_reconnect_dirty_caps(inodeno_t ino, int dirty) {
- cap_imports_dirty[ino] |= dirty;
- }
void wait_replay_cap_reconnect(inodeno_t ino, MDSInternalContextBase *c) {
cap_reconnect_waiters[ino].push_back(c);
}
struct reconnected_cap_info_t {
inodeno_t realm_ino;
snapid_t snap_follows;
- reconnected_cap_info_t() : realm_ino(0), snap_follows(0) {}
+ int dirty_caps;
+ reconnected_cap_info_t() :
+ realm_ino(0), snap_follows(0), dirty_caps(0) {}
};
- map<CInode*,map<client_t, reconnected_cap_info_t> > reconnected_caps; // inode -> client -> snap_follows,realmino
+ map<inodeno_t,map<client_t, reconnected_cap_info_t> > reconnected_caps; // inode -> client -> snap_follows,realmino
map<inodeno_t,map<client_t, snapid_t> > reconnected_snaprealms; // realmino -> client -> realmseq
- void add_reconnected_cap(CInode *in, client_t client, const cap_reconnect_t& icr) {
- reconnected_cap_info_t &info = reconnected_caps[in][client];
+ void add_reconnected_cap(client_t client, inodeno_t ino, const cap_reconnect_t& icr) {
+ reconnected_cap_info_t &info = reconnected_caps[ino][client];
info.realm_ino = inodeno_t(icr.capinfo.snaprealm);
info.snap_follows = icr.snap_follows;
}
+ void set_reconnected_dirty_caps(client_t client, inodeno_t ino, int dirty) {
+ reconnected_cap_info_t &info = reconnected_caps[ino][client];
+ info.dirty_caps |= dirty;
+ }
void add_reconnected_snaprealm(client_t client, inodeno_t ino, snapid_t seq) {
reconnected_snaprealms[ino][client] = seq;
}
dout(15) << "open cap realm " << inodeno_t(p->second.capinfo.snaprealm)
<< " on " << *in << dendl;
in->reconnect_cap(from, p->second, session);
- mdcache->add_reconnected_cap(in, from, p->second);
+ mdcache->add_reconnected_cap(from, p->first, p->second);
recover_filelocks(in, p->second.flockbl, m->get_orig_source().num());
continue;
}