From 512a1da9af5bbd87a0bb32581f6aaf78f37345d1 Mon Sep 17 00:00:00 2001 From: Greg Farnum Date: Fri, 15 Oct 2010 17:05:24 -0700 Subject: [PATCH] mds: Check for LOCK_MIX_STALE along with LOCK_MIX LOCK_MIX_STALE precludes writing to the protected data, but in general cases it's an acceptable state whenever LOCK_MIX is. Add checks for LOCK_MIX_STALE to asserts and if statements that match those for LOCK_MIX. --- src/mds/CInode.cc | 6 ++++-- src/mds/Locker.cc | 27 ++++++++++++++++++--------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 19131b5e55d80..c360efb099f8e 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -2391,7 +2391,8 @@ void CInode::decode_import(bufferlist::iterator& p, // it is frozen (and in a SYNC or LOCK state). FIXME. if (dir->is_auth() || - filelock.get_state() == LOCK_MIX) { + filelock.get_state() == LOCK_MIX || + filelock.get_state() == LOCK_MIX_STALE) { dout(10) << " skipped fragstat info for " << *dir << dendl; frag_info_t f; ::decode(f, q); @@ -2402,7 +2403,8 @@ void CInode::decode_import(bufferlist::iterator& p, dout(10) << " took fragstat info for " << *dir << dendl; } if (dir->is_auth() || - nestlock.get_state() == LOCK_MIX) { + nestlock.get_state() == LOCK_MIX || + nestlock.get_state() == LOCK_MIX_STALE) { dout(10) << " skipped rstat info for " << *dir << dendl; nest_info_t n; ::decode(n, q); diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 037aece238253..91429351ac941 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -2955,6 +2955,7 @@ bool Locker::simple_sync(SimpleLock *lock, bool *need_issue) if (old_state != LOCK_TSYN) { switch (lock->get_state()) { + case LOCK_MIX_STALE: case LOCK_MIX: lock->set_state(LOCK_MIX_SYNC); break; case LOCK_SCAN: case LOCK_LOCK: lock->set_state(LOCK_LOCK_SYNC); break; @@ -2969,7 +2970,7 @@ bool Locker::simple_sync(SimpleLock *lock, bool *need_issue) gather++; if (lock->get_parent()->is_replicated() && - old_state == LOCK_MIX) { + ((old_state == LOCK_MIX) || (old_state == LOCK_MIX_STALE))) { send_lock_message(lock, LOCK_AC_SYNC); lock->init_gather(); gather++; @@ -3081,6 +3082,7 @@ void Locker::simple_lock(SimpleLock *lock, bool *need_issue) case LOCK_SCAN: lock->set_state(LOCK_SCAN_LOCK); break; case LOCK_SYNC: lock->set_state(LOCK_SYNC_LOCK); break; case LOCK_EXCL: lock->set_state(LOCK_EXCL_LOCK); break; + case LOCK_MIX_STALE: case LOCK_MIX: lock->set_state(LOCK_MIX_LOCK); break; case LOCK_TSYN: lock->set_state(LOCK_TSYN_LOCK); break; default: assert(0); @@ -3290,7 +3292,8 @@ void Locker::scatter_eval(ScatterLock *lock, bool *need_issue) if (lock->get_type() == CEPH_LOCK_INEST) { // in general, we want to keep INEST scattered at all times. if (!lock->is_rdlocked() && - lock->get_state() != LOCK_MIX) + lock->get_state() != LOCK_MIX && + lock->get_state() != LOCK_MIX_STALE) file_mixed(lock, need_issue); return; } @@ -3385,7 +3388,8 @@ void Locker::scatter_nudge(ScatterLock *lock, Context *c, bool forcelockchange) dout(10) << "scatter_nudge auth, scatter/unscattering " << *lock << " on " << *p << dendl; switch (lock->get_type()) { case CEPH_LOCK_IFILE: - if (p->is_replicated() && lock->get_state() != LOCK_MIX) + if (p->is_replicated() && lock->get_state() != LOCK_MIX && + lock->get_state() != LOCK_MIX_STALE) file_mixed((ScatterLock*)lock); else if (lock->get_state() != LOCK_LOCK) simple_lock((ScatterLock*)lock); @@ -3395,7 +3399,8 @@ void Locker::scatter_nudge(ScatterLock *lock, Context *c, bool forcelockchange) case CEPH_LOCK_IDFT: case CEPH_LOCK_INEST: - if (p->is_replicated() && lock->get_state() != LOCK_MIX) + if (p->is_replicated() && lock->get_state() != LOCK_MIX && + lock->get_state() != LOCK_MIX_STALE) file_mixed(lock); else if (lock->get_state() != LOCK_LOCK) simple_lock(lock); @@ -3477,6 +3482,7 @@ void Locker::scatter_tempsync(ScatterLock *lock, bool *need_issue) switch (lock->get_state()) { case LOCK_SYNC: assert(0); // this shouldn't happen case LOCK_LOCK: lock->set_state(LOCK_LOCK_TSYN); break; + case LOCK_MIX_STALE: case LOCK_MIX: lock->set_state(LOCK_MIX_TSYN); break; default: assert(0); } @@ -3645,7 +3651,7 @@ void Locker::file_eval(ScatterLock *lock, bool *need_issue) } // * -> mixed? - else if (lock->get_state() != LOCK_MIX && + else if (lock->get_state() != LOCK_MIX && lock->get_state() != LOCK_MIX_STALE && //!lock->is_rdlocked() && //!lock->is_waiter_for(SimpleLock::WAIT_WR) && (lock->get_scatter_wanted() || @@ -3660,7 +3666,7 @@ void Locker::file_eval(ScatterLock *lock, bool *need_issue) !lock->is_wrlocked() && // drain wrlocks first! !in->filelock.is_waiter_for(SimpleLock::WAIT_WR) && !(wanted & (CEPH_CAP_GWR|CEPH_CAP_GBUFFER)) && - !(lock->get_state() == LOCK_MIX && + !((in->get_state() == LOCK_MIX || in->get_state() == LOCK_MIX_STALE) && in->is_dir() && in->has_subtree_root_dirfrag()) // if we are a delegation point, stay where we are //((wanted & CEPH_CAP_RD) || //in->is_replicated() || @@ -3769,6 +3775,7 @@ void Locker::file_excl(ScatterLock *lock, bool *need_issue) switch (lock->get_state()) { case LOCK_SYNC: lock->set_state(LOCK_SYNC_EXCL); break; + case LOCK_MIX_STALE: case LOCK_MIX: lock->set_state(LOCK_MIX_EXCL); break; case LOCK_SCAN: case LOCK_LOCK: lock->set_state(LOCK_LOCK_EXCL); break; @@ -3870,10 +3877,10 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m) // -- replica -- case LOCK_AC_SYNC: assert(lock->get_state() == LOCK_LOCK || - lock->get_state() == LOCK_MIX || + lock->get_state() == LOCK_MIX || lock->get_state() == LOCK_MIX_STALE || lock->get_state() == LOCK_MIX_SYNC2); - if (lock->get_state() == LOCK_MIX) { + if (lock->get_state() == LOCK_MIX || lock->get_state() == LOCK_MIX_STALE) { lock->set_state(LOCK_MIX_SYNC); eval_gather(lock, true); break; @@ -3893,6 +3900,7 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m) case LOCK_AC_LOCK: switch (lock->get_state()) { case LOCK_SYNC: lock->set_state(LOCK_SYNC_LOCK); break; + case LOCK_MIX_STALE: case LOCK_MIX: lock->set_state(LOCK_MIX_LOCK); break; default: assert(0); } @@ -3994,7 +4002,8 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m) */ dout(7) << "handle_file_lock got scatter request on " << *lock << " on " << *lock->get_parent() << dendl; - if (lock->get_state() != LOCK_MIX) // i.e., the reqscatter didn't race with an actual mix/scatter + if (lock->get_state() != LOCK_MIX && + lock->get_state() != LOCK_MIX_STALE) // i.e., the reqscatter didn't race with an actual mix/scatter file_mixed(lock); } else { dout(7) << "handle_file_lock ignoring scatter request on " << *lock -- 2.39.5