[PATCH 058/124] staging: lustre: statahead: race in start/stop statahead

2016-09-18 Thread James Simmons
From: Lai Siyao 

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 
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3270
Reviewed-on: http://review.whamcloud.com/9666
Reviewed-by: Fan Yong 
Reviewed-by: James Simmons 
Reviewed-by: Oleg Drokin 
Signed-off-by: James Simmons 
---
 drivers/staging/lustre/lustre/llite/statahead.c |   29 +++---
 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 5be955d..70ca252 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_sa_lock);
+   if (unlikely(lli->lli_sai || lli->lli_opendir_key ||
+lli->lli_opendir_pid != current->pid)) {
+   spin_unlock(>lli_sa_lock);
+
+   dput(parent);
+   iput(sai->sai_inode);
+   rc = -EAGAIN;
+   goto out;
+   }
lli->lli_sai = sai;
+   spin_unlock(>lli_sa_lock);
+
+   atomic_inc(_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_sa_lock);
thread_set_flags(thread, SVC_STOPPED);
thread_set_flags(>sai_agl_thread, SVC_STOPPED);
+   spin_unlock(>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),
 );
-   atomic_inc(_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_sa_lock);
-   lli->lli_opendir_key = NULL;
-   lli->lli_opendir_pid = 0;
lli->lli_sa_enabled = 0;
spin_unlock(>lli_sa_lock);
 
-- 
1.7.1



[PATCH 058/124] staging: lustre: statahead: race in start/stop statahead

2016-09-18 Thread James Simmons
From: Lai Siyao 

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 
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3270
Reviewed-on: http://review.whamcloud.com/9666
Reviewed-by: Fan Yong 
Reviewed-by: James Simmons 
Reviewed-by: Oleg Drokin 
Signed-off-by: James Simmons 
---
 drivers/staging/lustre/lustre/llite/statahead.c |   29 +++---
 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 5be955d..70ca252 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_sa_lock);
+   if (unlikely(lli->lli_sai || lli->lli_opendir_key ||
+lli->lli_opendir_pid != current->pid)) {
+   spin_unlock(>lli_sa_lock);
+
+   dput(parent);
+   iput(sai->sai_inode);
+   rc = -EAGAIN;
+   goto out;
+   }
lli->lli_sai = sai;
+   spin_unlock(>lli_sa_lock);
+
+   atomic_inc(_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_sa_lock);
thread_set_flags(thread, SVC_STOPPED);
thread_set_flags(>sai_agl_thread, SVC_STOPPED);
+   spin_unlock(>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),
 );
-   atomic_inc(_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_sa_lock);
-   lli->lli_opendir_key = NULL;
-   lli->lli_opendir_pid = 0;
lli->lli_sa_enabled = 0;
spin_unlock(>lli_sa_lock);
 
-- 
1.7.1