unionfs_unlock_dentry(sb->s_root);
if (!err) {
/* its now ok to start the cleanup thread */
- run_sioa(odf->cleanup, __odf_cleanup,
+ err = run_sioa(odf->cleanup, __odf_cleanup,
msecs_to_jiffies(odf->cleanup->cleanup.attr->timeout->
val));
- goto out;
+ if (!err)
+ goto out;
}
/* else fall through */
int __run_sioa(void *args)
{
struct sioa_args *sioa_args = (struct sioa_args *)args;
- sioa_args->process = current;
- while (!sioa_args->complete) {
+ while (!kthread_should_stop()) {
sioa_args->work(args);
if (sioa_args->waiting) {
complete(&sioa_args->comp_work);
/*
* Creates an asynchronous thread. Calling process is responsible for
- * calling wait_for_completion. The thread executes the work function, then
- * sleeps for timeout time. When it wakes up it runs the done function and
- * terminates if done, otherwise repeats the loop. The done function should
- * return 0 if not done.
+ * calling kthread_stop. The function returns 0 upon success.
+ * The thread executes the work function, then sleeps for timeout time.
+ * When it wakes up it runs the done function and terminates if done,
+ * otherwise repeats the loop. The done function should return 0
+ * if not done.
*/
-void run_sioa(struct sioa_args *args, void (*work) (void *),
+
+int run_sioa(struct sioa_args *args, void (*work) (void *),
signed long timeout)
{
+ int err = 0;
init_completion(&args->comp_thread);
mutex_init(&args->lock);
- args->complete = 0;
args->waiting = 0;
args->process = NULL;
args->timeout = timeout;
args->work = work;
- kernel_thread(__run_sioa, args, 0);
+ args->process = kernel_run(__run_sioa, args, "kunionfs_odf_cleanup");
+ if (IS_ERR(args->process))
+ err = PTR_ERR(args->process);
+ return err;
}
/*
void complete_sioa(struct sioa_args *args)
{
mutex_lock(&args->lock);
- args->complete = 1;
/* there might be the case that this is called before the */
/* thread actually runs and process is initialized */
if (args->process)
- wake_up_process(args->process);
- schedule();
- wait_for_completion(&args->comp_thread);
+ kthread_stop(args->process);
mutex_unlock(&args->lock);
}
void (*work) (void *);
struct mutex lock; /* synchronize multiple threads */
int waiting;
- int complete;
union {
struct cleanup_args cleanup;
extern int __init init_sioq(void);
extern void stop_sioq(void);
extern void run_sioq(work_func_t func, struct sioq_args *args);
-extern void run_sioa(struct sioa_args *args, void (*work) (void *),
+extern int run_sioa(struct sioa_args *args, void (*work) (void *),
signed long timeout);
extern void wake_up_and_wait_sioa(struct sioa_args *args);
extern void wake_up_sioa(struct sioa_args *args);