2006-01-17 11:47:12 +03:00
|
|
|
/*
|
|
|
|
* Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
|
|
|
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
|
|
|
*
|
|
|
|
* This copyrighted material is made available to anyone wishing to use,
|
|
|
|
* modify, copy, or redistribute it subject to the terms and conditions
|
2006-09-01 19:05:15 +04:00
|
|
|
* of the GNU General Public License version 2.
|
2006-01-17 11:47:12 +03:00
|
|
|
*/
|
2006-01-16 19:52:38 +03:00
|
|
|
|
|
|
|
#include "lock_dlm.h"
|
|
|
|
|
2008-05-21 20:21:42 +04:00
|
|
|
static inline int no_work(struct gdlm_ls *ls)
|
2006-01-16 19:52:38 +03:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
spin_lock(&ls->async_lock);
|
2008-05-21 20:21:42 +04:00
|
|
|
ret = list_empty(&ls->submit);
|
2006-01-16 19:52:38 +03:00
|
|
|
spin_unlock(&ls->async_lock);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-05-21 20:21:42 +04:00
|
|
|
static int gdlm_thread(void *data)
|
2006-01-16 19:52:38 +03:00
|
|
|
{
|
|
|
|
struct gdlm_ls *ls = (struct gdlm_ls *) data;
|
|
|
|
struct gdlm_lock *lp = NULL;
|
|
|
|
|
|
|
|
while (!kthread_should_stop()) {
|
2007-11-07 18:03:56 +03:00
|
|
|
wait_event_interruptible(ls->thread_wait,
|
2008-05-21 20:21:42 +04:00
|
|
|
!no_work(ls) || kthread_should_stop());
|
2006-01-16 19:52:38 +03:00
|
|
|
|
|
|
|
spin_lock(&ls->async_lock);
|
|
|
|
|
2008-05-21 20:21:42 +04:00
|
|
|
if (!list_empty(&ls->submit)) {
|
2006-01-16 19:52:38 +03:00
|
|
|
lp = list_entry(ls->submit.next, struct gdlm_lock,
|
|
|
|
delay_list);
|
|
|
|
list_del_init(&lp->delay_list);
|
2008-05-21 20:21:42 +04:00
|
|
|
spin_unlock(&ls->async_lock);
|
2006-02-23 13:00:56 +03:00
|
|
|
gdlm_do_lock(lp);
|
2008-05-21 20:21:42 +04:00
|
|
|
spin_lock(&ls->async_lock);
|
|
|
|
}
|
|
|
|
spin_unlock(&ls->async_lock);
|
2006-01-16 19:52:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int gdlm_init_threads(struct gdlm_ls *ls)
|
|
|
|
{
|
|
|
|
struct task_struct *p;
|
|
|
|
int error;
|
|
|
|
|
2008-05-21 20:21:42 +04:00
|
|
|
p = kthread_run(gdlm_thread, ls, "lock_dlm");
|
2006-01-16 19:52:38 +03:00
|
|
|
error = IS_ERR(p);
|
|
|
|
if (error) {
|
2008-05-21 20:21:42 +04:00
|
|
|
log_error("can't start lock_dlm thread %d", error);
|
2006-01-16 19:52:38 +03:00
|
|
|
return error;
|
|
|
|
}
|
2008-05-21 20:21:42 +04:00
|
|
|
ls->thread = p;
|
2006-01-16 19:52:38 +03:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void gdlm_release_threads(struct gdlm_ls *ls)
|
|
|
|
{
|
2008-05-21 20:21:42 +04:00
|
|
|
kthread_stop(ls->thread);
|
2006-01-16 19:52:38 +03:00
|
|
|
}
|
|
|
|
|