]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: create abstract LockType that includes numeric type and state machine
authorSage Weil <sage@newdream.net>
Thu, 11 Mar 2010 17:30:10 +0000 (09:30 -0800)
committerSage Weil <sage@newdream.net>
Thu, 11 Mar 2010 17:30:10 +0000 (09:30 -0800)
This eliminates 1 field in each SimpleLock.

src/mds/CDentry.cc
src/mds/CDentry.h
src/mds/CInode.cc
src/mds/CInode.h
src/mds/LocalLock.h
src/mds/Locker.cc
src/mds/ScatterLock.h
src/mds/SimpleLock.h

index d9ce1e799ab49c29bc5de60e79c282584ad74918..5bd8396b9121e281273e1b1573168ab1c8030375 100644 (file)
@@ -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
 
index 194b20ef3a987c214a9c860de70bf7c606d6917a..0ae7d8cb1935daddfec43dbd26f66fdf118602a8 100644 (file)
@@ -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;
index d80504c2a371b0f13600453be6fa6d4dd6734202..d44fe9e7d0a677190fb44018149a0cd037bdc094 100644 (file)
 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)
index 62970faf537445d2c74732536a2a1bd24551b1dc..48a77f04417c6d394381e4f991c8125ad6a9c666 100644 (file)
@@ -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;
index ad21e42da1ca548acdeb1cb07e33f6ad569c2254..933f5b6d2256b31e26a3c7cf6cccc81f50288254 100644 (file)
@@ -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.
   }
index 01bd0f6b04fe0459b34b0614969aa2adaddb4137..a579a75edaa4b22b79eeb1f965587e5ded7834f4 100644 (file)
@@ -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++;
index b8804265e6a27c4e53e0a3ff8bab13807536a872..de24c8f31c50e973176a76a10f2433414b15e5a9 100644 (file)
@@ -27,8 +27,8 @@ public:
   xlist<ScatterLock*>::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());
       }
     }
   }
index 482841945b0635b6bf6841283447893add0871b4..ec3b8b64dcbae81402482d8fed52d6f2d11e3999 100644 (file)
@@ -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<<WAIT_BITS)-1);
 
 
-  sm_t *sm;
-
 protected:
   // parent (what i lock)
   MDSCacheObject *parent;
-  int type;
-
-  int get_wait_shift() {
-    switch (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);
-    }
-  }
 
   // lock state
   __s32 state;
@@ -142,38 +151,38 @@ public:
 
 
 public:
-  SimpleLock(MDSCacheObject *o, int t) :
-    parent(o), type(t),
+  SimpleLock(MDSCacheObject *o, LockType *lt) :
+    type(lt),
+    parent(o), 
     state(LOCK_SYNC), num_client_lease(0),
     num_rdlock(0), num_wrlock(0), num_xlock(0),
     xlock_by(0), xlock_by_client(-1), excl_client(-1) {
-    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;
-    }
   }
   virtual ~SimpleLock() {}
 
   // parent
   MDSCacheObject *get_parent() { return parent; }
-  int get_type() { return type; }
+  int get_type() { return type->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();