mirror of
https://github.com/ceph/ceph
synced 2025-01-18 09:02:08 +00:00
mds: more lock refactoring. merge *_lock() methods.
This commit is contained in:
parent
7a9a689daa
commit
0a20684698
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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.
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user