mirror of
https://github.com/ceph/ceph
synced 2025-03-25 11:48:05 +00:00
Merge pull request #6432 from ukernel/wip-11482
mds: fix client capabilities during reconnect (client.XXXX isn't responding to mclientcaps(revoke)) Reviewed-by: John Spray <john.spray@redhat.com>
This commit is contained in:
commit
304965f17e
@ -2498,14 +2498,16 @@ void Client::send_reconnect(MetaSession *session)
|
||||
bufferlist flockbl;
|
||||
_encode_filelocks(in, flockbl);
|
||||
|
||||
in->caps[mds]->seq = 0; // reset seq.
|
||||
in->caps[mds]->issue_seq = 0; // reset seq.
|
||||
in->caps[mds]->mseq = 0; // reset seq.
|
||||
Cap *cap = in->caps[mds];
|
||||
cap->seq = 0; // reset seq.
|
||||
cap->issue_seq = 0; // reset seq.
|
||||
cap->mseq = 0; // reset seq.
|
||||
cap->issued = cap->implemented;
|
||||
m->add_cap(p->first.ino,
|
||||
in->caps[mds]->cap_id,
|
||||
cap->cap_id,
|
||||
path.get_ino(), path.get_path(), // ino
|
||||
in->caps_wanted(), // wanted
|
||||
in->caps[mds]->issued, // issued
|
||||
cap->issued, // issued
|
||||
in->snaprealm->ino,
|
||||
flockbl);
|
||||
|
||||
|
@ -2695,7 +2695,7 @@ void CInode::choose_lock_state(SimpleLock *lock, int allissued)
|
||||
if (lock->is_xlocked()) {
|
||||
// do nothing here
|
||||
} else if (lock->get_state() != LOCK_MIX) {
|
||||
if (issued & CEPH_CAP_GEXCL)
|
||||
if (issued & (CEPH_CAP_GEXCL | CEPH_CAP_GBUFFER))
|
||||
lock->set_state(LOCK_EXCL);
|
||||
else if (issued & CEPH_CAP_GWR)
|
||||
lock->set_state(LOCK_MIX);
|
||||
@ -2714,9 +2714,9 @@ void CInode::choose_lock_state(SimpleLock *lock, int allissued)
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
@ -895,7 +895,7 @@ public:
|
||||
|
||||
// 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;
|
||||
|
@ -2463,6 +2463,11 @@ void Locker::handle_client_caps(MClientCaps *m)
|
||||
<< " 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;
|
||||
}
|
||||
|
@ -5375,7 +5375,11 @@ void MDCache::choose_lock_states_and_reconnect_caps()
|
||||
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();
|
||||
@ -5521,6 +5525,7 @@ void MDCache::export_remaining_imported_caps()
|
||||
}
|
||||
|
||||
cap_imports.clear();
|
||||
cap_imports_dirty.clear();
|
||||
|
||||
if (warn_str.peek() != EOF) {
|
||||
mds->clog->warn() << "failed to reconnect caps for missing inodes:" << "\n";
|
||||
@ -5543,7 +5548,11 @@ void MDCache::try_reconnect_cap(CInode *in, Session *session)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ protected:
|
||||
map<inodeno_t,mds_rank_t> cap_export_targets; // ino -> auth mds
|
||||
|
||||
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;
|
||||
|
||||
@ -534,7 +534,6 @@ public:
|
||||
void rejoin_recovered_caps(inodeno_t ino, client_t client, cap_reconnect_t& icr,
|
||||
mds_rank_t frommds=MDS_RANK_NONE) {
|
||||
cap_imports[ino][client][frommds] = icr.capinfo;
|
||||
cap_import_paths[ino] = filepath(icr.path, (uint64_t)icr.capinfo.pathbase);
|
||||
}
|
||||
ceph_mds_cap_reconnect *get_replay_cap_reconnect(inodeno_t ino, client_t client) {
|
||||
if (cap_imports.count(ino) &&
|
||||
@ -549,6 +548,9 @@ public:
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user