mds: more lock refactoring. merge *_lock() methods.

This commit is contained in:
Sage Weil 2009-01-15 20:14:00 -08:00
parent 7a9a689daa
commit 0a20684698
6 changed files with 67 additions and 157 deletions

View File

@ -148,7 +148,7 @@ public:
version(0), projected_version(0),
xlist_dirty(this),
auth_pins(0), nested_auth_pins(0), nested_anchors(0),
lock(this, CEPH_LOCK_DN, WAIT_LOCK_OFFSET, 0) { }
lock(this, CEPH_LOCK_DN, WAIT_LOCK_OFFSET) { }
CDentry(const nstring& n, inodeno_t ino, unsigned char dt,
snapid_t f, snapid_t l) :
name(n),
@ -157,7 +157,7 @@ public:
version(0), projected_version(0),
xlist_dirty(this),
auth_pins(0), nested_auth_pins(0), nested_anchors(0),
lock(this, CEPH_LOCK_DN, WAIT_LOCK_OFFSET, 0) {
lock(this, CEPH_LOCK_DN, WAIT_LOCK_OFFSET) {
linkage.remote_ino = ino;
linkage.remote_d_type = dt;
}

View File

@ -297,14 +297,14 @@ private:
xlist_purging_inode(this),
auth_pins(0), nested_auth_pins(0),
nested_anchors(0),
versionlock(this, CEPH_LOCK_IVERSION, WAIT_VERSIONLOCK_OFFSET, 0),
authlock(this, CEPH_LOCK_IAUTH, WAIT_AUTHLOCK_OFFSET, CEPH_CAP_SAUTH),
linklock(this, CEPH_LOCK_ILINK, WAIT_LINKLOCK_OFFSET, CEPH_CAP_SLINK),
dirfragtreelock(this, CEPH_LOCK_IDFT, WAIT_DIRFRAGTREELOCK_OFFSET, 0),
filelock(this, CEPH_LOCK_IFILE, WAIT_FILELOCK_OFFSET, CEPH_CAP_SFILE),
xattrlock(this, CEPH_LOCK_IXATTR, WAIT_XATTRLOCK_OFFSET, CEPH_CAP_SXATTR),
snaplock(this, CEPH_LOCK_ISNAP, WAIT_SNAPLOCK_OFFSET, 0),
nestlock(this, CEPH_LOCK_INEST, WAIT_NESTLOCK_OFFSET, 0),
versionlock(this, CEPH_LOCK_IVERSION, WAIT_VERSIONLOCK_OFFSET),
authlock(this, CEPH_LOCK_IAUTH, WAIT_AUTHLOCK_OFFSET),
linklock(this, CEPH_LOCK_ILINK, WAIT_LINKLOCK_OFFSET),
dirfragtreelock(this, CEPH_LOCK_IDFT, WAIT_DIRFRAGTREELOCK_OFFSET),
filelock(this, CEPH_LOCK_IFILE, WAIT_FILELOCK_OFFSET),
xattrlock(this, CEPH_LOCK_IXATTR, WAIT_XATTRLOCK_OFFSET),
snaplock(this, CEPH_LOCK_ISNAP, WAIT_SNAPLOCK_OFFSET),
nestlock(this, CEPH_LOCK_INEST, WAIT_NESTLOCK_OFFSET),
loner_cap(-1)
{
memset(&inode, 0, sizeof(inode));

View File

@ -19,13 +19,9 @@
#include "SimpleLock.h"
class LocalLock : public SimpleLock {
protected:
int num_wrlock;
public:
LocalLock(MDSCacheObject *o, int t, int ws, int cs ) :
SimpleLock(o, t, ws, cs),
num_wrlock(0) {
LocalLock(MDSCacheObject *o, int t, int ws) :
SimpleLock(o, t, ws) {
set_state(LOCK_LOCK); // always.
}

View File

@ -579,7 +579,7 @@ bool Locker::rdlock_start(SimpleLock *lock, MDRequest *mut)
else
scatter_sync((ScatterLock*)lock);
} else if (lock->sm == &sm_filelock)
file_lock((ScatterLock*)lock);
simple_lock(lock);
else
simple_sync(lock);
}
@ -666,21 +666,17 @@ bool Locker::wrlock_start(SimpleLock *lock, MDRequest *mut, bool nowait)
break;
if (in->is_auth()) {
if (lock->sm == &sm_filelock) {
if (want_scatter)
if (want_scatter) {
if (lock->sm == &sm_filelock)
file_mixed((ScatterLock*)lock);
else
file_lock((ScatterLock*)lock);
} else if (lock->sm == &sm_scatterlock) {
if (want_scatter)
scatter_scatter((ScatterLock*)lock, nowait);
else
scatter_lock((ScatterLock*)lock, nowait);
if (nowait && !lock->can_wrlock(client))
return false;
} else
assert(0);
continue;
} else
simple_lock(lock);
if (nowait && !lock->can_wrlock(client))
return false;
} else {
// replica.
// auth should be auth_pinned (see acquire_locks wrlock weird mustpin case).
@ -688,6 +684,7 @@ bool Locker::wrlock_start(SimpleLock *lock, MDRequest *mut, bool nowait)
dout(10) << "requesting scatter from auth on "
<< *lock << " on " << *lock->get_parent() << dendl;
mds->send_message_mds(new MLock(lock, LOCK_AC_REQSCATTER, mds->get_nodeid()), auth);
break;
}
}
@ -756,10 +753,7 @@ bool Locker::xlock_start(SimpleLock *lock, MDRequest *mut)
if (lock->get_state() == LOCK_LOCK)
simple_xlock(lock);
else {
if (lock->sm == &sm_simplelock)
simple_lock(lock);
else
file_lock((ScatterLock*)lock);
simple_lock(lock);
}
}
@ -1276,7 +1270,7 @@ bool Locker::check_inode_max_size(CInode *in, bool force_wrlock, bool update_siz
if (!force_wrlock && !in->filelock.can_wrlock(-1)) {
// lock?
if (in->filelock.is_stable())
file_lock(&in->filelock);
simple_lock(&in->filelock);
if (!in->filelock.can_wrlock(-1)) {
// try again later
in->filelock.add_waiter(SimpleLock::WAIT_STABLE, new C_MDL_CheckMaxSize(this, in));
@ -2126,7 +2120,7 @@ bool Locker::simple_sync(SimpleLock *lock)
if (in) {
int loner_issued, other_issued;
in->get_caps_issued(&loner_issued, &other_issued, lock->get_cap_shift(), 3);
in->get_caps_issued(&loner_issued, &other_issued, lock->get_cap_shift(), lock->get_cap_mask());
if ((loner_issued & ~lock->gcaps_allowed(true)) ||
(other_issued & ~lock->gcaps_allowed(false))) {
issue_caps(in);
@ -2162,14 +2156,19 @@ void Locker::simple_lock(SimpleLock *lock)
if (lock->get_cap_shift())
in = (CInode *)lock->get_parent();
int old_state = lock->get_state();
switch (lock->get_state()) {
case LOCK_SYNC: lock->set_state(LOCK_SYNC_LOCK); break;
case LOCK_EXCL: lock->set_state(LOCK_EXCL_LOCK); break;
case LOCK_MIX: lock->set_state(LOCK_MIX_LOCK); break;
case LOCK_TSYN: lock->set_state(LOCK_TSYN_LOCK); break;
default: assert(0);
}
int gather = 0;
if (lock->get_parent()->is_replicated()) {
if (lock->get_parent()->is_replicated() &&
lock->sm->states[old_state].replica_state != LOCK_LOCK) { // replica may already be LOCK
gather++;
send_lock_message(lock, LOCK_AC_LOCK);
lock->init_gather();
@ -2180,10 +2179,9 @@ void Locker::simple_lock(SimpleLock *lock)
}
if (lock->is_rdlocked())
gather++;
if (in) {
int loner_issued, other_issued;
in->get_caps_issued(&loner_issued, &other_issued, lock->get_cap_shift(), 3);
in->get_caps_issued(&loner_issued, &other_issued, lock->get_cap_shift(), lock->get_cap_mask());
if ((loner_issued & ~lock->gcaps_allowed(true)) ||
(other_issued & ~lock->gcaps_allowed(false))) {
issue_caps(in);
@ -2191,10 +2189,24 @@ void Locker::simple_lock(SimpleLock *lock)
}
}
if (lock->get_type() == CEPH_LOCK_IFILE &&
in->state_test(CInode::STATE_NEEDSRECOVER)) {
mds->mdcache->queue_file_recover(in);
mds->mdcache->do_file_recover();
gather++;
}
if (!gather && lock->is_updated()) {
scatter_writebehind((ScatterLock*)lock);
gather++;
}
if (gather) {
lock->get_parent()->auth_pin(lock);
} else {
lock->set_state(LOCK_LOCK);
in->loner_cap = -1;
lock->finish_waiters(FileLock::WAIT_XLOCK|FileLock::WAIT_WR|FileLock::WAIT_STABLE);
}
}
@ -2475,7 +2487,7 @@ void Locker::scatter_nudge(ScatterLock *lock, Context *c)
if (p->is_replicated() && lock->get_state() != LOCK_MIX)
file_mixed((FileLock*)lock);
else
file_lock((FileLock*)lock);
simple_lock((FileLock*)lock);
break;
case CEPH_LOCK_IDFT:
@ -2483,7 +2495,7 @@ void Locker::scatter_nudge(ScatterLock *lock, Context *c)
if (p->is_replicated() && lock->get_state() != LOCK_MIX)
scatter_scatter(lock);
else // if (lock->get_state() != LOCK_LOCK)
scatter_lock(lock);
simple_lock(lock);
//else
//scatter_sync(lock);
break;
@ -2649,59 +2661,6 @@ void Locker::scatter_scatter(ScatterLock *lock, bool nowait)
revoke_client_leases(lock);
}
bool Locker::scatter_lock_fastpath(ScatterLock *lock)
{
assert(lock->get_parent()->is_auth());
assert(lock->is_stable());
if (lock->get_state() == LOCK_LOCK)
return true;
if (!lock->is_rdlocked() &&
!lock->is_wrlocked() &&
!lock->is_xlocked() &&
!lock->get_num_client_lease() &&
(!lock->get_parent()->is_replicated() || // sync | scatter
lock->get_state() == LOCK_TSYN)) {
if (lock->is_updated()) {
scatter_writebehind(lock);
return false;
}
// lock
lock->set_state(LOCK_LOCK);
lock->finish_waiters(ScatterLock::WAIT_XLOCK|ScatterLock::WAIT_WR|ScatterLock::WAIT_STABLE);
return true;
}
return false;
}
void Locker::scatter_lock(ScatterLock *lock, bool nowait)
{
dout(10) << "scatter_lock " << *lock
<< " on " << *lock->get_parent() << dendl;
assert(lock->get_parent()->is_auth());
assert(lock->is_stable());
if (scatter_lock_fastpath(lock) || nowait)
return;
switch (lock->get_state()) {
case LOCK_SYNC: lock->set_state(LOCK_SYNC_LOCK); break;
case LOCK_MIX: lock->set_state(LOCK_MIX_LOCK); break;
case LOCK_TSYN: lock->set_state(LOCK_TSYN_LOCK); break;
default: assert(0);
}
lock->get_parent()->auth_pin(lock);
if (lock->get_parent()->is_replicated()) {
send_lock_message(lock, LOCK_AC_LOCK);
lock->init_gather();
}
if (lock->get_num_client_lease())
revoke_client_leases(lock);
}
void Locker::scatter_tempsync(ScatterLock *lock)
{
@ -3155,60 +3114,6 @@ bool Locker::file_sync(FileLock *lock)
void Locker::file_lock(FileLock *lock)
{
CInode *in = (CInode*)lock->get_parent();
dout(7) << "file_lock " << *lock << " on " << *lock->get_parent() << dendl;
assert(in->is_auth());
assert(lock->is_stable());
// gather?
switch (lock->get_state()) {
case LOCK_SYNC: lock->set_state(LOCK_SYNC_LOCK); break;
case LOCK_MIX: lock->set_state(LOCK_MIX_LOCK); break;
case LOCK_EXCL: lock->set_state(LOCK_EXCL_LOCK); break;
default: assert(0);
}
int gather = 0;
if (in->is_replicated() &&
lock->get_state() != LOCK_EXCL_LOCK) { // (replicas are LOCK when auth is EXCL)
send_lock_message(lock, LOCK_AC_LOCK);
lock->init_gather();
gather++;
}
if (lock->get_num_client_lease()) {
revoke_client_leases(lock);
gather++;
}
int loner_issued, other_issued;
in->get_caps_issued(&loner_issued, &other_issued, CEPH_CAP_SFILE);
if ((loner_issued & ~lock->gcaps_allowed(true)) ||
(other_issued & ~lock->gcaps_allowed(false))) {
issue_caps(in);
gather++;
}
if (in->state_test(CInode::STATE_NEEDSRECOVER)) {
mds->mdcache->queue_file_recover(in);
mds->mdcache->do_file_recover();
gather++;
}
if (lock->is_updated()) {
scatter_writebehind(lock);
gather++;
}
if (gather)
lock->get_parent()->auth_pin(lock);
else {
lock->set_state(LOCK_LOCK);
in->loner_cap = -1;
lock->finish_waiters(FileLock::WAIT_XLOCK|FileLock::WAIT_WR|FileLock::WAIT_STABLE);
}
}
void Locker::file_mixed(FileLock *lock)
{
dout(7) << "file_mixed " << *lock << " on " << *lock->get_parent() << dendl;

View File

@ -26,8 +26,8 @@ public:
xlist<ScatterLock*>::item xlistitem_updated;
utime_t update_stamp;
ScatterLock(MDSCacheObject *o, int t, int ws, int cs) :
SimpleLock(o, t, ws, cs),
ScatterLock(MDSCacheObject *o, int t, int ws) :
SimpleLock(o, t, ws),
updated(false),
xlistitem_updated(this) {}
~ScatterLock() {

View File

@ -99,7 +99,6 @@ protected:
MDSCacheObject *parent;
int type;
int wait_shift;
int cap_shift;
// lock state
__s32 state;
@ -113,8 +112,8 @@ protected:
public:
SimpleLock(MDSCacheObject *o, int t, int ws, int cs) :
parent(o), type(t), wait_shift(ws), cap_shift(cs),
SimpleLock(MDSCacheObject *o, int t, int ws) :
parent(o), type(t), wait_shift(ws),
state(LOCK_SYNC), num_client_lease(0),
num_rdlock(0), num_wrlock(0), num_xlock(0),
xlock_by(0), xlock_by_client(-1) {
@ -143,7 +142,21 @@ public:
MDSCacheObject *get_parent() { return parent; }
int get_type() { return type; }
int get_cap_shift() { return cap_shift; }
int get_cap_shift() {
switch (type) {
case CEPH_LOCK_IAUTH: return CEPH_CAP_SAUTH;
case CEPH_LOCK_ILINK: return CEPH_CAP_SLINK;
case CEPH_LOCK_IFILE: return CEPH_CAP_SFILE;
case CEPH_LOCK_IXATTR: return CEPH_CAP_SXATTR;
default: return 0;
}
}
int get_cap_mask() {
switch (type) {
case CEPH_LOCK_IFILE: return 0xffff;
default: return 0x3;
}
}
struct ptr_lt {
bool operator()(const SimpleLock* l, const SimpleLock* r) const {
@ -374,13 +387,9 @@ public:
return sm->states[state].loner;
}
int gcaps_allowed_ever() {
if (!cap_shift)
return 0; // none for this lock.
return parent->is_auth() ? sm->allowed_ever_auth : sm->allowed_ever_replica;
}
int gcaps_allowed(bool loner, int s=-1) {
if (!cap_shift)
return 0;
if (s < 0) s = state;
if (parent->is_auth()) {
if (is_loner_mode() && !loner)