summaryrefslogtreecommitdiff
path: root/drivers/staging/lustre/lustre/llite
diff options
context:
space:
mode:
authorLai Siyao <lai.siyao@intel.com>2016-09-18 16:37:57 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-09-19 09:44:03 +0200
commit17be217056561b90134384d863abfd543d2321e4 (patch)
treea829ad58acad44c9b03650afae714ff021d2a5db /drivers/staging/lustre/lustre/llite
parent6535a7d046a24d7d426a9dfedf918eac954ea00c (diff)
staging: lustre: statahead: race in start/stop statahead
When starting statahead thread, it should check whether current lli_opendir_key was deauthorized in the mean time by another process. Signed-off-by: Lai Siyao <lai.siyao@intel.com> Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3270 Reviewed-on: http://review.whamcloud.com/9666 Reviewed-by: Fan Yong <fan.yong@intel.com> Reviewed-by: James Simmons <uja.ornl@gmail.com> Reviewed-by: Oleg Drokin <oleg.drokin@intel.com> Signed-off-by: James Simmons <jsimmons@infradead.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/lustre/lustre/llite')
-rw-r--r--drivers/staging/lustre/lustre/llite/statahead.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index 92972d09d6e1..8cc0bfaf32d3 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -1509,7 +1509,24 @@ static int start_statahead_thread(struct inode *dir, struct dentry *dentry)
CDEBUG(D_READA, "start statahead thread: sai %p, parent %pd\n",
sai, parent);
+ /*
+ * if another process started statahead thread, or deauthorized current
+ * lli_opendir_key, don't start statahead.
+ */
+ spin_lock(&lli->lli_sa_lock);
+ if (unlikely(lli->lli_sai || lli->lli_opendir_key ||
+ lli->lli_opendir_pid != current->pid)) {
+ spin_unlock(&lli->lli_sa_lock);
+
+ dput(parent);
+ iput(sai->sai_inode);
+ rc = -EAGAIN;
+ goto out;
+ }
lli->lli_sai = sai;
+ spin_unlock(&lli->lli_sa_lock);
+
+ atomic_inc(&ll_i2sbi(parent->d_inode)->ll_sa_running);
task = kthread_run(ll_statahead_thread, parent, "ll_sa_%u",
lli->lli_opendir_pid);
@@ -1518,9 +1535,12 @@ static int start_statahead_thread(struct inode *dir, struct dentry *dentry)
rc = PTR_ERR(task);
CERROR("cannot start ll_sa thread: rc = %d\n", rc);
dput(parent);
- lli->lli_opendir_key = NULL;
+
+ spin_lock(&lli->lli_sa_lock);
thread_set_flags(thread, SVC_STOPPED);
thread_set_flags(&sai->sai_agl_thread, SVC_STOPPED);
+ spin_unlock(&lli->lli_sa_lock);
+
ll_sai_put(sai);
LASSERT(!lli->lli_sai);
return -EAGAIN;
@@ -1529,7 +1549,6 @@ static int start_statahead_thread(struct inode *dir, struct dentry *dentry)
l_wait_event(thread->t_ctl_waitq,
thread_is_running(thread) || thread_is_stopped(thread),
&lwi);
- atomic_inc(&ll_i2sbi(d_inode(parent))->ll_sa_running);
ll_sai_put(sai);
/*
@@ -1540,9 +1559,11 @@ static int start_statahead_thread(struct inode *dir, struct dentry *dentry)
out:
kfree(sai);
+ /*
+ * once we start statahead thread failed, disable statahead so
+ * subsequent won't waste time to try it.
+ */
spin_lock(&lli->lli_sa_lock);
- lli->lli_opendir_key = NULL;
- lli->lli_opendir_pid = 0;
lli->lli_sa_enabled = 0;
spin_unlock(&lli->lli_sa_lock);