Commit 17be2170 authored by Lai Siyao's avatar Lai Siyao Committed by Greg Kroah-Hartman
Browse files

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: default avatarLai 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: default avatarFan Yong <fan.yong@intel.com>
Reviewed-by: default avatarJames Simmons <uja.ornl@gmail.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6535a7d0
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
@@ -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);