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;
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++;
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);
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;
}
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);
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);
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);
}
}
// * -> 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() ||
!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() ||
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;
// -- 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;
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);
}
*/
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