summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-08-08 22:19:21 -0700
committerSage Weil <sage@inktank.com>2013-08-08 22:19:21 -0700
commit151e6d24e4512076731e7dbe9707bd36b2aad986 (patch)
tree45e1e67a9a2253b7f02beb27570671a7b3a8f6e9
parent7e285149fb2616d59f5f70d722a28d8a0bbfcdb7 (diff)
parent0c22dade2481af5431c3ce06a2e2329937225a95 (diff)
downloadceph-151e6d24e4512076731e7dbe9707bd36b2aad986.tar.gz
Merge remote-tracking branch 'yan/wip-mds'
Reviewed-by: Sage Weil <sage@inktank.com>
-rw-r--r--src/mds/CInode.cc4
-rw-r--r--src/mds/Capability.h8
-rw-r--r--src/mds/Locker.cc89
-rw-r--r--src/mds/Locker.h2
-rw-r--r--src/mds/MDCache.cc1
-rw-r--r--src/mds/locks.c3
-rw-r--r--src/mds/locks.h1
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,