diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 9512ebfbb1a..1e112864f63 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -2751,10 +2751,24 @@ client_t CInode::calc_ideal_loner() return loner; } -client_t CInode::choose_ideal_loner() +bool CInode::choose_ideal_loner() { want_loner_cap = calc_ideal_loner(); - return want_loner_cap; + int changed = false; + if (loner_cap >= 0 && loner_cap != want_loner_cap) { + if (!try_drop_loner()) + return false; + changed = true; + } + + if (want_loner_cap >= 0) { + if (loner_cap < 0) { + set_loner_cap(want_loner_cap); + changed = true; + } else + assert(loner_cap == want_loner_cap); + } + return changed; } bool CInode::try_set_loner() @@ -2822,9 +2836,8 @@ void CInode::choose_lock_state(SimpleLock *lock, int allissued) void CInode::choose_lock_states(int dirty_caps) { int issued = get_caps_issued() | dirty_caps; - if (is_auth() && (issued & (CEPH_CAP_ANY_EXCL|CEPH_CAP_ANY_WR)) && - choose_ideal_loner() >= 0) - try_set_loner(); + if (is_auth() && (issued & (CEPH_CAP_ANY_EXCL|CEPH_CAP_ANY_WR))) + choose_ideal_loner(); choose_lock_state(&filelock, issued); choose_lock_state(&nestlock, issued); choose_lock_state(&dirfragtreelock, issued); @@ -3314,12 +3327,8 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session, if (!no_caps && !cap) { // add a new cap cap = add_client_cap(client, session, realm); - if (is_auth()) { - if (choose_ideal_loner() >= 0) - try_set_loner(); - else if (get_wanted_loner() < 0) - try_drop_loner(); - } + if (is_auth()) + choose_ideal_loner(); } int issue = 0; diff --git a/src/mds/CInode.h b/src/mds/CInode.h index f95f299f4a1..b0cbc39a151 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -936,9 +936,9 @@ public: } client_t calc_ideal_loner(); - client_t choose_ideal_loner(); - bool try_set_loner(); void set_loner_cap(client_t l); + bool choose_ideal_loner(); + bool try_set_loner(); bool try_drop_loner(); // choose new lock state during recovery, based on issued caps diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 01427c63b82..f2055db87dd 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -958,6 +958,7 @@ void Locker::eval_gather(SimpleLock *lock, bool first, bool *pneed_issue, liststart_scatter(static_cast(lock)); if (lock->get_parent()->is_replicated()) { bufferlist softdata; @@ -1038,15 +1039,15 @@ bool Locker::eval(CInode *in, int mask, bool caps_imported) // choose loner? if (in->is_auth() && in->is_head()) { - if (in->choose_ideal_loner() >= 0) { - if (in->try_set_loner()) { - dout(10) << "eval set loner to client." << in->get_loner() << dendl; - need_issue = true; - mask = -1; - } else - dout(10) << "eval want loner client." << in->get_wanted_loner() << " but failed to set it" << dendl; - } else - dout(10) << "eval doesn't want loner" << dendl; + client_t orig_loner = in->get_loner(); + if (in->choose_ideal_loner()) { + dout(10) << "eval set loner: client." << orig_loner << " -> client." << in->get_loner() << dendl; + need_issue = true; + mask = -1; + } else if (in->get_wanted_loner() != in->get_loner()) { + dout(10) << "eval want loner: client." << in->get_wanted_loner() << " but failed to set it" << dendl; + mask = -1; + } } retry: @@ -1067,19 +1068,14 @@ bool Locker::eval(CInode *in, int mask, bool caps_imported) // drop loner? if (in->is_auth() && in->is_head() && in->get_wanted_loner() != in->get_loner()) { - dout(10) << " trying to drop loner" << dendl; if (in->try_drop_loner()) { - dout(10) << " dropped loner" << dendl; need_issue = true; - if (in->get_wanted_loner() >= 0) { - if (in->try_set_loner()) { - dout(10) << "eval end set loner to client." << in->get_loner() << dendl; - mask = -1; - goto retry; - } else { - dout(10) << "eval want loner client." << in->get_wanted_loner() << " but failed to set it" << dendl; - } + dout(10) << "eval end set loner to client." << in->get_loner() << dendl; + bool ok = in->try_set_loner(); + assert(ok); + mask = -1; + goto retry; } } } @@ -4187,11 +4183,7 @@ void Locker::simple_lock(SimpleLock *lock, bool *need_issue) switch (lock->get_state()) { case LOCK_SYNC: lock->set_state(LOCK_SYNC_LOCK); break; - case LOCK_XSYN: - file_excl(static_cast(lock), need_issue); - if (lock->get_state() != LOCK_EXCL) - return; - // fall-thru + case LOCK_XSYN: lock->set_state(LOCK_XSYN_LOCK); break; case LOCK_EXCL: lock->set_state(LOCK_EXCL_LOCK); break; case LOCK_MIX: lock->set_state(LOCK_MIX_LOCK); (static_cast(lock))->clear_unscatter_wanted(); @@ -4858,7 +4850,7 @@ void Locker::file_eval(ScatterLock *lock, bool *need_issue) !lock->is_rdlocked() && //!lock->is_waiter_for(SimpleLock::WAIT_WR) && (lock->get_scatter_wanted() || - (in->get_wanted_loner() < 0 && (wanted & CEPH_CAP_GWR)))) { + (in->get_target_loner() < 0 && (wanted & CEPH_CAP_GWR)))) { dout(7) << "file_eval stable, bump to mixed " << *lock << " on " << *lock->get_parent() << dendl; scatter_mix(lock, need_issue); @@ -4916,12 +4908,8 @@ void Locker::scatter_mix(ScatterLock *lock, bool *need_issue) // gather? switch (lock->get_state()) { case LOCK_SYNC: lock->set_state(LOCK_SYNC_MIX); break; - case LOCK_XSYN: - file_excl(lock, need_issue); - if (lock->get_state() != LOCK_EXCL) - return; - // fall-thru case LOCK_EXCL: lock->set_state(LOCK_EXCL_MIX); break; + case LOCK_XSYN: lock->set_state(LOCK_XSYN_MIX); break; case LOCK_TSYN: lock->set_state(LOCK_TSYN_MIX); break; default: ceph_abort(); } @@ -4930,8 +4918,7 @@ void Locker::scatter_mix(ScatterLock *lock, bool *need_issue) if (lock->is_rdlocked()) gather++; if (in->is_replicated()) { - if (lock->get_state() != LOCK_EXCL_MIX && // EXCL replica is already LOCK - lock->get_state() != LOCK_XSYN_EXCL) { // XSYN replica is already LOCK; ** FIXME here too! + if (lock->get_state() == LOCK_SYNC_MIX) { // for the rest states, replicas are already LOCK send_lock_message(lock, LOCK_AC_MIX); lock->init_gather(); gather++; diff --git a/src/mds/SimpleLock.h b/src/mds/SimpleLock.h index 6e60d2a7015..8c52df733c5 100644 --- a/src/mds/SimpleLock.h +++ b/src/mds/SimpleLock.h @@ -120,6 +120,8 @@ public: case LOCK_XSYN_EXCL: return "xsyn->excl"; case LOCK_EXCL_XSYN: return "excl->xsyn"; case LOCK_XSYN_SYNC: return "xsyn->sync"; + case LOCK_XSYN_LOCK: return "xsyn->lock"; + case LOCK_XSYN_MIX: return "xsyn->mix"; case LOCK_SYNC_MIX: return "sync->mix"; case LOCK_SYNC_MIX2: return "sync->mix(2)"; diff --git a/src/mds/locks.c b/src/mds/locks.c index 2fc0a5fc041..de99abe7a7d 100644 --- a/src/mds/locks.c +++ b/src/mds/locks.c @@ -95,6 +95,7 @@ const struct sm_state_t filelock[LOCK_MAX] = { [LOCK_EXCL_LOCK] = { LOCK_LOCK, false, LOCK_LOCK, 0, 0, 0, 0, XCL, 0, 0, CEPH_CAP_GCACHE|CEPH_CAP_GBUFFER,0,0,0 }, [LOCK_MIX_LOCK] = { LOCK_LOCK, false, LOCK_MIX, AUTH, 0, REQ, 0, 0, 0, 0, 0,0,0,0 }, [LOCK_MIX_LOCK2] = { LOCK_LOCK, false, LOCK_LOCK, AUTH, 0, REQ, 0, 0, 0, 0, 0,0,0,0 }, + [LOCK_XSYN_LOCK] = { LOCK_LOCK, true, LOCK_LOCK, AUTH, 0, 0, XCL, 0, 0, 0, 0,CEPH_CAP_GCACHE|CEPH_CAP_GBUFFER,0,0 }, [LOCK_PREXLOCK] = { LOCK_LOCK, false, LOCK_LOCK, 0, XCL, 0, 0, 0, 0, ANY, CEPH_CAP_GCACHE|CEPH_CAP_GBUFFER,0,0,0 }, [LOCK_XLOCK] = { LOCK_LOCK, false, LOCK_LOCK, 0, XCL, 0, 0, 0, 0, 0, CEPH_CAP_GCACHE|CEPH_CAP_GBUFFER,0,0,0 }, @@ -106,6 +107,7 @@ const struct sm_state_t filelock[LOCK_MAX] = { [LOCK_SYNC_MIX] = { LOCK_MIX, false, LOCK_SYNC_MIX2,ANY,0, 0, 0, 0, 0, 0, CEPH_CAP_GRD|CEPH_CAP_GLAZYIO,0,0,CEPH_CAP_GRD }, [LOCK_SYNC_MIX2] = { LOCK_MIX, false, 0, 0, 0, 0, 0, 0, 0, 0, CEPH_CAP_GRD|CEPH_CAP_GLAZYIO,0,0,CEPH_CAP_GRD }, [LOCK_EXCL_MIX] = { LOCK_MIX, true, LOCK_LOCK, 0, 0, 0, XCL, 0, 0, 0, 0,CEPH_CAP_GRD|CEPH_CAP_GWR|CEPH_CAP_GLAZYIO,0,0 }, + [LOCK_XSYN_MIX] = { LOCK_MIX, true, LOCK_LOCK, 0, 0, 0, XCL, 0, 0, 0, 0,0,0,0 }, [LOCK_EXCL] = { 0, true, LOCK_LOCK, 0, 0, XCL, XCL, 0, 0, 0, 0,CEPH_CAP_GSHARED|CEPH_CAP_GEXCL|CEPH_CAP_GCACHE|CEPH_CAP_GRD|CEPH_CAP_GWR|CEPH_CAP_GBUFFER|CEPH_CAP_GLAZYIO,0,0 }, [LOCK_SYNC_EXCL] = { LOCK_EXCL, true, LOCK_LOCK, AUTH, 0, 0, 0, 0, 0, 0, 0,CEPH_CAP_GSHARED|CEPH_CAP_GCACHE|CEPH_CAP_GRD,0,0 }, diff --git a/src/mds/locks.h b/src/mds/locks.h index 9f4ea566b4a..252cf0ed524 100644 --- a/src/mds/locks.h +++ b/src/mds/locks.h @@ -94,6 +94,8 @@ enum { LOCK_XSYN_EXCL, LOCK_EXCL_XSYN, LOCK_XSYN_SYNC, + LOCK_XSYN_LOCK, + LOCK_XSYN_MIX, LOCK_MAX, };