diff options
Diffstat (limited to 'src/mds/Server.cc')
-rw-r--r-- | src/mds/Server.cc | 271 |
1 files changed, 142 insertions, 129 deletions
diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 7889a2cb73c..98dafc3e285 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -635,25 +635,16 @@ void Server::handle_client_reconnect(MClientReconnect *m) continue; } - filepath path(p->second.path, (uint64_t)p->second.capinfo.pathbase); if (in && !in->is_auth()) { // not mine. - dout(0) << "non-auth " << p->first << " " << path - << ", will pass off to authority" << dendl; - - // mark client caps stale. - MClientCaps *stale = new MClientCaps(CEPH_CAP_OP_EXPORT, p->first, 0, 0, 0); - //stale->head.migrate_seq = 0; // FIXME ****** - mds->send_message_client_counted(stale, session); - + dout(10) << "non-auth " << *in << ", will pass off to authority" << dendl; // add to cap export list. - mdcache->rejoin_export_caps(p->first, from, p->second); + mdcache->rejoin_export_caps(p->first, from, p->second.capinfo, + in->authority().first); } else { // don't know if the inode is mine - dout(0) << "missing " << p->first << " " << path - << " will load or export later" << dendl; + dout(10) << "missing ino " << p->first << ", will load later" << dendl; mdcache->rejoin_recovered_caps(p->first, from, p->second, -1); - mdcache->rejoin_export_caps(p->first, from, p->second); } } @@ -1797,6 +1788,24 @@ CDentry* Server::prepare_null_dentry(MDRequest *mdr, CDir *dir, const string& dn return dn; } +CDentry* Server::prepare_stray_dentry(MDRequest *mdr, CInode *in) +{ + CDentry *straydn = mdr->straydn; + if (straydn) { + string name; + in->name_stray_dentry(name); + if (straydn->get_name() == name) + return straydn; + + assert(!mdr->done_locking); + mdr->unpin(straydn); + } + + straydn = mdcache->get_or_create_stray_dentry(in); + mdr->straydn = straydn; + mdr->pin(straydn); + return straydn; +} /** prepare_new_inode * @@ -2670,6 +2679,7 @@ public: // dirty inode, dn, dir newi->inode.version--; // a bit hacky, see C_MDS_mknod_finish newi->mark_dirty(newi->inode.version+1, mdr->ls); + newi->_mark_dirty_parent(mdr->ls); mdr->apply(); @@ -2679,8 +2689,6 @@ public: mds->balancer->hit_inode(mdr->now, newi, META_POP_IWR); - mdr->ls->queue_backtrace_update(newi, newi->inode.layout.fl_pg_pool); - MClientReply *reply = new MClientReply(mdr->client_request, 0); reply->set_extra_bl(mdr->reply_extra_bl); mds->server->reply_request(mdr, reply); @@ -2803,6 +2811,7 @@ void Server::handle_client_openc(MDRequest *mdr) dn->push_projected_linkage(in); in->inode.version = dn->pre_dirty(); + in->inode.update_backtrace(); if (cmode & CEPH_FILE_MODE_WR) { in->inode.client_ranges[client].range.first = 0; in->inode.client_ranges[client].range.last = in->inode.get_layout_size_increment(); @@ -2821,7 +2830,7 @@ void Server::handle_client_openc(MDRequest *mdr) le->metablob.add_client_req(req->get_reqid(), req->get_oldest_client_tid()); journal_allocated_inos(mdr, &le->metablob); mdcache->predirty_journal_parents(mdr, &le->metablob, in, dn->get_dir(), PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); - le->metablob.add_primary_dentry(dn, true, in); + le->metablob.add_primary_dentry(dn, in, true, true); // do the open mds->locker->issue_new_caps(in, cmode, mdr->session, realm, req->is_replay()); @@ -3086,8 +3095,6 @@ public: void finish(int r) { assert(r == 0); - int64_t old_pool = in->inode.layout.fl_pg_pool; - // apply in->pop_and_dirty_projected_inode(mdr->ls); mdr->apply(); @@ -3104,16 +3111,6 @@ public: if (changed_ranges) mds->locker->share_inode_max_size(in); - - // if pool changed, queue a new backtrace and set forward pointer on old - if (old_pool != in->inode.layout.fl_pg_pool) { - mdr->ls->remove_pending_backtraces(in->ino(), in->inode.layout.fl_pg_pool); - mdr->ls->queue_backtrace_update(in, in->inode.layout.fl_pg_pool); - - // set forwarding pointer on old backtrace - mdr->ls->remove_pending_backtraces(in->ino(), old_pool); - mdr->ls->queue_backtrace_update(in, old_pool, in->inode.layout.fl_pg_pool); - } } }; @@ -3494,8 +3491,6 @@ void Server::handle_client_setlayout(MDRequest *mdr) EUpdate *le = new EUpdate(mdlog, "setlayout"); mdlog->start_entry(le); le->metablob.add_client_req(req->get_reqid(), req->get_oldest_client_tid()); - // add the old pool to the metablob to indicate the pool changed with this event - le->metablob.add_old_pool(old_pool); mdcache->predirty_journal_parents(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false); mdcache->journal_dirty_inode(mdr, &le->metablob, cur); @@ -3753,16 +3748,14 @@ void Server::handle_set_vxattr(MDRequest *mdr, CInode *cur, } pi->version = cur->pre_dirty(); + if (cur->is_file()) + pi->update_backtrace(); // log + wait mdr->ls = mdlog->get_current_segment(); EUpdate *le = new EUpdate(mdlog, "set vxattr layout"); mdlog->start_entry(le); le->metablob.add_client_req(req->get_reqid(), req->get_oldest_client_tid()); - if (cur->is_file()) { - assert(old_pool != -1); - le->metablob.add_old_pool(old_pool); - } mdcache->predirty_journal_parents(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false); mdcache->journal_dirty_inode(mdr, &le->metablob, cur); @@ -3995,6 +3988,7 @@ public: // a new version of hte inode since it's just been created) newi->inode.version--; newi->mark_dirty(newi->inode.version + 1, mdr->ls); + newi->_mark_dirty_parent(mdr->ls); // mkdir? if (newi->inode.is_dir()) { @@ -4014,15 +4008,6 @@ public: // hit pop mds->balancer->hit_inode(mdr->now, newi, META_POP_IWR); - // store the backtrace on the 'parent' xattr - if (newi->inode.is_dir()) { - // if its a dir, put it in the metadata pool - mdr->ls->queue_backtrace_update(newi, mds->mdsmap->get_metadata_pool()); - } else { - // if its a file, put it in the data pool for that file - mdr->ls->queue_backtrace_update(newi, newi->inode.layout.fl_pg_pool); - } - // reply MClientReply *reply = new MClientReply(mdr->client_request, 0); reply->set_result(0); @@ -4077,6 +4062,7 @@ void Server::handle_client_mknod(MDRequest *mdr) newi->inode.mode |= S_IFREG; newi->inode.version = dn->pre_dirty(); newi->inode.rstat.rfiles = 1; + newi->inode.update_backtrace(); // if the client created a _regular_ file via MKNOD, it's highly likely they'll // want to write to it (e.g., if they are reexporting NFS) @@ -4117,7 +4103,7 @@ void Server::handle_client_mknod(MDRequest *mdr) mdcache->predirty_journal_parents(mdr, &le->metablob, newi, dn->get_dir(), PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); - le->metablob.add_primary_dentry(dn, true, newi); + le->metablob.add_primary_dentry(dn, newi, true, true); journal_and_reply(mdr, newi, dn, le, new C_MDS_mknod_finish(mds, mdr, dn, newi, follows)); } @@ -4157,6 +4143,7 @@ void Server::handle_client_mkdir(MDRequest *mdr) newi->inode.version = dn->pre_dirty(); newi->inode.rstat.rsubdirs = 1; + newi->inode.update_backtrace(); dout(12) << " follows " << follows << dendl; if (follows >= dn->first) @@ -4175,7 +4162,7 @@ void Server::handle_client_mkdir(MDRequest *mdr) le->metablob.add_client_req(req->get_reqid(), req->get_oldest_client_tid()); journal_allocated_inos(mdr, &le->metablob); mdcache->predirty_journal_parents(mdr, &le->metablob, newi, dn->get_dir(), PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); - le->metablob.add_primary_dentry(dn, true, newi); + le->metablob.add_primary_dentry(dn, newi, true, true); le->metablob.add_new_dir(newdir); // dirty AND complete AND new // issue a cap on the directory @@ -4233,6 +4220,7 @@ void Server::handle_client_symlink(MDRequest *mdr) newi->inode.rstat.rbytes = newi->inode.size; newi->inode.rstat.rfiles = 1; newi->inode.version = dn->pre_dirty(); + newi->inode.update_backtrace(); if (follows >= dn->first) dn->first = follows + 1; @@ -4245,7 +4233,7 @@ void Server::handle_client_symlink(MDRequest *mdr) le->metablob.add_client_req(req->get_reqid(), req->get_oldest_client_tid()); journal_allocated_inos(mdr, &le->metablob); mdcache->predirty_journal_parents(mdr, &le->metablob, newi, dn->get_dir(), PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); - le->metablob.add_primary_dentry(dn, true, newi); + le->metablob.add_primary_dentry(dn, newi, true, true); journal_and_reply(mdr, newi, dn, le, new C_MDS_mknod_finish(mds, mdr, dn, newi, follows)); } @@ -4435,8 +4423,14 @@ void Server::_link_remote(MDRequest *mdr, bool inc, CDentry *dn, CInode *targeti // 1. send LinkPrepare to dest (journal nlink++ prepare) int linkauth = targeti->authority().first; if (mdr->more()->witnessed.count(linkauth) == 0) { - dout(10) << " targeti auth must prepare nlink++/--" << dendl; + if (!mds->mdsmap->is_clientreplay_or_active_or_stopping(linkauth)) { + dout(10) << " targeti auth mds." << linkauth << " is not active" << dendl; + if (mdr->more()->waiting_on_slave.empty()) + mds->wait_for_active_peer(linkauth, new C_MDS_RetryRequest(mdcache, mdr)); + return; + } + dout(10) << " targeti auth must prepare nlink++/--" << dendl; int op; if (inc) op = MMDSSlaveRequest::OP_LINKPREP; @@ -4777,7 +4771,7 @@ void Server::do_link_rollback(bufferlist &rbl, int master, MDRequest *mdr) mdlog->start_entry(le); le->commit.add_dir_context(parent); le->commit.add_dir(parent, true); - le->commit.add_primary_dentry(in->get_projected_parent_dn(), true, 0); + le->commit.add_primary_dentry(in->get_projected_parent_dn(), 0, true); mdlog->submit_entry(le, new C_MDS_LoggedLinkRollback(this, mut, mdr)); mdlog->flush(); @@ -4899,18 +4893,14 @@ void Server::handle_client_unlink(MDRequest *mdr) } // -- create stray dentry? -- - CDentry *straydn = mdr->straydn; + CDentry *straydn = NULL; if (dnl->is_primary()) { - if (!straydn) { - straydn = mdcache->get_or_create_stray_dentry(dnl->get_inode()); - mdr->pin(straydn); - mdr->straydn = straydn; - } - } else if (straydn) - straydn = NULL; - if (straydn) + straydn = prepare_stray_dentry(mdr, dnl->get_inode()); dout(10) << " straydn is " << *straydn << dendl; - + } else if (mdr->straydn) { + mdr->unpin(mdr->straydn); + mdr->straydn = NULL; + } // lock set<SimpleLock*> rdlocks, wrlocks, xlocks; @@ -4996,7 +4986,8 @@ void Server::handle_client_unlink(MDRequest *mdr) } else if (mdr->more()->waiting_on_slave.count(*p)) { dout(10) << " already waiting on witness mds." << *p << dendl; } else { - _rmdir_prepare_witness(mdr, *p, dn, straydn); + if (!_rmdir_prepare_witness(mdr, *p, dn, straydn)) + return; } } if (!mdr->more()->waiting_on_slave.empty()) @@ -5075,7 +5066,8 @@ void Server::_unlink_local(MDRequest *mdr, CDentry *dn, CDentry *straydn) if (in->snaprealm || follows + 1 > dn->first) in->project_past_snaprealm_parent(straydn->get_dir()->inode->find_snaprealm()); - le->metablob.add_primary_dentry(straydn, true, in); + pi->update_backtrace(); + le->metablob.add_primary_dentry(straydn, in, true, true); } else { // remote link. update remote inode. mdcache->predirty_journal_parents(mdr, &le->metablob, in, dn->get_dir(), PREDIRTY_DIR, -1); @@ -5158,10 +5150,16 @@ void Server::_unlink_local_finish(MDRequest *mdr, dn->get_dir()->try_remove_unlinked_dn(dn); } -void Server::_rmdir_prepare_witness(MDRequest *mdr, int who, CDentry *dn, CDentry *straydn) +bool Server::_rmdir_prepare_witness(MDRequest *mdr, int who, CDentry *dn, CDentry *straydn) { - dout(10) << "_rmdir_prepare_witness mds." << who << " for " << *mdr << dendl; + if (!mds->mdsmap->is_clientreplay_or_active_or_stopping(who)) { + dout(10) << "_rmdir_prepare_witness mds." << who << " is not active" << dendl; + if (mdr->more()->waiting_on_slave.empty()) + mds->wait_for_active_peer(who, new C_MDS_RetryRequest(mdcache, mdr)); + return false; + } + dout(10) << "_rmdir_prepare_witness mds." << who << dendl; MMDSSlaveRequest *req = new MMDSSlaveRequest(mdr->reqid, mdr->attempt, MMDSSlaveRequest::OP_RMDIRPREP); dn->make_path(req->srcdnpath); @@ -5174,6 +5172,7 @@ void Server::_rmdir_prepare_witness(MDRequest *mdr, int who, CDentry *dn, CDentr assert(mdr->more()->waiting_on_slave.count(who) == 0); mdr->more()->waiting_on_slave.insert(who); + return true; } struct C_MDS_SlaveRmdirPrep : public Context { @@ -5228,7 +5227,7 @@ void Server::handle_slave_rmdir_prep(MDRequest *mdr) le->rollback = mdr->more()->rollback_bl; le->commit.add_dir_context(straydn->get_dir()); - le->commit.add_primary_dentry(straydn, true, in); + le->commit.add_primary_dentry(straydn, in, true); // slave: no need to journal original dentry dout(10) << " noting renamed (unlinked) dir ino " << in->ino() << " in metablob" << dendl; @@ -5362,7 +5361,7 @@ void Server::do_rmdir_rollback(bufferlist &rbl, int master, MDRequest *mdr) mdlog->start_entry(le); le->commit.add_dir_context(dn->get_dir()); - le->commit.add_primary_dentry(dn, true, in); + le->commit.add_primary_dentry(dn, in, true); // slave: no need to journal straydn dout(10) << " noting renamed (unlinked) dir ino " << in->ino() << " in metablob" << dendl; @@ -5654,17 +5653,14 @@ void Server::handle_client_rename(MDRequest *mdr) dout(10) << " this is a link merge" << dendl; // -- create stray dentry? -- - CDentry *straydn = mdr->straydn; + CDentry *straydn = NULL; if (destdnl->is_primary() && !linkmerge) { - if (!straydn) { - straydn = mdcache->get_or_create_stray_dentry(destdnl->get_inode()); - mdr->pin(straydn); - mdr->straydn = straydn; - } - } else if (straydn) - straydn = NULL; - if (straydn) + straydn = prepare_stray_dentry(mdr, destdnl->get_inode()); dout(10) << " straydn is " << *straydn << dendl; + } else if (mdr->straydn) { + mdr->unpin(mdr->straydn); + mdr->straydn = NULL; + } // -- prepare witness list -- /* @@ -5873,7 +5869,8 @@ void Server::handle_client_rename(MDRequest *mdr) } else if (mdr->more()->waiting_on_slave.count(*p)) { dout(10) << " already waiting on witness mds." << *p << dendl; } else { - _rename_prepare_witness(mdr, *p, witnesses, srcdn, destdn, straydn); + if (!_rename_prepare_witness(mdr, *p, witnesses, srcdn, destdn, straydn)) + return; } } if (!mdr->more()->waiting_on_slave.empty()) @@ -5951,20 +5948,6 @@ void Server::_rename_finish(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDe // did we import srci? if so, explicitly ack that import that, before we unlock and reply. assert(g_conf->mds_kill_rename_at != 7); - // backtrace - if (destdnl->inode->is_dir()) { - // replace previous backtrace on this inode with myself - mdr->ls->remove_pending_backtraces(destdnl->inode->ino(), mds->mdsmap->get_metadata_pool()); - // queue an updated backtrace - mdr->ls->queue_backtrace_update(destdnl->inode, mds->mdsmap->get_metadata_pool()); - - } else { - // remove all pending backtraces going to the same pool - mdr->ls->remove_pending_backtraces(destdnl->inode->ino(), destdnl->inode->inode.layout.fl_pg_pool); - // queue an updated backtrace - mdr->ls->queue_backtrace_update(destdnl->inode, destdnl->inode->inode.layout.fl_pg_pool); - } - assert(g_conf->mds_kill_rename_at != 8); // reply MClientReply *reply = new MClientReply(mdr->client_request, 0); @@ -5979,9 +5962,16 @@ void Server::_rename_finish(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDe // helpers -void Server::_rename_prepare_witness(MDRequest *mdr, int who, set<int> &witnesse, +bool Server::_rename_prepare_witness(MDRequest *mdr, int who, set<int> &witnesse, CDentry *srcdn, CDentry *destdn, CDentry *straydn) { + if (!mds->mdsmap->is_clientreplay_or_active_or_stopping(who)) { + dout(10) << "_rename_prepare_witness mds." << who << " is not active" << dendl; + if (mdr->more()->waiting_on_slave.empty()) + mds->wait_for_active_peer(who, new C_MDS_RetryRequest(mdcache, mdr)); + return false; + } + dout(10) << "_rename_prepare_witness mds." << who << dendl; MMDSSlaveRequest *req = new MMDSSlaveRequest(mdr->reqid, mdr->attempt, MMDSSlaveRequest::OP_RENAMEPREP); @@ -5999,6 +5989,7 @@ void Server::_rename_prepare_witness(MDRequest *mdr, int who, set<int> &witnesse assert(mdr->more()->waiting_on_slave.count(who) == 0); mdr->more()->waiting_on_slave.insert(who); + return true; } version_t Server::_rename_prepare_import(MDRequest *mdr, CDentry *srcdn, bufferlist *client_map_bl) @@ -6133,6 +6124,7 @@ void Server::_rename_prepare(MDRequest *mdr, if (destdn->is_auth()) { tpi = oldin->project_inode(); //project_snaprealm tpi->version = straydn->pre_dirty(tpi->version); + tpi->update_backtrace(); } straydn->push_projected_linkage(oldin); } else if (destdnl->is_remote()) { @@ -6187,6 +6179,7 @@ void Server::_rename_prepare(MDRequest *mdr, pi = srci->project_inode(); // project snaprealm if srcdnl->is_primary // & srcdnl->snaprealm pi->version = mdr->more()->pvmap[destdn] = destdn->pre_dirty(oldpv); + pi->update_backtrace(); } destdn->push_projected_linkage(srci); } @@ -6198,7 +6191,6 @@ void Server::_rename_prepare(MDRequest *mdr, if (!silent) { if (pi) { - pi->last_renamed_version = pi->version; pi->ctime = mdr->now; if (linkmerge) pi->nlink--; @@ -6252,11 +6244,11 @@ void Server::_rename_prepare(MDRequest *mdr, if (oldin->snaprealm || src_realm->get_newest_seq() + 1 > srcdn->first) oldin->project_past_snaprealm_parent(straydn->get_dir()->inode->find_snaprealm()); straydn->first = MAX(oldin->first, next_dest_snap); - metablob->add_primary_dentry(straydn, true, oldin); + metablob->add_primary_dentry(straydn, oldin, true, true); } else if (force_journal_stray) { dout(10) << " forced journaling straydn " << *straydn << dendl; metablob->add_dir_context(straydn->get_dir()); - metablob->add_primary_dentry(straydn, true, oldin); + metablob->add_primary_dentry(straydn, oldin, true); } } else if (destdnl->is_remote()) { if (oldin->is_auth()) { @@ -6264,7 +6256,7 @@ void Server::_rename_prepare(MDRequest *mdr, metablob->add_dir_context(oldin->get_projected_parent_dir()); mdcache->journal_cow_dentry(mdr, metablob, oldin->get_projected_parent_dn(), CEPH_NOSNAP, 0, destdnl); - metablob->add_primary_dentry(oldin->get_projected_parent_dn(), true, oldin); + metablob->add_primary_dentry(oldin->get_projected_parent_dn(), oldin, true); } } } @@ -6282,7 +6274,7 @@ void Server::_rename_prepare(MDRequest *mdr, if (srci->get_projected_parent_dn()->is_auth()) { // it's remote metablob->add_dir_context(srci->get_projected_parent_dir()); mdcache->journal_cow_dentry(mdr, metablob, srci->get_projected_parent_dn(), CEPH_NOSNAP, 0, srcdnl); - metablob->add_primary_dentry(srci->get_projected_parent_dn(), true, srci); + metablob->add_primary_dentry(srci->get_projected_parent_dn(), srci, true); } } else { if (destdn->is_auth() && !destdnl->is_null()) @@ -6291,7 +6283,7 @@ void Server::_rename_prepare(MDRequest *mdr, destdn->first = MAX(destdn->first, next_dest_snap); if (destdn->is_auth()) - metablob->add_primary_dentry(destdn, true, destdnl->get_inode()); + metablob->add_primary_dentry(destdn, destdnl->get_inode(), true, true); } } else if (srcdnl->is_primary()) { // project snap parent update? @@ -6305,11 +6297,21 @@ void Server::_rename_prepare(MDRequest *mdr, destdn->first = MAX(destdn->first, next_dest_snap); if (destdn->is_auth()) - metablob->add_primary_dentry(destdn, true, srci); + metablob->add_primary_dentry(destdn, srci, true, true); else if (force_journal_dest) { dout(10) << " forced journaling destdn " << *destdn << dendl; metablob->add_dir_context(destdn->get_dir()); - metablob->add_primary_dentry(destdn, true, srci); + metablob->add_primary_dentry(destdn, srci, true); + if (srcdn->is_auth() && srci->is_dir()) { + // journal new subtrees root dirfrags + list<CDir*> ls; + srci->get_dirfrags(ls); + for (list<CDir*>::iterator p = ls.begin(); p != ls.end(); ++p) { + CDir *dir = *p; + if (dir->is_auth()) + metablob->add_dir(dir, true); + } + } } } @@ -6321,7 +6323,7 @@ void Server::_rename_prepare(MDRequest *mdr, // both primary and NULL dentries. Because during journal replay, null dentry is // processed after primary dentry. if (srcdnl->is_primary() && !srci->is_dir() && !destdn->is_auth()) - metablob->add_primary_dentry(srcdn, true, srci); + metablob->add_primary_dentry(srcdn, srci, true); metablob->add_null_dentry(srcdn, true); } else dout(10) << " NOT journaling srcdn " << *srcdn << dendl; @@ -6341,8 +6343,6 @@ void Server::_rename_prepare(MDRequest *mdr, if (srci->is_dir()) mdcache->project_subtree_rename(srci, srcdn->get_dir(), destdn->get_dir()); - // always update the backtrace - metablob->update_backtrace(); } @@ -6789,23 +6789,10 @@ void Server::_commit_slave_rename(MDRequest *mdr, int r, mdlog->flush(); } else { if (srcdn->is_auth() && destdnl->is_primary()) { - dout(10) << " reversing inode export of " << *destdnl->get_inode() << dendl; destdnl->get_inode()->abort_export(); - - // unfreeze - assert(destdnl->get_inode()->is_frozen_inode()); - destdnl->get_inode()->unfreeze_inode(finished); } - // singleauth - if (mdr->more()->is_ambiguous_auth) { - mdr->more()->rename_inode->clear_ambiguous_auth(finished); - mdr->more()->is_ambiguous_auth = false; - } - - mds->queue_waiters(finished); - // abort // rollback_bl may be empty if we froze the inode but had to provide an expanded // witness list from the master, and they failed before we tried prep again. @@ -6813,11 +6800,20 @@ void Server::_commit_slave_rename(MDRequest *mdr, int r, if (mdcache->is_ambiguous_slave_update(mdr->reqid, mdr->slave_to_mds)) { mdcache->remove_ambiguous_slave_update(mdr->reqid, mdr->slave_to_mds); // rollback but preserve the slave request - do_rename_rollback(mdr->more()->rollback_bl, mdr->slave_to_mds, NULL); + do_rename_rollback(mdr->more()->rollback_bl, mdr->slave_to_mds, mdr, false); } else - do_rename_rollback(mdr->more()->rollback_bl, mdr->slave_to_mds, mdr); + do_rename_rollback(mdr->more()->rollback_bl, mdr->slave_to_mds, mdr, true); } else { dout(10) << " rollback_bl empty, not rollback back rename (master failed after getting extra witnesses?)" << dendl; + // singleauth + if (mdr->more()->is_ambiguous_auth) { + if (srcdn->is_auth()) + mdr->more()->rename_inode->unfreeze_inode(finished); + + mdr->more()->rename_inode->clear_ambiguous_auth(finished); + mdr->more()->is_ambiguous_auth = false; + } + mds->queue_waiters(finished); mds->mdcache->request_finish(mdr); } } @@ -6862,15 +6858,20 @@ struct C_MDS_LoggedRenameRollback : public Context { version_t srcdnpv; CDentry *destdn; CDentry *straydn; + bool finish_mdr; C_MDS_LoggedRenameRollback(Server *s, Mutation *m, MDRequest *r, - CDentry *sd, version_t pv, CDentry *dd, CDentry *st) : - server(s), mut(m), mdr(r), srcdn(sd), srcdnpv(pv), destdn(dd), straydn(st) {} + CDentry *sd, version_t pv, CDentry *dd, + CDentry *st, bool f) : + server(s), mut(m), mdr(r), srcdn(sd), srcdnpv(pv), destdn(dd), + straydn(st), finish_mdr(f) {} void finish(int r) { - server->_rename_rollback_finish(mut, mdr, srcdn, srcdnpv, destdn, straydn); + server->_rename_rollback_finish(mut, mdr, srcdn, srcdnpv, + destdn, straydn, finish_mdr); } }; -void Server::do_rename_rollback(bufferlist &rbl, int master, MDRequest *mdr) +void Server::do_rename_rollback(bufferlist &rbl, int master, MDRequest *mdr, + bool finish_mdr) { rename_rollback rollback; bufferlist::iterator p = rbl.begin(); @@ -7000,7 +7001,7 @@ void Server::do_rename_rollback(bufferlist &rbl, int master, MDRequest *mdr) } if (straydn) - destdn->push_projected_linkage(); + straydn->push_projected_linkage(); if (target) { inode_t *ti = NULL; @@ -7032,7 +7033,7 @@ void Server::do_rename_rollback(bufferlist &rbl, int master, MDRequest *mdr) if (srcdn && (srcdn->authority().first == whoami || force_journal_src)) { le->commit.add_dir_context(srcdir); if (rollback.orig_src.ino) - le->commit.add_primary_dentry(srcdn, true); + le->commit.add_primary_dentry(srcdn, 0, true); else le->commit.add_remote_dentry(srcdn, true); } @@ -7040,7 +7041,7 @@ void Server::do_rename_rollback(bufferlist &rbl, int master, MDRequest *mdr) if (force_journal_dest) { assert(rollback.orig_dest.ino); le->commit.add_dir_context(destdir); - le->commit.add_primary_dentry(destdn, true); + le->commit.add_primary_dentry(destdn, 0, true); } // slave: no need to journal straydn @@ -7048,7 +7049,7 @@ void Server::do_rename_rollback(bufferlist &rbl, int master, MDRequest *mdr) if (target && target->authority().first == whoami) { assert(rollback.orig_dest.remote_ino); le->commit.add_dir_context(target->get_projected_parent_dir()); - le->commit.add_primary_dentry(target->get_projected_parent_dn(), true, target); + le->commit.add_primary_dentry(target->get_projected_parent_dn(), target, true); } if (force_journal_dest) { @@ -7069,15 +7070,16 @@ void Server::do_rename_rollback(bufferlist &rbl, int master, MDRequest *mdr) mdcache->project_subtree_rename(in, destdir, srcdir); } - mdlog->submit_entry(le, new C_MDS_LoggedRenameRollback(this, mut, mdr, - srcdn, srcdnpv, destdn, straydn)); + mdlog->submit_entry(le, new C_MDS_LoggedRenameRollback(this, mut, mdr, srcdn, srcdnpv, + destdn, straydn, finish_mdr)); mdlog->flush(); } void Server::_rename_rollback_finish(Mutation *mut, MDRequest *mdr, CDentry *srcdn, - version_t srcdnpv, CDentry *destdn, CDentry *straydn) + version_t srcdnpv, CDentry *destdn, + CDentry *straydn, bool finish_mdr) { - dout(10) << "_rename_rollback_finish" << mut->reqid << dendl; + dout(10) << "_rename_rollback_finish " << mut->reqid << dendl; if (straydn) { straydn->get_dir()->unlink_inode(straydn); @@ -7123,8 +7125,19 @@ void Server::_rename_rollback_finish(Mutation *mut, MDRequest *mdr, CDentry *src mdcache->try_trim_non_auth_subtree(root); } - if (mdr) - mds->mdcache->request_finish(mdr); + if (mdr) { + list<Context*> finished; + if (mdr->more()->is_ambiguous_auth) { + if (srcdn->is_auth()) + mdr->more()->rename_inode->unfreeze_inode(finished); + + mdr->more()->rename_inode->clear_ambiguous_auth(finished); + mdr->more()->is_ambiguous_auth = false; + } + mds->queue_waiters(finished); + if (finish_mdr) + mds->mdcache->request_finish(mdr); + } mds->mdcache->finish_rollback(mut->reqid); |