From 0ec25575f4ed4c5d248d360061af7f76e30febb8 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Tue, 6 Dec 2016 22:52:32 +0800 Subject: [PATCH] mds: properly wake up scatter_nudge waiters after clearing scatter dirty LogSegment::try_to_expire() calls Locker::scatter_nudge() for dirty scatter locks. If lock's parent is non-auth, Locker::scatter_nudge() waits on the stable bit of corresponding lock. There are some cases that scatter locks get marked clean without involving lock state transition. We need to wake up scatter_nudge waiters in these cases. Also remove the code that clear dirty scatter locks after inode gets imported. I can't see why we should do that. Signed-off-by: Yan, Zheng --- src/mds/Locker.cc | 3 +++ src/mds/MDCache.cc | 4 +--- src/mds/Migrator.cc | 38 ++++++++++++++++++++------------------ src/mds/Server.cc | 4 +--- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index e4fd8ef5a8e..306d9043384 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -5055,6 +5055,9 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m) case LOCK_AC_LOCKFLUSHED: (static_cast(lock))->finish_flush(); (static_cast(lock))->clear_flushed(); + // wake up scatter_nudge waiters + if (lock->is_stable()) + lock->finish_waiters(SimpleLock::WAIT_STABLE); break; case LOCK_AC_MIX: diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 5b24edbdcb1..797dff718ff 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -298,9 +298,7 @@ void MDCache::remove_inode(CInode *o) if (o->is_dirty_parent()) o->clear_dirty_parent(); - o->filelock.remove_dirty(); - o->nestlock.remove_dirty(); - o->dirfragtreelock.remove_dirty(); + o->clear_scatter_dirty(); o->item_open_file.remove_myself(); diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc index 8bd3172f4b0..64168a15640 100644 --- a/src/mds/Migrator.cc +++ b/src/mds/Migrator.cc @@ -1831,11 +1831,6 @@ void Migrator::export_finish(CDir *dir) C_ContextsBase *fin = new C_ContextsBase(g_ceph_context); finish_export_dir(dir, ceph_clock_now(g_ceph_context), it->second.peer, it->second.peer_imported, fin->contexts, &num_dentries); - dir->add_waiter(CDir::WAIT_UNFREEZE, fin); - - // unfreeze - dout(7) << "export_finish unfreezing" << dendl; - dir->unfreeze_tree(); // unpin bounds set bounds; @@ -1855,8 +1850,17 @@ void Migrator::export_finish(CDir *dir) // no more auth subtree? clear scatter dirty if (!dir->get_inode()->is_auth() && - !dir->get_inode()->has_subtree_root_dirfrag(mds->get_nodeid())) + !dir->get_inode()->has_subtree_root_dirfrag(mds->get_nodeid())) { dir->get_inode()->clear_scatter_dirty(); + // wake up scatter_nudge waiters + dir->get_inode()->take_waiting(CInode::WAIT_ANY_MASK, fin->contexts); + } + + dir->add_waiter(CDir::WAIT_UNFREEZE, fin); + + // unfreeze + dout(7) << "export_finish unfreezing" << dendl; + dir->unfreeze_tree(); // discard delayed expires cache->discard_delayed_expire(dir); @@ -2389,9 +2393,13 @@ void Migrator::import_reverse(CDir *dir) cache->adjust_subtree_auth(dir, stat.peer); + C_ContextsBase *fin = new C_ContextsBase(g_ceph_context); if (!dir->get_inode()->is_auth() && - !dir->get_inode()->has_subtree_root_dirfrag(mds->get_nodeid())) + !dir->get_inode()->has_subtree_root_dirfrag(mds->get_nodeid())) { dir->get_inode()->clear_scatter_dirty(); + // wake up scatter_nudge waiters + dir->get_inode()->take_waiting(CInode::WAIT_ANY_MASK, fin->contexts); + } int num_dentries = 0; // adjust auth bits. @@ -2427,8 +2435,10 @@ void Migrator::import_reverse(CDir *dir) if (in->is_dirty()) in->mark_clean(); in->clear_dirty_rstat(); - if (!in->has_subtree_root_dirfrag(mds->get_nodeid())) + if (!in->has_subtree_root_dirfrag(mds->get_nodeid())) { in->clear_scatter_dirty(); + in->take_waiting(CInode::WAIT_ANY_MASK, fin->contexts); + } in->clear_dirty_parent(); @@ -2452,6 +2462,8 @@ void Migrator::import_reverse(CDir *dir) } } + dir->add_waiter(CDir::WAIT_UNFREEZE, fin); + if (stat.state == IMPORT_ACKING) { // remove imported caps for (map >::iterator p = stat.peer_exports.begin(); @@ -2538,8 +2550,6 @@ void Migrator::import_reverse_unfreeze(CDir *dir) assert(dir); dout(7) << "import_reverse_unfreeze " << *dir << dendl; dir->unfreeze_tree(); - list ls; - mds->queue_waiters(ls); cache->discard_delayed_expire(dir); import_reverse_final(dir); } @@ -2678,14 +2688,6 @@ void Migrator::import_finish(CDir *dir, bool notify, bool last) return; } - // clear updated scatterlocks - /* - for (list::iterator p = import_updated_scatterlocks[dir].begin(); - p != import_updated_scatterlocks[dir].end(); - ++p) - (*p)->clear_updated(); - */ - // remove pins set bounds; cache->get_subtree_bounds(dir, bounds); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 40ae3b66dcf..bdfc58fd99b 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -6628,13 +6628,11 @@ version_t Server::_rename_prepare_import(MDRequestRef& mdr, CDentry *srcdn, buff mds->mdsmap->get_up_features()); prepare_force_open_sessions(mdr->more()->imported_client_map, mdr->more()->sseq_map); - list updated_scatterlocks; // we clear_updated explicitly below + list updated_scatterlocks; mdcache->migrator->decode_import_inode(srcdn, blp, srcdn->authority().first, mdr->ls, 0, mdr->more()->cap_imports, updated_scatterlocks); - srcdnl->get_inode()->filelock.remove_dirty(); - srcdnl->get_inode()->nestlock.remove_dirty(); // hack: force back to !auth and clean, temporarily srcdnl->get_inode()->state_clear(CInode::STATE_AUTH); -- 2.47.3