b=16947
i=h.huang
i=yury.umanets
Hold lli_lock when access lli_sai to prevent NULL pointer.
* 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)
* 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;
if (inode->i_sb->s_root == file->f_dentry) {
LUSTRE_FPRIVATE(file) = NULL;
up(&lli->lli_och_sem);
out_openerr:
if (opendir_set != 0)
up(&lli->lli_och_sem);
out_openerr:
if (opendir_set != 0)
- ll_stop_statahead(inode, fd);
+ ll_stop_statahead(inode, lli->lli_opendir_key);
};
int do_statahead_enter(struct inode *dir, struct dentry **dentry, int lookup);
};
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
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_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);
struct ll_dentry_data *ldd = ll_d2d(dentry);
- 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;
+ 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);
struct inode *dir = parent->d_inode;
struct ll_inode_info *lli = ll_i2info(dir);
struct ll_sb_info *sbi = ll_i2sbi(dir);
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;
struct page *page;
__u64 pos = 0;
int first = 0;
struct ll_dir_chain chain;
ENTRY;
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);
}
{
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;
sbi->ll_sa_total++;
spin_lock(&lli->lli_lock);
thread->t_flags = SVC_RUNNING;
* \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 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)
* \retval others -- error
*/
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);
sai->sai_thread.t_flags = SVC_STOPPED;
ll_sai_put(sai);
LASSERT(lli->lli_sai == NULL);
}
l_wait_event(sai->sai_thread.t_ctl_waitq,
}
l_wait_event(sai->sai_thread.t_ctl_waitq,
/**
* update hit/miss count.
*/
/**
* 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);
- 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++;
if (result >= 1) {
sbi->ll_sa_hit++;
sai->sai_hit++;
if (!sa_is_stopped(sai))
cfs_waitq_signal(&sai->sai_thread.t_ctl_waitq);
ll_sai_entry_fini(sai);
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;