]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: make eval take a mask; kill try_*_eval
authorSage Weil <sage@newdream.net>
Wed, 29 Apr 2009 23:27:24 +0000 (16:27 -0700)
committerSage Weil <sage@newdream.net>
Fri, 1 May 2009 14:38:08 +0000 (07:38 -0700)
This will eventually help us deal with all locks as a group.

Also, simplify the eval_subtree_root bits.

src/include/ceph_fs.h
src/mds/Locker.cc
src/mds/Locker.h
src/mds/MDCache.cc

index 122c9b01770cc96ef42c90b235da4f2d32f18d44..c2e0195f3b2cd75e5b481cba425adab107223329 100644 (file)
@@ -963,7 +963,7 @@ static inline int ceph_flags_to_mode(int flags)
 #define CEPH_CAP_FILE_WREXTEND (CEPH_CAP_GWREXTEND << CEPH_CAP_SFILE)
 #define CEPH_CAP_FILE_LAZYIO   (CEPH_CAP_GLAZYIO   << CEPH_CAP_SFILE)
 
-/* cap masks (for stat/getattr) */
+/* cap masks (for getattr) */
 #define CEPH_STAT_CAP_INODE    CEPH_CAP_PIN
 #define CEPH_STAT_CAP_TYPE     CEPH_CAP_PIN  /* mode >> 12 */
 #define CEPH_STAT_CAP_SYMLINK  CEPH_CAP_PIN
@@ -996,6 +996,8 @@ static inline int ceph_flags_to_mode(int flags)
 #define CEPH_CAP_ANY_WR   (CEPH_CAP_ANY_EXCL | CEPH_CAP_ANY_FILE_WR)
 #define CEPH_CAP_ANY      (CEPH_CAP_ANY_RD|CEPH_CAP_ANY_EXCL|CEPH_CAP_ANY_FILE_WR|CEPH_CAP_PIN)
 
+#define CEPH_CAP_LOCKS (CEPH_LOCK_IFILE|CEPH_LOCK_IAUTH|CEPH_LOCK_ILINK|CEPH_LOCK_IXATTR)
+
 /*
  * these cap bits time out, if no others are held and nothing is
  * registered as 'wanted' by the client.
index 3f9a81d566dd9e22037069b64c55c890c47ede6b..ad50fbd6da35ae15b53be7609b4c2c94835eee2d 100644 (file)
@@ -541,11 +541,11 @@ void Locker::eval_gather(SimpleLock *lock, bool first, bool *need_issue)
   }
 }
 
-bool Locker::eval_caps(CInode *in)
+bool Locker::eval(CInode *in, int mask)
 {
   bool need_issue = false;
   
-  dout(10) << "eval_caps " << *in << dendl;
+  dout(10) << "eval " << mask << " " << *in << dendl;
 
   // choose loner?
   if (in->is_auth() && in->get_loner() < 0) {
@@ -556,25 +556,20 @@ bool Locker::eval_caps(CInode *in)
        in->try_choose_loner()) {
       dout(10) << "  chose loner client" << in->get_loner() << dendl;
       need_issue = true;
+      mask = -1;
     }
   }
 
-  if (!in->filelock.is_stable())
-    eval_gather(&in->filelock, false, &need_issue);
-  else if (in->is_auth())
-    eval(&in->filelock, &need_issue);
-  if (!in->authlock.is_stable())
-    eval_gather(&in->authlock, false, &need_issue);
-  else if (in->is_auth())
-    eval(&in->authlock, &need_issue);
-  if (!in->linklock.is_stable())
-    eval_gather(&in->linklock, false, &need_issue);
-  else if (in->is_auth())
-    eval(&in->linklock, &need_issue);
-  if (!in->xattrlock.is_stable())
-    eval_gather(&in->xattrlock, false, &need_issue);
-  else if (in->is_auth())
-    eval(&in->xattrlock, &need_issue);
+  if (mask & CEPH_LOCK_IFILE)
+    eval_any(&in->filelock, &need_issue);
+  if (mask & CEPH_LOCK_IAUTH)
+    eval_any(&in->authlock, &need_issue);
+  if (mask & CEPH_LOCK_ILINK)
+    eval_any(&in->linklock, &need_issue);
+  if (mask & CEPH_LOCK_IXATTR)
+    eval_any(&in->xattrlock, &need_issue);
+  if (mask & CEPH_LOCK_INEST)
+    eval_any(&in->nestlock, &need_issue);
 
   // drop loner?
   if (in->is_auth() && in->get_loner() >= 0) {
@@ -588,10 +583,47 @@ bool Locker::eval_caps(CInode *in)
   if (need_issue)
     issue_caps(in);
 
-  dout(10) << "eval_caps done" << dendl;
+  dout(10) << "eval done" << dendl;
   return need_issue;
 }
 
+class C_Locker_Eval : public Context {
+  Locker *locker;
+  CInode *in;
+  int mask;
+public:
+  C_Locker_Eval(Locker *l, CInode *i, int m) : locker(l), in(in), mask(m) {
+    in->get(CInode::PIN_PTRWAITER);    
+  }
+  void finish(int r) {
+    in->put(CInode::PIN_PTRWAITER);
+    locker->try_eval(in, mask);
+  }
+};
+
+void Locker::try_eval(CInode *in, int mask)
+{
+  // unstable and ambiguous auth?
+  if (in->is_ambiguous_auth()) {
+    dout(7) << "try_eval not ambiguous auth, waiting on " << *in << dendl;
+    in->add_waiter(CInode::WAIT_SINGLEAUTH, new C_Locker_Eval(this, in, mask));
+    return;
+  }
+
+  if (!in->is_auth()) {
+    dout(7) << "try_eval not auth for " << *in << dendl;
+    return;
+  }
+
+  if (!in->can_auth_pin()) {
+    dout(7) << "try_eval can't auth_pin, waiting on " << *in << dendl;
+    in->add_waiter(CInode::WAIT_UNFREEZE, new C_Locker_Eval(this, in, mask));
+    return;
+  }
+
+  eval(in, mask);
+}
+
 void Locker::eval_cap_gather(CInode *in)
 {
   bool need_issue = false;
@@ -1035,7 +1067,7 @@ Capability* Locker::issue_new_caps(CInode *in,
 
   if (in->is_auth()) {
     // [auth] twiddle mode?
-    eval_caps(in);
+    eval(in, CEPH_CAP_LOCKS);
 
     if (!in->filelock.is_stable() ||
        !in->authlock.is_stable() ||
@@ -1235,7 +1267,7 @@ void Locker::resume_stale_caps(Session *session)
     if (cap->is_stale()) {
       dout(10) << " clearing stale flag on " << *in << dendl;
       cap->set_stale(false);
-      if (!in->is_auth() || !eval_caps(in))
+      if (!in->is_auth() || !eval(in, CEPH_CAP_LOCKS))
        issue_caps(in, cap);
     }
   }
@@ -1352,8 +1384,7 @@ void Locker::handle_inode_file_caps(MInodeFileCaps *m)
   else
     in->mds_caps_wanted.erase(m->get_from());
 
-  if (in->filelock.is_stable())
-    try_file_eval(&in->filelock);  // ** may or may not be auth_pinned **
+  try_eval(in, CEPH_CAP_LOCKS);
   delete m;
 }
 
@@ -1660,7 +1691,7 @@ void Locker::handle_client_caps(MClientCaps *m)
       if (_do_cap_update(in, cap, m->get_dirty(), cap->wanted(), follows, m, ack)) {
        // updated, cap msg is delayed
        cap->inc_suppress();
-       eval_caps(in);
+       eval(in, CEPH_CAP_LOCKS);
        cap->dec_suppress();
 
        if (cap->wanted() & ~cap->pending())
@@ -1670,7 +1701,7 @@ void Locker::handle_client_caps(MClientCaps *m)
        if (ack)
          mds->send_message_client(ack, client);
       
-       bool did_issue = eval_caps(in);
+       bool did_issue = eval(in, CEPH_CAP_LOCKS);
        if (!did_issue && (cap->wanted() & ~cap->pending()))
          issue_caps(in, cap);
       }
@@ -1710,7 +1741,7 @@ void Locker::process_cap_update(int client, inodeno_t ino, __u64 cap_id, int cap
     adjust_cap_wanted(cap, wanted, issue_seq);
 
     cap->inc_suppress();
-    eval_caps(in);
+    eval(in, CEPH_CAP_LOCKS);
     cap->dec_suppress();
   }
   
@@ -2670,54 +2701,6 @@ void Locker::dentry_anon_rdlock_trace_finish(vector<CDentry*>& trace)
 // ==========================================================================
 // scatter lock
 
-
-class C_Locker_ScatterEval : public Context {
-  Locker *locker;
-  ScatterLock *lock;
-public:
-  C_Locker_ScatterEval(Locker *l, ScatterLock *lk) : locker(l), lock(lk) {
-    lock->get_parent()->get(CInode::PIN_PTRWAITER);
-  }
-  void finish(int r) {
-    lock->get_parent()->put(CInode::PIN_PTRWAITER);
-    locker->try_scatter_eval(lock);
-  }
-};
-
-
-void Locker::try_scatter_eval(ScatterLock *lock)
-{
-  // unstable and ambiguous auth?
-  if (!lock->is_stable() &&
-      lock->get_parent()->is_ambiguous_auth()) {
-    dout(7) << "try_scatter_eval not stable and ambiguous auth, waiting on " << *lock->get_parent() << dendl;
-    //if (!lock->get_parent()->is_waiter(MDSCacheObject::WAIT_SINGLEAUTH))
-    lock->get_parent()->add_waiter(MDSCacheObject::WAIT_SINGLEAUTH, new C_Locker_ScatterEval(this, lock));
-    return;
-  }
-
-  if (!lock->get_parent()->is_auth()) {
-    dout(7) << "try_scatter_eval not auth for " << *lock->get_parent() << dendl;
-    return;
-  }
-
-  if (!lock->get_parent()->can_auth_pin()) {
-    dout(7) << "try_scatter_eval can't auth_pin, waiting on " << *lock->get_parent() << dendl;
-    //if (!lock->get_parent()->is_waiter(MDSCacheObject::WAIT_SINGLEAUTH))
-    lock->get_parent()->add_waiter(MDSCacheObject::WAIT_UNFREEZE, new C_Locker_ScatterEval(this, lock));
-    return;
-  }
-
-  if (lock->is_stable()) {
-    bool need_issue = false;
-    scatter_eval(lock, &need_issue);
-    if (need_issue)
-      issue_caps((CInode*)lock->get_parent());
-  }
-}
-
-
-
 void Locker::scatter_writebehind(ScatterLock *lock)
 {
   CInode *in = (CInode*)lock->get_parent();
@@ -3049,61 +3032,6 @@ void Locker::local_xlock_finish(LocalLock *lock, Mutation *mut)
 // ==========================================================================
 // file lock
 
-/*
- * ...
- *
- * also called after client caps are acked to us
- * - checks if we're in unstable sfot state and can now move on to next state
- * - checks if soft state should change (eg bc last writer closed)
- */
-class C_Locker_FileEval : public Context {
-  Locker *locker;
-  ScatterLock *lock;
-public:
-  C_Locker_FileEval(Locker *l, ScatterLock *lk) : locker(l), lock(lk) {
-    lock->get_parent()->get(CInode::PIN_PTRWAITER);    
-  }
-  void finish(int r) {
-    lock->get_parent()->put(CInode::PIN_PTRWAITER);
-    locker->try_file_eval(lock);
-  }
-};
-
-void Locker::try_file_eval(ScatterLock *lock)
-{
-  CInode *in = (CInode*)lock->get_parent();
-
-  // unstable and ambiguous auth?
-  if (!lock->is_stable() &&
-      in->is_ambiguous_auth()) {
-    dout(7) << "try_file_eval not stable and ambiguous auth, waiting on " << *in << dendl;
-    //if (!lock->get_parent()->is_waiter(MDSCacheObject::WAIT_SINGLEAUTH))
-    in->add_waiter(CInode::WAIT_SINGLEAUTH, new C_Locker_FileEval(this, lock));
-    return;
-  }
-
-  if (!lock->get_parent()->is_auth()) {
-    dout(7) << "try_file_eval not auth for " << *lock->get_parent() << dendl;
-    return;
-  }
-
-  if (!lock->get_parent()->can_auth_pin()) {
-    dout(7) << "try_file_eval can't auth_pin, waiting on " << *in << dendl;
-    //if (!lock->get_parent()->is_waiter(MDSCacheObject::WAIT_SINGLEAUTH))
-    in->add_waiter(CInode::WAIT_UNFREEZE, new C_Locker_FileEval(this, lock));
-    return;
-  }
-
-  if (lock->is_stable()) {
-    bool need_issue = false;
-    file_eval(lock, &need_issue);
-    if (need_issue)
-      issue_caps((CInode*)lock->get_parent());
-  }
-}
-
-
-
 
 void Locker::file_eval(ScatterLock *lock, bool *need_issue)
 {
index 5639e8506d8ec04afba7b3c90cebec9da02c6ea4..bb7fa75af0faced4673ee1fe54311e931c138611 100644 (file)
@@ -54,6 +54,8 @@ class ScatterLock;
 class LocalLock;
 class MDCache;
 
+#include "SimpleLock.h"
+
 class Locker {
 private:
   MDS *mds;
@@ -89,9 +91,17 @@ public:
 
   void eval_gather(SimpleLock *lock, bool first=false, bool *need_issue=0);
   void eval(SimpleLock *lock, bool *need_issue=0);
+  void eval_any(SimpleLock *lock, bool *need_issue=0) {
+    if (!lock->is_stable())
+      eval_gather(lock, false, need_issue);
+    else if (lock->get_parent()->is_auth())
+      eval(lock, need_issue);
+  }
 
   void eval_cap_gather(CInode *in);
-  bool eval_caps(CInode *in);
+
+  bool eval(CInode *in, int mask);
+  void try_eval(CInode *in, int mask);
 
   bool _rdlock_kick(SimpleLock *lock);
   bool rdlock_try(SimpleLock *lock, int client, Context *c);
@@ -127,7 +137,6 @@ public:
 
   // scatter
 public:
-  void try_scatter_eval(ScatterLock *lock);
   void scatter_eval(ScatterLock *lock, bool *need_issue);        // public for MDCache::adjust_subtree_auth()
 
   void scatter_tick();
@@ -182,7 +191,6 @@ protected:
 
   // file
 public:
-  void try_file_eval(ScatterLock *lock);
   void file_eval(ScatterLock *lock, bool *need_issue);
 protected:
   void handle_file_lock(ScatterLock *lock, MLock *m);
index 7e8e7faa9339ecaaaf045800ecc5252b5d360d80..6fa315feea195cc91149dce295b1a81ece881e4d 100644 (file)
@@ -821,27 +821,8 @@ void MDCache::eval_subtree_root(CDir *dir)
 {
   // evaluate subtree inode filelock?
   //  (we should scatter the filelock on subtree bounds)
-  if (dir->inode->is_auth()) {
-    bool need_issue = false;
-    if (dir->inode->filelock.is_stable()) {
-      // force the issue a bit
-      if (!dir->inode->is_frozen())
-       mds->locker->file_eval(&dir->inode->filelock, &need_issue);
-      else
-       mds->locker->try_file_eval(&dir->inode->filelock);  // ** may or may not be auth_pinned **
-    }
-    if (dir->inode->nestlock.is_stable()) {
-      // force the issue a bit
-      if (!dir->inode->is_frozen())
-       mds->locker->scatter_eval(&dir->inode->nestlock, &need_issue);
-      else
-       mds->locker->try_scatter_eval(&dir->inode->nestlock);  // ** may or may not be auth_pinned **
-    }
-    if (need_issue)
-      mds->locker->issue_caps(dir->inode);
-  }
-  
-  
+  if (dir->inode->is_auth())
+    mds->locker->try_eval(dir->inode, CEPH_LOCK_IFILE | CEPH_LOCK_INEST);
 }
 
 
@@ -5145,7 +5126,7 @@ void MDCache::remove_client_cap(CInode *in, int client)
   if (!in->is_auth())
     mds->locker->request_inode_file_caps(in);
   
-  mds->locker->eval_caps(in);
+  mds->locker->eval(in, CEPH_CAP_LOCKS);
 
   // unlinked stray?  may need to purge (e.g., after all caps are released)
   if (in->inode.nlink == 0 &&