]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: implement try_eval() on a single lock
authorSage Weil <sage@newdream.net>
Wed, 27 Jul 2011 20:13:38 +0000 (13:13 -0700)
committerSage Weil <sage@newdream.net>
Thu, 28 Jul 2011 16:49:22 +0000 (09:49 -0700)
We frequently call eval() on locks, usually after dropping an rd/wr/xlock.
At that point the eval() may do nothing because the object is now freezing
or frozen.  However, we still need to do the eval eventually.

These callers should eventually all switch to try_eval(), and retry as
needed.

Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
src/mds/Locker.cc
src/mds/Locker.h

index 62d18356121488395e4ee8c3223e64e4b74a00f9..e58ea42fd39cdc340e490108ab770328090ae0c7 100644 (file)
@@ -783,39 +783,72 @@ bool Locker::eval(CInode *in, int mask)
 
 class C_Locker_Eval : public Context {
   Locker *locker;
-  CInode *in;
+  MDSCacheObject *p;
   int mask;
 public:
-  C_Locker_Eval(Locker *l, CInode *i, int m) : locker(l), in(i), mask(m) {
-    in->get(CInode::PIN_PTRWAITER);    
+  C_Locker_Eval(Locker *l, MDSCacheObject *pp, int m) : locker(l), p(pp), mask(m) {
+    p->get(MDSCacheObject::PIN_PTRWAITER);    
   }
   void finish(int r) {
-    in->put(CInode::PIN_PTRWAITER);
-    locker->try_eval(in, mask);
+    p->put(MDSCacheObject::PIN_PTRWAITER);
+    locker->try_eval(p, mask);
   }
 };
 
-void Locker::try_eval(CInode *in, int mask)
+void Locker::try_eval(MDSCacheObject *p, 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));
+  if (p->is_ambiguous_auth()) {
+    dout(7) << "try_eval ambiguous auth, waiting on " << *p << dendl;
+    p->add_waiter(MDSCacheObject::WAIT_SINGLEAUTH, new C_Locker_Eval(this, p, mask));
+    return;
+  }
+
+  if (!p->is_auth()) {
+    dout(7) << "try_eval not auth for " << *p << dendl;
     return;
   }
 
-  if (!in->is_auth()) {
-    dout(7) << "try_eval not auth for " << *in << dendl;
+  if (!p->can_auth_pin()) {
+    dout(7) << "try_eval can't auth_pin, waiting on " << *p << dendl;
+    p->add_waiter(MDSCacheObject::WAIT_UNFREEZE, new C_Locker_Eval(this, p, mask));
+    return;
+  }
+
+  if (mask & CEPH_LOCK_DN) {
+    assert(mask == CEPH_LOCK_DN);
+    bool need_issue = false;  // ignore this, no caps on dentries
+    CDentry *dn = (CDentry *)p;
+    simple_eval(&dn->lock, &need_issue);
+  } else {
+    CInode *in = (CInode *)p;
+    eval(in, mask);
+  }
+}
+
+void Locker::try_eval(SimpleLock *lock, bool *pneed_issue)
+{
+  MDSCacheObject *p = lock->get_parent();
+
+  // unstable and ambiguous auth?
+  if (p->is_ambiguous_auth()) {
+    dout(7) << "try_eval " << *lock << " ambiguousauth, waiting on " << *p << dendl;
+    p->add_waiter(MDSCacheObject::WAIT_SINGLEAUTH, new C_Locker_Eval(this, p, lock->get_type()));
+    return;
+  }
+  
+  if (!p->is_auth()) {
+    dout(7) << "try_eval " << *lock << " not auth for " << *p << 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));
+  if (!p->can_auth_pin()) {
+    dout(7) << "try_eval " << *lock << " can't auth_pin, waiting on " << *p << dendl;
+    p->add_waiter(MDSCacheObject::WAIT_UNFREEZE, new C_Locker_Eval(this, p, lock->get_type()));
     return;
   }
 
-  eval(in, mask);
+  eval(lock, pneed_issue);
 }
 
 void Locker::eval_cap_gather(CInode *in, set<CInode*> *issue_set)
index 04016f866f76f2baffaa0c01a3032e4ff11d73ff..4987094fead6de015a7da514097ac8009939c2a7 100644 (file)
@@ -121,7 +121,8 @@ public:
   void eval_cap_gather(CInode *in, set<CInode*> *issue_set=0);
 
   bool eval(CInode *in, int mask);
-  void try_eval(CInode *in, int mask);
+  void try_eval(MDSCacheObject *p, int mask);
+  void try_eval(SimpleLock *lock, bool *pneed_issue);
 
   bool _rdlock_kick(SimpleLock *lock, bool as_anon);
   bool rdlock_try(SimpleLock *lock, client_t client, Context *c);