diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 35c1d8713e1fa2e76dca8e3cc2f98b52ba85ed78..9850774e44941c44585b53b90d348d7ab099cfca 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -331,7 +331,7 @@ int ll_file_release(struct inode *inode, struct file *file) * Different processes can open the same dir, "ll_opendir_key" means: * it is me that should stop the statahead thread. */ if (lli->lli_opendir_key == fd && lli->lli_opendir_pid != 0) - ll_stop_statahead(inode, fd); + ll_stop_statahead(inode, lli->lli_opendir_key); if (inode->i_sb->s_root == file->f_dentry) { LUSTRE_FPRIVATE(file) = NULL; @@ -690,7 +690,7 @@ out_och_free: up(&lli->lli_och_sem); out_openerr: if (opendir_set != 0) - ll_stop_statahead(inode, fd); + ll_stop_statahead(inode, lli->lli_opendir_key); } return rc; diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 22b598125001e8f7fca6c8865678ddde25314b99..a03e1bf82e3ea6a97a05f629442ec64a211dbf3e 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -1069,23 +1069,23 @@ struct ll_statahead_info { }; int do_statahead_enter(struct inode *dir, struct dentry **dentry, int lookup); -int ll_statahead_exit(struct dentry *dentry, int result); +void ll_statahead_exit(struct dentry *dentry, int result); void ll_stop_statahead(struct inode *inode, void *key); static inline -int ll_statahead_mark(struct dentry *dentry) +void ll_statahead_mark(struct dentry *dentry) { struct ll_inode_info *lli = ll_i2info(dentry->d_parent->d_inode); - struct ll_statahead_info *sai = lli->lli_sai; struct ll_dentry_data *ldd = ll_d2d(dentry); - int rc = 0; - if (likely(ldd != NULL)) - ldd->lld_sa_generation = sai->sai_generation; - else - rc = -ENOMEM; + /* not the same process, don't mark */ + if (lli->lli_opendir_pid != cfs_curproc_pid()) + return; - return rc; + spin_lock(&lli->lli_lock); + if (likely(lli->lli_sai != NULL && ldd != NULL)) + ldd->lld_sa_generation = lli->lli_sai->sai_generation; + spin_unlock(&lli->lli_lock); } static inline diff --git a/lustre/llite/statahead.c b/lustre/llite/statahead.c index e5fff85a5c2b7bf82bedb06ccf0c39309ff52696..e3416758b59c802b10e7c27fbaa1298cf3df6fb8 100644 --- a/lustre/llite/statahead.c +++ b/lustre/llite/statahead.c @@ -741,8 +741,8 @@ static int ll_statahead_thread(void *arg) struct inode *dir = parent->d_inode; struct ll_inode_info *lli = ll_i2info(dir); struct ll_sb_info *sbi = ll_i2sbi(dir); - struct ll_statahead_info *sai = ll_sai_get(lli->lli_sai); - struct ptlrpc_thread *thread = &sai->sai_thread; + struct ll_statahead_info *sai; + struct ptlrpc_thread *thread; struct page *page; __u64 pos = 0; int first = 0; @@ -750,12 +750,23 @@ static int ll_statahead_thread(void *arg) struct ll_dir_chain chain; ENTRY; + spin_lock(&lli->lli_lock); + if (unlikely(lli->lli_sai == NULL)) { + spin_unlock(&lli->lli_lock); + dput(parent); + RETURN(-EAGAIN); + } else { + sai = ll_sai_get(lli->lli_sai); + spin_unlock(&lli->lli_lock); + } + { char pname[16]; snprintf(pname, 15, "ll_sa_%u", sta->sta_pid); cfs_daemonize(pname); } + thread = &sai->sai_thread; sbi->ll_sa_total++; spin_lock(&lli->lli_lock); thread->t_flags = SVC_RUNNING; @@ -1055,6 +1066,7 @@ out: * \retval 1 -- stat ahead thread process such dentry, for lookup, it hit * \retval -EEXIST -- stat ahead thread started, and this is the first dentry * \retval -EBADFD -- statahead thread exit and not dentry available + * \retval -EAGAIN -- try to stat by caller * \retval others -- error */ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, int lookup) @@ -1175,7 +1187,7 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, int lookup) sai->sai_thread.t_flags = SVC_STOPPED; ll_sai_put(sai); LASSERT(lli->lli_sai == NULL); - RETURN(rc); + RETURN(-EAGAIN); } l_wait_event(sai->sai_thread.t_ctl_waitq, @@ -1192,20 +1204,16 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp, int lookup) /** * update hit/miss count. */ -int ll_statahead_exit(struct dentry *dentry, int result) +void ll_statahead_exit(struct dentry *dentry, int result) { - struct dentry *parent = dentry->d_parent; - struct ll_inode_info *lli = ll_i2info(parent->d_inode); - struct ll_sb_info *sbi = ll_i2sbi(parent->d_inode); - int rc = 0; + struct dentry *parent = dentry->d_parent; + struct ll_inode_info *lli = ll_i2info(parent->d_inode); + struct ll_sb_info *sbi = ll_i2sbi(parent->d_inode); + struct ll_statahead_info *sai = lli->lli_sai; + struct ll_dentry_data *ldd = ll_d2d(dentry); ENTRY; - if (lli->lli_opendir_pid != cfs_curproc_pid()) - RETURN(-EBADFD); - - if (lli->lli_sai) { - struct ll_statahead_info *sai = lli->lli_sai; - + if (lli->lli_opendir_pid == cfs_curproc_pid() && sai) { if (result >= 1) { sbi->ll_sa_hit++; sai->sai_hit++; @@ -1235,7 +1243,8 @@ int ll_statahead_exit(struct dentry *dentry, int result) if (!sa_is_stopped(sai)) cfs_waitq_signal(&sai->sai_thread.t_ctl_waitq); ll_sai_entry_fini(sai); - rc = ll_statahead_mark(dentry); + if (likely(ldd != NULL)) + ldd->lld_sa_generation = sai->sai_generation; } - RETURN(rc); + EXIT; }