Reviewed-by: Greg Farnum <greg@xxxxxxxxxxx> Software Engineer #42 @ http://inktank.com | http://ceph.com On Sunday, March 17, 2013 at 7:51 AM, Yan, Zheng wrote: > From: "Yan, Zheng" <zheng.z.yan@xxxxxxxxx (mailto:zheng.z.yan@xxxxxxxxx)> > > If there are several unstable locks in an inode, current Locker::eval(CInode*,) > processes each lock's finished contexts seperately. This may cause very deep > call stack if finished contexts also call Locker::eval() on the same inode. > An extreme example is: > > Locker::eval() wakes an open request(). Server::handle_client_open() starts > a log entry, then call Locker::issue_new_caps(). Locker::issue_new_caps() > calls Locker::eval() and wakes another request. The later request also tries > starting a log entry. > > Signed-off-by: Yan, Zheng <zheng.z.yan@xxxxxxxxx (mailto:zheng.z.yan@xxxxxxxxx)> > --- > src/mds/Locker.cc (http://Locker.cc) | 17 ++++++++++------- > src/mds/Locker.h | 4 ++-- > 2 files changed, 12 insertions(+), 9 deletions(-) > > diff --git a/src/mds/Locker.cc (http://Locker.cc) b/src/mds/Locker.cc (http://Locker.cc) > index b61fb14..d06a9cc 100644 > --- a/src/mds/Locker.cc (http://Locker.cc) > +++ b/src/mds/Locker.cc (http://Locker.cc) > @@ -803,6 +803,7 @@ void Locker::eval_gather(SimpleLock *lock, bool first, bool *pneed_issue, list<C > bool Locker::eval(CInode *in, int mask, bool caps_imported) > { > bool need_issue = false; > + list<Context*> finishers; > > dout(10) << "eval " << mask << " " << *in << dendl; > > @@ -821,19 +822,19 @@ bool Locker::eval(CInode *in, int mask, bool caps_imported) > > retry: > if (mask & CEPH_LOCK_IFILE) > - eval_any(&in->filelock, &need_issue, caps_imported); > + eval_any(&in->filelock, &need_issue, &finishers, caps_imported); > if (mask & CEPH_LOCK_IAUTH) > - eval_any(&in->authlock, &need_issue, caps_imported); > + eval_any(&in->authlock, &need_issue, &finishers, caps_imported); > if (mask & CEPH_LOCK_ILINK) > - eval_any(&in->linklock, &need_issue,caps_imported); > + eval_any(&in->linklock, &need_issue, &finishers, caps_imported); > if (mask & CEPH_LOCK_IXATTR) > - eval_any(&in->xattrlock, &need_issue, caps_imported); > + eval_any(&in->xattrlock, &need_issue, &finishers, caps_imported); > if (mask & CEPH_LOCK_INEST) > - eval_any(&in->nestlock, &need_issue, caps_imported); > + eval_any(&in->nestlock, &need_issue, &finishers, caps_imported); > if (mask & CEPH_LOCK_IFLOCK) > - eval_any(&in->flocklock, &need_issue, caps_imported); > + eval_any(&in->flocklock, &need_issue, &finishers, caps_imported); > if (mask & CEPH_LOCK_IPOLICY) > - eval_any(&in->policylock, &need_issue, caps_imported); > + eval_any(&in->policylock, &need_issue, &finishers, caps_imported); > > // drop loner? > if (in->is_auth() && in->is_head() && in->get_wanted_loner() != in->get_loner()) { > @@ -854,6 +855,8 @@ bool Locker::eval(CInode *in, int mask, bool caps_imported) > } > } > > + finish_contexts(g_ceph_context, finishers); > + > if (need_issue && in->is_head()) > issue_caps(in); > > diff --git a/src/mds/Locker.h b/src/mds/Locker.h > index f005925..3f79996 100644 > --- a/src/mds/Locker.h > +++ b/src/mds/Locker.h > @@ -99,9 +99,9 @@ public: > > void eval_gather(SimpleLock *lock, bool first=false, bool *need_issue=0, list<Context*> *pfinishers=0); > void eval(SimpleLock *lock, bool *need_issue); > - void eval_any(SimpleLock *lock, bool *need_issue, bool first=false) { > + void eval_any(SimpleLock *lock, bool *need_issue, list<Context*> *pfinishers=0, bool first=false) { > if (!lock->is_stable()) > - eval_gather(lock, first, need_issue); > + eval_gather(lock, first, need_issue, pfinishers); > else if (lock->get_parent()->is_auth()) > eval(lock, need_issue); > } > -- > 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html