]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: add wrlock to simplelock; wrlock authlock on chmod, chown
authorSage Weil <sage@newdream.net>
Wed, 24 Dec 2008 22:18:45 +0000 (14:18 -0800)
committerSage Weil <sage@newdream.net>
Wed, 24 Dec 2008 22:19:30 +0000 (14:19 -0800)
src/mds/Locker.cc
src/mds/Locker.h
src/mds/ScatterLock.h
src/mds/Server.cc
src/mds/SimpleLock.h

index c2e70dabc98f946eea1631914c33d14b4fd26f57..8ad4f212c187c646741b74952f13d649befefc1b 100644 (file)
@@ -398,6 +398,8 @@ void Locker::rdlock_finish(SimpleLock *lock, Mutation *mut)
 bool Locker::wrlock_start(SimpleLock *lock, MDRequest *mut)
 {
   switch (lock->get_type()) {
+  case CEPH_LOCK_IAUTH:
+    return simple_wrlock_start((SimpleLock*)lock, mut);
   case CEPH_LOCK_IDFT:
   case CEPH_LOCK_INEST:
     return scatter_wrlock_start((ScatterLock*)lock, mut);
@@ -414,6 +416,8 @@ bool Locker::wrlock_start(SimpleLock *lock, MDRequest *mut)
 void Locker::wrlock_finish(SimpleLock *lock, Mutation *mut)
 {
   switch (lock->get_type()) {
+  case CEPH_LOCK_IAUTH:
+    return simple_wrlock_finish(lock, mut);
   case CEPH_LOCK_IDFT:
   case CEPH_LOCK_INEST:
     return scatter_wrlock_finish((ScatterLock*)lock, mut);
@@ -1662,7 +1666,8 @@ void Locker::simple_eval_gather(SimpleLock *lock)
       !lock->is_gathering() &&
       lock->get_num_client_lease() == 0 &&
       !lock->is_rdlocked()) {
-    dout(7) << "simple_eval finished gather on " << *lock << " on " << *lock->get_parent() << dendl;
+    dout(7) << "simple_eval finished gather on " << *lock
+           << " on " << *lock->get_parent() << dendl;
 
     // replica: tell auth
     if (!lock->get_parent()->is_auth()) {
@@ -1682,6 +1687,22 @@ void Locker::simple_eval_gather(SimpleLock *lock)
       simple_eval(lock);
     }
   }
+
+  else if (lock->get_state() == LOCK_LOCK_SYNC &&
+          !lock->is_gathering() &&
+          !lock->is_wrlocked()) {
+    dout(7) << "simple_eval finished gather on " << *lock 
+           << " on " << *lock->get_parent() << dendl;
+    assert(lock->get_parent()->is_auth());
+
+    lock->set_state(LOCK_SYNC);
+    lock->finish_waiters(SimpleLock::WAIT_STABLE|SimpleLock::WAIT_RD);
+
+    lock->get_parent()->auth_unpin(lock);
+
+    // re-eval?
+    simple_eval(lock);
+  }
 }
 
 void Locker::simple_eval(SimpleLock *lock)
@@ -1695,44 +1716,47 @@ void Locker::simple_eval(SimpleLock *lock)
 
   // stable -> sync?
   if (!lock->is_xlocked() &&
+      !lock->is_wrlocked() &&
       lock->get_state() != LOCK_SYNC &&
       !lock->is_waiter_for(SimpleLock::WAIT_WR)) {
     dout(7) << "simple_eval stable, syncing " << *lock 
            << " on " << *lock->get_parent() << dendl;
     simple_sync(lock);
   }
-  
 }
 
 
 // mid
 
-void Locker::simple_sync(SimpleLock *lock)
+bool Locker::simple_sync(SimpleLock *lock)
 {
   dout(7) << "simple_sync on " << *lock << " on " << *lock->get_parent() << dendl;
   assert(lock->get_parent()->is_auth());
   assert(lock->is_stable());
-  
-  // check state
-  if (lock->get_state() == LOCK_SYNC)
-    return; // already sync
+
   assert(lock->get_state() == LOCK_LOCK);
+  
+  lock->set_state(LOCK_LOCK_SYNC);
+
+  int gather = 0;
+  if (lock->is_wrlocked()) {
+    gather++;
+  }
+
+  if (gather) {
+    lock->get_parent()->auth_pin(lock);
+    return false;
+  }
 
-  // sync.
   if (lock->get_parent()->is_replicated()) {
-    // hard data
     bufferlist data;
     lock->encode_locked_state(data);
-    
-    // bcast to replicas
     send_lock_message(lock, LOCK_AC_SYNC, data);
   }
-  
-  // change lock
+
   lock->set_state(LOCK_SYNC);
-  
-  // waiters?
   lock->finish_waiters(SimpleLock::WAIT_RD|SimpleLock::WAIT_STABLE);
+  return true;
 }
 
 void Locker::simple_lock(SimpleLock *lock)
@@ -1784,20 +1808,72 @@ bool Locker::simple_rdlock_start(SimpleLock *lock, MDRequest *mut)
 {
   dout(7) << "simple_rdlock_start  on " << *lock << " on " << *lock->get_parent() << dendl;  
 
-  // can read?  grab ref.
-  if (lock->can_rdlock(mut)) {
-    lock->get_rdlock();
-    mut->rdlocks.insert(lock);
-    mut->locks.insert(lock);
-    return true;
+  while (1) {
+    // can read?  grab ref.
+    if (lock->can_rdlock(mut)) {
+      lock->get_rdlock();
+      mut->rdlocks.insert(lock);
+      mut->locks.insert(lock);
+      return true;
+    }
+    
+    if (lock->is_stable() &&
+       lock->get_parent()->is_auth())
+      simple_sync(lock);
+    else
+      break;
   }
-  
+
   // wait!
   dout(7) << "simple_rdlock_start waiting on " << *lock << " on " << *lock->get_parent() << dendl;
   lock->add_waiter(SimpleLock::WAIT_RD, new C_MDS_RetryRequest(mdcache, mut));
   return false;
 }
 
+bool Locker::simple_wrlock_start(SimpleLock *lock, MDRequest *mut)
+{
+  dout(7) << "simple_wrlock_start  on " << *lock
+         << " on " << *lock->get_parent() << dendl;  
+
+  while (1) {
+    // can wrlock?
+    if (lock->can_wrlock()) {
+      lock->get_wrlock();
+      if (mut) {
+       mut->wrlocks.insert(lock);
+       mut->locks.insert(lock);
+      }
+      return true;
+    }
+
+    if (lock->is_stable() && lock->get_state() == LOCK_SYNC)
+      simple_lock(lock);
+    else
+      break;
+  }
+
+  dout(7) << "simple_wrlock_start waiting on " << *lock << " on " << *lock->get_parent() << dendl;
+  lock->add_waiter(SimpleLock::WAIT_STABLE, new C_MDS_RetryRequest(mdcache, mut));
+  return false;
+}
+
+void Locker::simple_wrlock_finish(SimpleLock *lock, Mutation *mut)
+{
+  dout(7) << "simple_wrlock_finish on " << *lock << " on " << *lock->get_parent() << dendl;
+  lock->put_wrlock();
+  if (mut) {
+    mut->wrlocks.erase(lock);
+    mut->locks.erase(lock);
+  }
+
+  if (!lock->is_wrlocked()) {
+    if (!lock->is_stable())
+      simple_eval_gather(lock);
+    else if (lock->get_parent()->is_auth())
+      simple_eval(lock);
+  }
+}
+
 void Locker::simple_rdlock_finish(SimpleLock *lock, Mutation *mut)
 {
   // drop ref
@@ -3130,7 +3206,7 @@ bool Locker::file_wrlock_start(FileLock *lock, MDRequest *mut)
 
 void Locker::file_wrlock_finish(FileLock *lock, Mutation *mut)
 {
-  dout(7) << "wrlock_finish on " << *lock << " on " << *lock->get_parent() << dendl;
+  dout(7) << "file_wrlock_finish on " << *lock << " on " << *lock->get_parent() << dendl;
   lock->put_wrlock();
   if (mut) {
     mut->wrlocks.erase(lock);
index aa605576b86d5c9d9cda7f3e8a487cd5ce9ec8a4..5ba08c0785051ff23783997aac6fef575d8f34d3 100644 (file)
@@ -103,10 +103,12 @@ public:
 protected:
   void simple_eval(SimpleLock *lock);
   void handle_simple_lock(SimpleLock *lock, MLock *m);
-  void simple_sync(SimpleLock *lock);
+  bool simple_sync(SimpleLock *lock);
   void simple_lock(SimpleLock *lock);
   bool simple_rdlock_start(SimpleLock *lock, MDRequest *mut);
   void simple_rdlock_finish(SimpleLock *lock, Mutation *mut);
+  bool simple_wrlock_start(SimpleLock *lock, MDRequest *mut);
+  void simple_wrlock_finish(SimpleLock *lock, Mutation *mut);
   bool simple_xlock_start(SimpleLock *lock, MDRequest *mut);
   void simple_xlock_finish(SimpleLock *lock, Mutation *mut);
 
index 9f8197ea66f8324b94c8ce47f7a05372bffa95e4..a864ab318686c641399b17c9802cbdd67866b931 100644 (file)
@@ -27,7 +27,7 @@
 #define LOCK_SYNC_LOCK__       -20  // r .  r .  waiting for replicas+rdlocks (auth), or rdlocks to release (replica)
 #define LOCK_SYNC_SCATTER      -28  // r .  r .  
 
-#define LOCK_LOCK_SYNC         -29  // . w       LOCK on replica.
+#define LOCK_LOCK_SYNC_             // . w       LOCK on replica.
 #define LOCK_LOCK__                 // . W  . .
 #define LOCK_LOCK_TEMPSYNC     -21  // . w       LOCK on replica.
 
index b6553ebf72042ee4e637261c4c0a22d8da1616fe..010a1900472f48e0fc2f555dd704c36cf764515c 100644 (file)
@@ -1861,7 +1861,7 @@ void Server::handle_client_chmod(MDRequest *mdr)
   set<SimpleLock*> rdlocks = mdr->rdlocks;
   set<SimpleLock*> wrlocks = mdr->wrlocks;
   set<SimpleLock*> xlocks = mdr->xlocks;
-  xlocks.insert(&cur->authlock);
+  wrlocks.insert(&cur->authlock);
   mds->locker->include_snap_rdlocks(rdlocks, cur);
 
   if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
@@ -1906,7 +1906,7 @@ void Server::handle_client_chown(MDRequest *mdr)
   set<SimpleLock*> rdlocks = mdr->rdlocks;
   set<SimpleLock*> wrlocks = mdr->wrlocks;
   set<SimpleLock*> xlocks = mdr->xlocks;
-  xlocks.insert(&cur->authlock);
+  wrlocks.insert(&cur->authlock);
   mds->locker->include_snap_rdlocks(rdlocks, cur);
 
   if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
index 402de351bc4b5bc9f1482c8ace8ddc37d38259c9..913420194ac6b82a520956b736f7a0183243ef5f 100644 (file)
@@ -39,10 +39,11 @@ inline const char *get_lock_type_name(int t) {
 // sync <-> lock
 #define LOCK_UNDEF    0
 //                               auth   rep
-#define LOCK_SYNC     1  // AR   R .    R .
-#define LOCK_LOCK     2  // AR   R W    . .
-#define LOCK_SYNC_LOCK  -3  // AR   R .    . .
-#define LOCK_REMOTEXLOCK  -50    // on NON-auth
+#define LOCK_SYNC        1     // AR   R .    R .
+#define LOCK_LOCK        2     // AR   R W    . .
+#define LOCK_SYNC_LOCK  -3     // AR   R .    . .
+#define LOCK_LOCK_SYNC  -51    // A    R w
+#define LOCK_REMOTEXLOCK  -50  // on NON-auth
 
 inline const char *get_simplelock_state_name(int n) {
   switch (n) {
@@ -50,6 +51,7 @@ inline const char *get_simplelock_state_name(int n) {
   case LOCK_SYNC: return "sync";
   case LOCK_LOCK: return "lock";
   case LOCK_SYNC_LOCK: return "sync->lock";
+  case LOCK_LOCK_SYNC: return "lock->sync";
   case LOCK_REMOTEXLOCK: return "remote_xlock";
   default: assert(0); return 0;
   }
@@ -204,7 +206,9 @@ public:
   int get_num_rdlocks() { return num_rdlock; }
 
   // wrlock
-  virtual bool can_wrlock() { return false; }
+  virtual bool can_wrlock() {
+    return state == LOCK_LOCK;
+  }
   void get_wrlock(bool force=false) {
     assert(can_wrlock() || force);
     if (num_wrlock == 0) parent->get(MDSCacheObject::PIN_LOCK);