From 7f0791c2e27ec59ac30315c7bdf4712faa68e94a Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 11 Mar 2010 09:30:10 -0800 Subject: [PATCH] mds: create abstract LockType that includes numeric type and state machine This eliminates 1 field in each SimpleLock. --- src/mds/CDentry.cc | 2 + src/mds/CDentry.h | 6 +- src/mds/CInode.cc | 8 +++ src/mds/CInode.h | 25 ++++--- src/mds/LocalLock.h | 2 +- src/mds/Locker.cc | 20 +++--- src/mds/ScatterLock.h | 6 +- src/mds/SimpleLock.h | 163 ++++++++++++++++++++++-------------------- 8 files changed, 131 insertions(+), 101 deletions(-) diff --git a/src/mds/CDentry.cc b/src/mds/CDentry.cc index d9ce1e799ab49..5bd8396b9121e 100644 --- a/src/mds/CDentry.cc +++ b/src/mds/CDentry.cc @@ -38,6 +38,8 @@ ostream& CDentry::print_db_line_prefix(ostream& out) boost::pool<> CDentry::pool(sizeof(CDentry)); +LockType CDentry::lock_type(CEPH_LOCK_DN); + // CDentry diff --git a/src/mds/CDentry.h b/src/mds/CDentry.h index 194b20ef3a987..0ae7d8cb1935d 100644 --- a/src/mds/CDentry.h +++ b/src/mds/CDentry.h @@ -149,6 +149,8 @@ protected: public: // lock + static LockType lock_type; + SimpleLock lock; public: @@ -161,7 +163,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) { + lock(this, &lock_type) { g_num_dn++; g_num_dna++; } @@ -173,7 +175,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) { + lock(this, &lock_type) { g_num_dn++; g_num_dna++; linkage.remote_ino = ino; diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index d80504c2a371b..d44fe9e7d0a67 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -46,6 +46,14 @@ boost::pool<> CInode::pool(sizeof(CInode)); boost::pool<> Capability::pool(sizeof(Capability)); +LockType CInode::versionlock_type(CEPH_LOCK_IVERSION); +LockType CInode::authlock_type(CEPH_LOCK_IAUTH); +LockType CInode::linklock_type(CEPH_LOCK_ILINK); +LockType CInode::dirfragtreelock_type(CEPH_LOCK_IDFT); +LockType CInode::filelock_type(CEPH_LOCK_IFILE); +LockType CInode::xattrlock_type(CEPH_LOCK_IXATTR); +LockType CInode::snaplock_type(CEPH_LOCK_ISNAP); +LockType CInode::nestlock_type(CEPH_LOCK_INEST); //int cinode_pins[CINODE_NUM_PINS]; // counts ostream& CInode::print_db_line_prefix(ostream& out) diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 62970faf53744..48a77f04417c6 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -320,14 +320,14 @@ private: xlist_dirty_dirfrag_dirfragtree(this), auth_pins(0), nested_auth_pins(0), nested_anchors(0), - versionlock(this, CEPH_LOCK_IVERSION), - authlock(this, CEPH_LOCK_IAUTH), - linklock(this, CEPH_LOCK_ILINK), - dirfragtreelock(this, CEPH_LOCK_IDFT), - filelock(this, CEPH_LOCK_IFILE), - xattrlock(this, CEPH_LOCK_IXATTR), - snaplock(this, CEPH_LOCK_ISNAP), - nestlock(this, CEPH_LOCK_INEST), + versionlock(this, &versionlock_type), + authlock(this, &authlock_type), + linklock(this, &linklock_type), + dirfragtreelock(this, &dirfragtreelock_type), + filelock(this, &filelock_type), + xattrlock(this, &xattrlock_type), + snaplock(this, &snaplock_type), + nestlock(this, &nestlock_type), loner_cap(-1), want_loner_cap(-1) { g_num_ino++; @@ -488,6 +488,15 @@ private: // -- locks -- public: + static LockType versionlock_type; + static LockType authlock_type; + static LockType linklock_type; + static LockType dirfragtreelock_type; + static LockType filelock_type; + static LockType xattrlock_type; + static LockType snaplock_type; + static LockType nestlock_type; + LocalLock versionlock; SimpleLock authlock; SimpleLock linklock; diff --git a/src/mds/LocalLock.h b/src/mds/LocalLock.h index ad21e42da1ca5..933f5b6d2256b 100644 --- a/src/mds/LocalLock.h +++ b/src/mds/LocalLock.h @@ -22,7 +22,7 @@ class LocalLock : public SimpleLock { public: client_t last_wrlock_client; - LocalLock(MDSCacheObject *o, int t) : + LocalLock(MDSCacheObject *o, LockType *t) : SimpleLock(o, t) { set_state(LOCK_LOCK); // always. } diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 01bd0f6b04fe0..a579a75edaa4b 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -413,17 +413,17 @@ void Locker::eval_gather(SimpleLock *lock, bool first, bool *pneed_issue) } if (!lock->is_gathering() && - (lock->sm->states[next].can_rdlock || !lock->is_rdlocked()) && - (lock->sm->states[next].can_wrlock || !lock->is_wrlocked()) && - (lock->sm->states[next].can_xlock || !lock->is_xlocked()) && - (lock->sm->states[next].can_lease || !lock->is_leased()) && + (lock->get_sm()->states[next].can_rdlock || !lock->is_rdlocked()) && + (lock->get_sm()->states[next].can_wrlock || !lock->is_wrlocked()) && + (lock->get_sm()->states[next].can_xlock || !lock->is_xlocked()) && + (lock->get_sm()->states[next].can_lease || !lock->is_leased()) && (!caps || ((~lock->gcaps_allowed(CAP_ANY, next) & other_issued) == 0 && (~lock->gcaps_allowed(CAP_LONER, next) & loner_issued) == 0 && (~lock->gcaps_allowed(CAP_XLOCKER, next) & xlocker_issued) == 0))) { dout(7) << "eval_gather finished gather on " << *lock << " on " << *lock->get_parent() << dendl; - if (lock->sm == &sm_filelock) { + if (lock->get_sm() == &sm_filelock) { if (in->state_test(CInode::STATE_NEEDSRECOVER)) { dout(7) << "eval_gather finished gather, but need to recover" << dendl; mds->mdcache->queue_file_recover(in); @@ -678,7 +678,7 @@ bool Locker::_rdlock_kick(SimpleLock *lock) // kick the lock if (lock->is_stable() && lock->get_parent()->is_auth()) { - if (lock->sm == &sm_scatterlock) { + if (lock->get_sm() == &sm_scatterlock) { if (lock->get_parent()->is_replicated()) scatter_tempsync((ScatterLock*)lock); else @@ -905,7 +905,7 @@ bool Locker::xlock_start(SimpleLock *lock, MDRequest *mut) return false; } else { // replica - assert(lock->sm->can_remote_xlock); + assert(lock->get_sm()->can_remote_xlock); assert(!mut->slave_request); // wait for single auth @@ -946,7 +946,7 @@ void Locker::xlock_finish(SimpleLock *lock, Mutation *mut) // remote xlock? if (!lock->get_parent()->is_auth()) { - assert(lock->sm->can_remote_xlock); + assert(lock->get_sm()->can_remote_xlock); // tell auth dout(7) << "xlock_finish releasing remote xlock on " << *lock->get_parent() << dendl; @@ -2682,7 +2682,7 @@ void Locker::simple_lock(SimpleLock *lock, bool *need_issue) int gather = 0; if (lock->get_parent()->is_replicated() && - lock->sm->states[old_state].replica_state != LOCK_LOCK) { // replica may already be LOCK + lock->get_sm()->states[old_state].replica_state != LOCK_LOCK) { // replica may already be LOCK gather++; send_lock_message(lock, LOCK_AC_LOCK); lock->init_gather(); @@ -3394,7 +3394,7 @@ void Locker::file_recover(ScatterLock *lock) int gather = 0; if (in->is_replicated() && - lock->sm->states[oldstate].replica_state != LOCK_LOCK) { + lock->get_sm()->states[oldstate].replica_state != LOCK_LOCK) { send_lock_message(lock, LOCK_AC_LOCK); lock->init_gather(); gather++; diff --git a/src/mds/ScatterLock.h b/src/mds/ScatterLock.h index b8804265e6a27..de24c8f31c50e 100644 --- a/src/mds/ScatterLock.h +++ b/src/mds/ScatterLock.h @@ -27,8 +27,8 @@ public: xlist::item xlistitem_updated; utime_t update_stamp; - ScatterLock(MDSCacheObject *o, int t) : - SimpleLock(o, t), + ScatterLock(MDSCacheObject *o, LockType *lt) : + SimpleLock(o, lt), dirty(false), flushing(false), scatter_wanted(false), xlistitem_updated(this) {} ~ScatterLock() { @@ -58,7 +58,7 @@ public: flushing = false; if (!dirty) { parent->put(MDSCacheObject::PIN_DIRTYSCATTERED); - parent->clear_dirty_scattered(type); + parent->clear_dirty_scattered(get_type()); } } } diff --git a/src/mds/SimpleLock.h b/src/mds/SimpleLock.h index 482841945b063..ec3b8b64dcbae 100644 --- a/src/mds/SimpleLock.h +++ b/src/mds/SimpleLock.h @@ -46,9 +46,37 @@ extern "C" { #define CAP_LONER 1 #define CAP_XLOCKER 2 +struct LockType { + int type; + sm_t *sm; + + LockType(int t) : type(t) { + switch (type) { + case CEPH_LOCK_DN: + case CEPH_LOCK_IAUTH: + case CEPH_LOCK_ILINK: + case CEPH_LOCK_IXATTR: + case CEPH_LOCK_ISNAP: + sm = &sm_simplelock; + break; + case CEPH_LOCK_IDFT: + case CEPH_LOCK_INEST: + sm = &sm_scatterlock; + break; + case CEPH_LOCK_IFILE: + sm = &sm_filelock; + break; + default: + sm = 0; + } + } + +}; + class SimpleLock { public: + LockType *type; virtual const char *get_state_name(int n) { switch (n) { @@ -105,28 +133,9 @@ public: static const __u64 WAIT_ALL = ((1<type; } + const sm_t* get_sm() const { return type->sm; } + + int get_wait_shift() { + switch (get_type()) { + case CEPH_LOCK_DN: return 8; + case CEPH_LOCK_IAUTH: return 5 + SimpleLock::WAIT_BITS; + case CEPH_LOCK_ILINK: return 5 + SimpleLock::WAIT_BITS; + case CEPH_LOCK_IDFT: return 5 + 2*SimpleLock::WAIT_BITS; + case CEPH_LOCK_IFILE: return 5 + 3*SimpleLock::WAIT_BITS; + case CEPH_LOCK_IVERSION: return 5 + 4*SimpleLock::WAIT_BITS; + case CEPH_LOCK_IXATTR: return 5 + 5*SimpleLock::WAIT_BITS; + case CEPH_LOCK_ISNAP: return 5 + 6*SimpleLock::WAIT_BITS; + case CEPH_LOCK_INEST: return 5 + 7*SimpleLock::WAIT_BITS; + default: + assert(0); + } + } int get_cap_shift() { - switch (type) { + switch (get_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; @@ -182,7 +191,7 @@ public: } } int get_cap_mask() { - switch (type) { + switch (get_type()) { case CEPH_LOCK_IFILE: return 0xffff; default: return 0x3; } @@ -191,13 +200,13 @@ public: struct ptr_lt { bool operator()(const SimpleLock* l, const SimpleLock* r) const { // first sort by object type (dn < inode) - if ((l->type>CEPH_LOCK_DN) < (r->type>CEPH_LOCK_DN)) return true; - if ((l->type>CEPH_LOCK_DN) == (r->type>CEPH_LOCK_DN)) { + if ((l->type->type>CEPH_LOCK_DN) < (r->type->type>CEPH_LOCK_DN)) return true; + if ((l->type->type>CEPH_LOCK_DN) == (r->type->type>CEPH_LOCK_DN)) { // then sort by object if (l->parent->is_lt(r->parent)) return true; if (l->parent == r->parent) { // then sort by (inode) lock type - if (l->type < r->type) return true; + if (l->type->type < r->type->type) return true; } } return false; @@ -205,10 +214,10 @@ public: }; void decode_locked_state(bufferlist& bl) { - parent->decode_lock_state(type, bl); + parent->decode_lock_state(type->type, bl); } void encode_locked_state(bufferlist& bl) { - parent->encode_lock_state(type, bl); + parent->encode_lock_state(type->type, bl); } void finish_waiters(__u64 mask, int r=0) { parent->finish_waiting(mask << get_wait_shift(), r); @@ -243,14 +252,14 @@ public: } bool is_stable() { - return !sm || sm->states[state].next == 0; + return !get_sm() || get_sm()->states[state].next == 0; } int get_next_state() { - return sm->states[state].next; + return get_sm()->states[state].next; } bool fw_rdlock_to_auth() { - return sm->states[state].can_rdlock == FW; + return get_sm()->states[state].can_rdlock == FW; } // gather set @@ -279,35 +288,35 @@ public: // can_* bool can_lease(client_t client) { - return sm->states[state].can_lease == ANY || - (sm->states[state].can_lease == AUTH && parent->is_auth()) || - (sm->states[state].can_lease == XCL && client >= 0 && xlock_by_client == client); + return get_sm()->states[state].can_lease == ANY || + (get_sm()->states[state].can_lease == AUTH && parent->is_auth()) || + (get_sm()->states[state].can_lease == XCL && client >= 0 && xlock_by_client == client); } bool can_read(client_t client) { - return sm->states[state].can_read == ANY || - (sm->states[state].can_read == AUTH && parent->is_auth()) || - (sm->states[state].can_read == XCL && client >= 0 && xlock_by_client == client); + return get_sm()->states[state].can_read == ANY || + (get_sm()->states[state].can_read == AUTH && parent->is_auth()) || + (get_sm()->states[state].can_read == XCL && client >= 0 && xlock_by_client == client); } bool can_read_projected(client_t client) { - return sm->states[state].can_read_projected == ANY || - (sm->states[state].can_read_projected == AUTH && parent->is_auth()) || - (sm->states[state].can_read_projected == XCL && client >= 0 && xlock_by_client == client); + return get_sm()->states[state].can_read_projected == ANY || + (get_sm()->states[state].can_read_projected == AUTH && parent->is_auth()) || + (get_sm()->states[state].can_read_projected == XCL && client >= 0 && xlock_by_client == client); } bool can_rdlock(client_t client) { - return sm->states[state].can_rdlock == ANY || - (sm->states[state].can_rdlock == AUTH && parent->is_auth()) || - (sm->states[state].can_rdlock == XCL && client >= 0 && xlock_by_client == client); + return get_sm()->states[state].can_rdlock == ANY || + (get_sm()->states[state].can_rdlock == AUTH && parent->is_auth()) || + (get_sm()->states[state].can_rdlock == XCL && client >= 0 && xlock_by_client == client); } bool can_wrlock(client_t client) { - return sm->states[state].can_wrlock == ANY || - (sm->states[state].can_wrlock == AUTH && parent->is_auth()) || - (sm->states[state].can_wrlock == XCL && client >= 0 && (xlock_by_client == client || + return get_sm()->states[state].can_wrlock == ANY || + (get_sm()->states[state].can_wrlock == AUTH && parent->is_auth()) || + (get_sm()->states[state].can_wrlock == XCL && client >= 0 && (xlock_by_client == client || excl_client == client)); } bool can_xlock(client_t client) { - return sm->states[state].can_xlock == ANY || - (sm->states[state].can_xlock == AUTH && parent->is_auth()) || - (sm->states[state].can_xlock == XCL && client >= 0 && xlock_by_client == client); + return get_sm()->states[state].can_xlock == ANY || + (get_sm()->states[state].can_xlock == AUTH && parent->is_auth()) || + (get_sm()->states[state].can_xlock == XCL && client >= 0 && xlock_by_client == client); } // rdlock @@ -419,39 +428,39 @@ public: // caps bool is_loner_mode() { - return sm->states[state].loner; + return get_sm()->states[state].loner; } int gcaps_allowed_ever() { - return parent->is_auth() ? sm->allowed_ever_auth : sm->allowed_ever_replica; + return parent->is_auth() ? get_sm()->allowed_ever_auth : get_sm()->allowed_ever_replica; } int gcaps_allowed(int who, int s=-1) { if (s < 0) s = state; if (parent->is_auth()) { if (xlock_by_client >= 0 && who == CAP_XLOCKER) - return sm->states[s].xlocker_caps; + return get_sm()->states[s].xlocker_caps; else if (is_loner_mode() && who == CAP_ANY) - return sm->states[s].caps; + return get_sm()->states[s].caps; else - return sm->states[s].loner_caps | sm->states[s].caps; // loner always gets more + return get_sm()->states[s].loner_caps | get_sm()->states[s].caps; // loner always gets more } else - return sm->states[s].replica_caps; + return get_sm()->states[s].replica_caps; } int gcaps_careful() { if (num_wrlock) - return sm->careful; + return get_sm()->careful; return 0; } int gcaps_xlocker_mask(client_t client) { if (client == xlock_by_client) - return type == CEPH_LOCK_IFILE ? 0xffff : (CEPH_CAP_GSHARED|CEPH_CAP_GEXCL); + return type->type == CEPH_LOCK_IFILE ? 0xffff : (CEPH_CAP_GSHARED|CEPH_CAP_GEXCL); return 0; } // simplelock specifics int get_replica_state() const { - return sm->states[state].replica_state; + return get_sm()->states[state].replica_state; } void export_twiddle() { clear_gather(); -- 2.39.5