From e27f111f31f25a66f0a691247dc42978d1cd5aa1 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 5 Nov 2010 21:52:28 -0700 Subject: [PATCH] mds: preserve stale state on import; some cleanup Our new invariant is that MIX_STALE always implies is_stale(). And on import, if is_stale(), MIX becomes MIX_STALE. This ensures that a replica that we put into MIX_STALE doesn't turn back into MIX if we import it and take the auth's state in CInode::decode_import(). Signed-off-by: Sage Weil --- src/mds/CDir.cc | 14 ++++---------- src/mds/CInode.cc | 2 ++ src/mds/Locker.cc | 7 +++---- src/mds/ScatterLock.h | 26 ++++++++++++++++++++++---- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index b90e662d28c4c..d6354691f399b 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -1194,9 +1194,9 @@ void CDir::_fetched(bufferlist &bl, const string& want_dn) projected_version = committing_version = committed_version = got_fnode.version; if (fnode.rstat.version < inode->inode.rstat.version) - inode->nestlock.set_stale(); + inode->nestlock.set_and_apply_stale(); if (fnode.fragstat.version < inode->inode.dirstat.version) - inode->filelock.set_stale(); + inode->filelock.set_and_apply_stale(); } // purge stale snaps? @@ -1876,19 +1876,13 @@ void CDir::decode_import(bufferlist::iterator& blp, utime_t now) inode_t *pi = inode->get_projected_inode(); if (fnode.fragstat.version != pi->dirstat.version) { dout(10) << " got stale fragstat " << fnode.fragstat << " vs inode " << pi->dirstat << dendl; - if (inode->filelock.get_state() == LOCK_MIX) - inode->filelock.set_state(LOCK_MIX_STALE); - else if (inode->filelock.get_state() != LOCK_MIX_STALE) - inode->filelock.set_stale(); + inode->filelock.set_and_apply_stale(); } // stale rstat? if (fnode.rstat.version != pi->rstat.version) { dout(10) << " got stale rstat " << fnode.rstat << " vs inode " << pi->rstat << dendl; - if (inode->nestlock.get_state() == LOCK_MIX) - inode->nestlock.set_state(LOCK_MIX_STALE); - else if (inode->nestlock.get_state() != LOCK_MIX_STALE) - inode->nestlock.set_stale(); + inode->nestlock.set_and_apply_stale(); } } diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 800919cec49e6..595dab8b2381c 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -2373,9 +2373,11 @@ void CInode::_decode_locks_full(bufferlist::iterator& p) ::decode(linklock, p); ::decode(dirfragtreelock, p); ::decode(filelock, p); + filelock.apply_stale(); ::decode(xattrlock, p); ::decode(snaplock, p); ::decode(nestlock, p); + nestlock.apply_stale(); ::decode(flocklock, p); ::decode(policylock, p); } diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 7f8e234492115..b97af0c4c0a3a 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -3965,12 +3965,11 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m) // ok lock->decode_locked_state(m->get_data()); - if (!lock->is_stale()) - lock->set_state(LOCK_MIX); - else { + if (!lock->is_stale()) { dout(15) << "setting state to LOCK_MIX_STALE instead of LOCK_MIX" << dendl; lock->set_state(LOCK_MIX_STALE); - } + } else + lock->set_state(LOCK_MIX); ((ScatterLock *)lock)->finish_flush(); diff --git a/src/mds/ScatterLock.h b/src/mds/ScatterLock.h index 085ce400185a1..d9ffada083f5c 100644 --- a/src/mds/ScatterLock.h +++ b/src/mds/ScatterLock.h @@ -141,21 +141,39 @@ public: start_flush(); finish_flush(); } - + + /* + * "stale" means that at least one of our dirfrags has stale + * accounted_* scatter metadata on this inode. that means that any + * transition to MIX needs to implicitly go to MIX_STALE. also, + * MIX_STALE implies is_stale(). + */ bool is_stale() const { - return have_more() && _more->stale; + if (have_more() && _more->stale) + return true; + assert(state != LOCK_MIX_STALE); // invariant: LOCK_MIX_STALE => is_stale() + return false; } - void set_stale() { more()->stale = true; } - void clear_stale() { if (is_stale()) { _more->stale = false; try_clear_more(); } } + void apply_stale() { + if (state == LOCK_MIX_STALE) + set_stale(); + else if (is_stale() && state == LOCK_MIX) + state = LOCK_MIX_STALE; + } + void set_and_apply_stale() { + set_stale(); + if (state == LOCK_MIX) + state = LOCK_MIX_STALE; + } void set_last_scatter(utime_t t) { more()->last_scatter = t; } utime_t get_last_scatter() { -- 2.39.5