}
}
-void CInode::choose_lock_states()
+void CInode::choose_lock_states(int dirty_caps)
{
- int issued = get_caps_issued();
+ int issued = get_caps_issued() | dirty_caps;
if (is_auth() && (issued & (CEPH_CAP_ANY_EXCL|CEPH_CAP_ANY_WR)) &&
choose_ideal_loner() >= 0)
try_set_loner();
// choose new lock state during recovery, based on issued caps
void choose_lock_state(SimpleLock *lock, int allissued);
- void choose_lock_states();
+ void choose_lock_states(int dirty_caps);
int count_nonstale_caps() {
int n = 0;
<< " op " << ceph_cap_op_name(m->get_op()) << dendl;
if (!mds->is_clientreplay() && !mds->is_active() && !mds->is_stopping()) {
+ 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());
+ }
mds->wait_for_replay(new C_MDS_RetryMessage(mds, m));
return;
}
if (in->is_auth() && !in->is_base() && in->inode.is_dirty_rstat())
in->mark_dirty_rstat();
- in->choose_lock_states();
+ 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;
+ in->choose_lock_states(dirty_caps);
dout(15) << " chose lock states on " << *in << dendl;
SnapRealm *realm = in->find_snaprealm();
}
cap_imports.clear();
+ cap_imports_dirty.clear();
if (warn_str.peek() != EOF) {
mds->clog->warn() << "failed to reconnect caps for missing inodes:" << "\n";
if (in->is_replicated()) {
mds->locker->try_eval(in, CEPH_CAP_LOCKS);
} else {
- in->choose_lock_states();
+ 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;
+ in->choose_lock_states(dirty_caps);
dout(15) << " chose lock states on " << *in << dendl;
}
}
map<inodeno_t,map<client_t,map<mds_rank_t,ceph_mds_cap_reconnect> > > cap_imports; // ino -> client -> frommds -> capex
map<inodeno_t,filepath> cap_import_paths;
+ map<inodeno_t,int> cap_imports_dirty;
set<inodeno_t> cap_imports_missing;
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;
+ }
// [reconnect/rejoin caps]
map<CInode*,map<client_t, inodeno_t> > reconnected_caps; // inode -> client -> realmino