diff options
-rw-r--r-- | src/mds/CInode.cc | 4 | ||||
-rw-r--r-- | src/mds/Capability.h | 8 | ||||
-rw-r--r-- | src/mds/Locker.cc | 89 | ||||
-rw-r--r-- | src/mds/Locker.h | 2 | ||||
-rw-r--r-- | src/mds/MDCache.cc | 1 | ||||
-rw-r--r-- | src/mds/locks.c | 3 | ||||
-rw-r--r-- | src/mds/locks.h | 1 |
7 files changed, 52 insertions, 56 deletions
diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index d215d18690f..dd483263b6d 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -2733,10 +2733,12 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session, // do not issue caps if inode differs from readdir snaprealm SnapRealm *realm = find_snaprealm(); - bool no_caps = (realm && dir_realm && realm != dir_realm) || + bool no_caps = session->is_stale() || + (realm && dir_realm && realm != dir_realm) || is_frozen() || state_test(CInode::STATE_EXPORTINGCAPS); if (no_caps) dout(20) << "encode_inodestat no caps" + << (session->is_stale()?", session stale ":"") << ((realm && dir_realm && realm != dir_realm)?", snaprealm differs ":"") << (state_test(CInode::STATE_EXPORTINGCAPS)?", exporting caps":"") << (is_frozen()?", frozen inode":"") << dendl; diff --git a/src/mds/Capability.h b/src/mds/Capability.h index fdecb9090b3..fb6b3dc1f16 100644 --- a/src/mds/Capability.h +++ b/src/mds/Capability.h @@ -171,14 +171,16 @@ public: } void confirm_receipt(ceph_seq_t seq, unsigned caps) { if (seq == last_sent) { - _pending = caps; _revokes.clear(); _issued = caps; + // don't add bits + _pending &= caps; } else { // can i forget any revocations? - while (!_revokes.empty() && - _revokes.front().seq <= seq) + while (!_revokes.empty() && _revokes.front().seq < seq) _revokes.pop_front(); + if (!_revokes.empty() && _revokes.front().seq == seq) + _revokes.begin()->before = caps; _calc_issued(); } //check_rdcaps_list(); diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 30e014ab785..084d64aeb9c 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -543,15 +543,16 @@ void Locker::cancel_locking(Mutation *mut, set<CInode*> *pneed_issue) dout(10) << "cancel_locking " << *lock << " on " << *mut << dendl; if (lock->get_parent()->is_auth()) { - if (lock->get_type() != CEPH_LOCK_DN) { - bool need_issue = false; - if (lock->get_state() == LOCK_PREXLOCK) - _finish_xlock(lock, &need_issue); - if (lock->is_stable()) - eval(lock, &need_issue); - if (need_issue) - pneed_issue->insert(static_cast<CInode *>(lock->get_parent())); + bool need_issue = false; + if (lock->get_state() == LOCK_PREXLOCK) { + _finish_xlock(lock, -1, &need_issue); + } else if (lock->get_state() == LOCK_LOCK_XLOCK && + lock->get_num_xlocks() == 0) { + lock->set_state(LOCK_XLOCKDONE); + eval_gather(lock, true, &need_issue); } + if (need_issue) + pneed_issue->insert(static_cast<CInode *>(lock->get_parent())); } mut->finish_locking(lock); } @@ -1458,19 +1459,29 @@ bool Locker::xlock_start(SimpleLock *lock, MDRequest *mut) } } -void Locker::_finish_xlock(SimpleLock *lock, bool *pneed_issue) +void Locker::_finish_xlock(SimpleLock *lock, client_t xlocker, bool *pneed_issue) { assert(!lock->is_stable()); - if (lock->get_type() != CEPH_LOCK_DN && (static_cast<CInode*>(lock->get_parent())->get_loner()) >= 0) - lock->set_state(LOCK_EXCL); - else - lock->set_state(LOCK_LOCK); - if (lock->get_type() == CEPH_LOCK_DN && lock->get_parent()->is_replicated() && - !lock->is_waiter_for(SimpleLock::WAIT_WR)) - simple_sync(lock, pneed_issue); - if (lock->get_cap_shift()) - *pneed_issue = true; - lock->get_parent()->auth_unpin(lock); + if (lock->get_num_rdlocks() == 0 && + lock->get_num_wrlocks() == 0 && + lock->get_num_client_lease() == 0 && + lock->get_type() != CEPH_LOCK_DN) { + CInode *in = static_cast<CInode*>(lock->get_parent()); + client_t loner = in->get_target_loner(); + if (loner >= 0 && (xlocker < 0 || xlocker == loner)) { + lock->set_state(LOCK_EXCL); + lock->get_parent()->auth_unpin(lock); + lock->finish_waiters(SimpleLock::WAIT_STABLE|SimpleLock::WAIT_WR|SimpleLock::WAIT_RD); + if (lock->get_cap_shift()) + *pneed_issue = true; + if (lock->get_parent()->is_auth() && + lock->is_stable()) + try_eval(lock, pneed_issue); + return; + } + } + // the xlocker may have CEPH_CAP_GSHARED, need to revoke it if next state is LOCK_LOCK + eval_gather(lock, true, pneed_issue); } void Locker::xlock_finish(SimpleLock *lock, Mutation *mut, bool *pneed_issue) @@ -1481,6 +1492,8 @@ void Locker::xlock_finish(SimpleLock *lock, Mutation *mut, bool *pneed_issue) dout(10) << "xlock_finish on " << *lock << " " << *lock->get_parent() << dendl; + client_t xlocker = lock->get_xlock_by_client(); + // drop ref lock->put_xlock(); assert(mut); @@ -1508,24 +1521,12 @@ void Locker::xlock_finish(SimpleLock *lock, Mutation *mut, bool *pneed_issue) SimpleLock::WAIT_WR | SimpleLock::WAIT_RD, 0); } else { - if (lock->get_num_xlocks() == 0 && - lock->get_num_rdlocks() == 0 && - lock->get_num_wrlocks() == 0 && - lock->get_num_client_lease() == 0) { - _finish_xlock(lock, &do_issue); + if (lock->get_num_xlocks() == 0) { + if (lock->get_state() == LOCK_LOCK_XLOCK) + lock->set_state(LOCK_XLOCKDONE); + _finish_xlock(lock, xlocker, &do_issue); } - - // others waiting? - lock->finish_waiters(SimpleLock::WAIT_STABLE | - SimpleLock::WAIT_WR | - SimpleLock::WAIT_RD, 0); } - - // eval? - if (!lock->is_stable()) - eval_gather(lock, false, &do_issue); - else if (lock->get_parent()->is_auth()) - try_eval(lock, &do_issue); if (do_issue) { CInode *in = static_cast<CInode*>(lock->get_parent()); @@ -3440,7 +3441,6 @@ bool Locker::simple_sync(SimpleLock *lock, bool *need_issue) switch (lock->get_state()) { case LOCK_MIX: lock->set_state(LOCK_MIX_SYNC); break; - case LOCK_SCAN: case LOCK_LOCK: lock->set_state(LOCK_LOCK_SYNC); break; case LOCK_XSYN: lock->set_state(LOCK_XSYN_SYNC); break; case LOCK_EXCL: lock->set_state(LOCK_EXCL_SYNC); break; @@ -3517,7 +3517,6 @@ void Locker::simple_excl(SimpleLock *lock, bool *need_issue) in = static_cast<CInode *>(lock->get_parent()); switch (lock->get_state()) { - case LOCK_SCAN: case LOCK_LOCK: lock->set_state(LOCK_LOCK_EXCL); break; case LOCK_SYNC: lock->set_state(LOCK_SYNC_EXCL); break; case LOCK_XSYN: lock->set_state(LOCK_XSYN_EXCL); break; @@ -3576,7 +3575,6 @@ void Locker::simple_lock(SimpleLock *lock, bool *need_issue) int old_state = lock->get_state(); switch (lock->get_state()) { - case LOCK_SCAN: lock->set_state(LOCK_SCAN_LOCK); break; case LOCK_SYNC: lock->set_state(LOCK_SYNC_LOCK); break; case LOCK_XSYN: file_excl(static_cast<ScatterLock*>(lock), need_issue); @@ -4162,10 +4160,6 @@ void Locker::file_eval(ScatterLock *lock, bool *need_issue) if (lock->get_parent()->is_freezing_or_frozen()) return; - // wait for scan - if (lock->get_state() == LOCK_SCAN) - return; - // excl -> *? if (lock->get_state() == LOCK_EXCL) { dout(20) << " is excl" << dendl; @@ -4352,7 +4346,6 @@ 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: lock->set_state(LOCK_MIX_EXCL); break; - case LOCK_SCAN: case LOCK_LOCK: lock->set_state(LOCK_LOCK_EXCL); break; case LOCK_XSYN: lock->set_state(LOCK_XSYN_EXCL); break; default: assert(0); @@ -4463,12 +4456,12 @@ void Locker::file_recover(ScatterLock *lock) issue_caps(in); gather++; } - if (gather) { - lock->get_parent()->auth_pin(lock); - } else { - lock->set_state(LOCK_SCAN); + + lock->set_state(LOCK_SCAN); + if (gather) + in->state_set(CInode::STATE_NEEDSRECOVER); + else mds->mdcache->queue_file_recover(in); - } } diff --git a/src/mds/Locker.h b/src/mds/Locker.h index b97307d6cb2..b39eff175d6 100644 --- a/src/mds/Locker.h +++ b/src/mds/Locker.h @@ -143,7 +143,7 @@ public: void remote_wrlock_finish(SimpleLock *lock, int target, Mutation *mut); bool xlock_start(SimpleLock *lock, MDRequest *mut); - void _finish_xlock(SimpleLock *lock, bool *pneed_issue); + void _finish_xlock(SimpleLock *lock, client_t xlocker, bool *pneed_issue); void xlock_finish(SimpleLock *lock, Mutation *mut, bool *pneed_issue); void xlock_export(SimpleLock *lock, Mutation *mut); diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 77d3d8b97b8..898dcd39f48 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -5718,6 +5718,7 @@ void MDCache::identify_files_to_recover(vector<CInode*>& recover_q, vector<CInod } if (recover) { + in->auth_pin(&in->filelock); in->filelock.set_state(LOCK_PRE_SCAN); recover_q.push_back(in); diff --git a/src/mds/locks.c b/src/mds/locks.c index 90310874411..37e3f5ea764 100644 --- a/src/mds/locks.c +++ b/src/mds/locks.c @@ -122,8 +122,7 @@ const struct sm_state_t filelock[LOCK_MAX] = { [LOCK_EXCL_XSYN] = { LOCK_XSYN, false, LOCK_LOCK, 0, 0, XCL, 0, 0, 0, 0, 0,CEPH_CAP_GCACHE|CEPH_CAP_GBUFFER,0,0 }, [LOCK_PRE_SCAN] = { LOCK_SCAN, false, LOCK_LOCK, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0 }, - [LOCK_SCAN] = { 0, false, LOCK_LOCK, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0 }, - [LOCK_SCAN_LOCK] = { LOCK_LOCK, false, LOCK_LOCK, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0 }, + [LOCK_SCAN] = { LOCK_LOCK, false, LOCK_LOCK, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0 }, }; const struct sm_t sm_filelock = { diff --git a/src/mds/locks.h b/src/mds/locks.h index 2adcbf21fea..d1585cec576 100644 --- a/src/mds/locks.h +++ b/src/mds/locks.h @@ -86,7 +86,6 @@ enum { LOCK_PRE_SCAN, LOCK_SCAN, - LOCK_SCAN_LOCK, LOCK_SNAP_SYNC, |