}
}
+class C_RetryEvalRemote : public StrayManagerContext {
+ CDentry *dn;
+ public:
+ C_RetryEvalRemote(StrayManager *sm_, CDentry *dn_) :
+ StrayManagerContext(sm_), dn(dn_) {
+ dn->get(CDentry::PIN_PTRWAITER);
+ }
+ void finish(int r) override {
+ if (dn->get_projected_linkage()->is_remote())
+ sm->eval_remote(dn);
+ dn->put(CDentry::PIN_PTRWAITER);
+ }
+};
+
void StrayManager::_eval_stray_remote(CDentry *stray_dn, CDentry *remote_dn)
{
dout(20) << __func__ << " " << *stray_dn << dendl;
for (compact_set<CDentry*>::iterator p = stray_in->remote_parents.begin();
p != stray_in->remote_parents.end();
++p)
- if ((*p)->last == CEPH_NOSNAP) {
- remote_dn = *p;
- break;
+ if ((*p)->last == CEPH_NOSNAP && !(*p)->is_projected()) {
+ if ((*p)->is_auth()) {
+ remote_dn = *p;
+ if (remote_dn->dir->can_auth_pin())
+ break;
+ } else if (!remote_dn) {
+ remote_dn = *p;
+ }
}
}
if (!remote_dn) {
assert(remote_dn->last == CEPH_NOSNAP);
// NOTE: we repeat this check in _rename(), since our submission path is racey.
if (!remote_dn->is_projected()) {
- if (remote_dn->is_auth() && remote_dn->dir->can_auth_pin()) {
- reintegrate_stray(stray_dn, remote_dn);
+ if (remote_dn->is_auth()) {
+ if (remote_dn->dir->can_auth_pin()) {
+ reintegrate_stray(stray_dn, remote_dn);
+ } else {
+ remote_dn->dir->add_waiter(CDir::WAIT_UNFREEZE, new C_RetryEvalRemote(this, remote_dn));
+ dout(20) << __func__ << ": not reintegrating (can't authpin remote parent)" << dendl;
+ }
+
} else if (!remote_dn->is_auth() && stray_dn->is_auth()) {
migrate_stray(stray_dn, remote_dn->authority().first);
} else {