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()
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);
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;
}
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
// 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:
// 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;
}
}
}