From: Yan, Zheng Date: Wed, 13 Mar 2013 08:54:58 +0000 (+0800) Subject: mds: send resolve acks after master updates are safely logged X-Git-Tag: v0.62~120^2~24 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3ab86637b34897fa22dcf87eed6ac8d77afdfbc6;p=ceph.git mds: send resolve acks after master updates are safely logged Signed-off-by: Yan, Zheng Reviewed-by: Greg Farnum --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 9156e5bb0e0d..5e7a0ee598db 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -2181,6 +2181,17 @@ void MDCache::committed_master_slave(metareqid_t r, int from) log_master_commit(r); } +void MDCache::logged_master_update(metareqid_t reqid) +{ + dout(10) << "logged_master_update " << reqid << dendl; + assert(uncommitted_masters.count(reqid)); + uncommitted_masters[reqid].safe = true; + if (pending_masters.count(reqid)) { + pending_masters.erase(reqid); + if (pending_masters.empty()) + process_delayed_resolve(); + } +} /* * The mds could crash after receiving all slaves' commit acknowledgement, @@ -2768,8 +2779,23 @@ void MDCache::handle_resolve(MMDSResolve *m) return; } + discard_delayed_resolve(from); + // ambiguous slave requests? if (!m->slave_requests.empty()) { + for (vector::iterator p = m->slave_requests.begin(); + p != m->slave_requests.end(); + ++p) { + if (uncommitted_masters.count(*p) && !uncommitted_masters[*p].safe) + pending_masters.insert(*p); + } + + if (!pending_masters.empty()) { + dout(10) << " still have pending updates, delay processing slave resolve" << dendl; + delayed_resolve[from] = m; + return; + } + MMDSResolveAck *ack = new MMDSResolveAck; for (vector::iterator p = m->slave_requests.begin(); p != m->slave_requests.end(); @@ -2792,7 +2818,6 @@ void MDCache::handle_resolve(MMDSResolve *m) if (!resolve_ack_gather.empty() || !need_resolve_rollback.empty()) { dout(10) << "delay processing subtree resolve" << dendl; - discard_delayed_resolve(from); delayed_resolve[from] = m; return; } @@ -2887,10 +2912,10 @@ void MDCache::handle_resolve(MMDSResolve *m) void MDCache::process_delayed_resolve() { dout(10) << "process_delayed_resolve" << dendl; - for (map::iterator p = delayed_resolve.begin(); - p != delayed_resolve.end(); ++p) + map tmp; + tmp.swap(delayed_resolve); + for (map::iterator p = tmp.begin(); p != tmp.end(); ++p) handle_resolve(p->second); - delayed_resolve.clear(); } void MDCache::discard_delayed_resolve(int who) diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index 99420429f230..89144de69b78 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -281,14 +281,16 @@ public: snapid_t follows=CEPH_NOSNAP); // slaves - void add_uncommitted_master(metareqid_t reqid, LogSegment *ls, set &slaves) { + void add_uncommitted_master(metareqid_t reqid, LogSegment *ls, set &slaves, bool safe=false) { uncommitted_masters[reqid].ls = ls; uncommitted_masters[reqid].slaves = slaves; + uncommitted_masters[reqid].safe = safe; } void wait_for_uncommitted_master(metareqid_t reqid, Context *c) { uncommitted_masters[reqid].waiters.push_back(c); } void log_master_commit(metareqid_t reqid); + void logged_master_update(metareqid_t reqid); void _logged_master_commit(metareqid_t reqid, LogSegment *ls, list &waiters); void committed_master_slave(metareqid_t r, int from); void finish_committed_masters(); @@ -320,9 +322,12 @@ protected: set slaves; LogSegment *ls; list waiters; + bool safe; }; map uncommitted_masters; // master: req -> slave set + set pending_masters; + //map ambiguous_slave_updates; // for log trimming. //map waiting_for_slave_update_commit; friend class ESlaveUpdate; diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 9e0ad7aff9e3..159dc23eced0 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -4501,6 +4501,9 @@ void Server::_link_remote_finish(MDRequest *mdr, bool inc, assert(g_conf->mds_kill_link_at != 3); + if (!mdr->more()->witnessed.empty()) + mdcache->logged_master_update(mdr->reqid); + if (inc) { // link the new dentry dn->pop_projected_linkage(); @@ -5111,6 +5114,9 @@ void Server::_unlink_local_finish(MDRequest *mdr, { dout(10) << "_unlink_local_finish " << *dn << dendl; + if (!mdr->more()->witnessed.empty()) + mdcache->logged_master_update(mdr->reqid); + // unlink main dentry dn->get_dir()->unlink_inode(dn); dn->pop_projected_linkage(); @@ -5919,6 +5925,9 @@ void Server::_rename_finish(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDe { dout(10) << "_rename_finish " << *mdr << dendl; + if (!mdr->more()->witnessed.empty()) + mdcache->logged_master_update(mdr->reqid); + // apply _rename_apply(mdr, srcdn, destdn, straydn); diff --git a/src/mds/journal.cc b/src/mds/journal.cc index 75a733b10a72..b8139e3a05b9 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -1885,7 +1885,7 @@ void EUpdate::replay(MDS *mds) dout(10) << "EUpdate.replay " << reqid << " had slaves, expecting a matching ECommitted" << dendl; _segment->uncommitted_masters.insert(reqid); set slaves; - mds->mdcache->add_uncommitted_master(reqid, _segment, slaves); + mds->mdcache->add_uncommitted_master(reqid, _segment, slaves, true); } if (client_map.length()) {