Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[sfrench/cifs-2.6.git] / fs / jffs2 / background.c
index 638836b277d444d36c07acc8284a0824e99769f2..ff2a872e80e78677de43baaf8acc758299106ec0 100644 (file)
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: background.c,v 1.50 2004/11/16 20:36:10 dwmw2 Exp $
+ * $Id: background.c,v 1.54 2005/05/20 21:37:12 gleixner Exp $
  *
  */
 
@@ -15,6 +15,7 @@
 #include <linux/jffs2.h>
 #include <linux/mtd/mtd.h>
 #include <linux/completion.h>
+#include <linux/sched.h>
 #include "nodelist.h"
 
 
@@ -34,10 +35,9 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
        pid_t pid;
        int ret = 0;
 
-       if (c->gc_task)
-               BUG();
+       BUG_ON(c->gc_task);
 
-       init_MUTEX_LOCKED(&c->gc_thread_start);
+       init_completion(&c->gc_thread_start);
        init_completion(&c->gc_thread_exit);
 
        pid = kernel_thread(jffs2_garbage_collect_thread, c, CLONE_FS|CLONE_FILES);
@@ -48,21 +48,24 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
        } else {
                /* Wait for it... */
                D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid));
-               down(&c->gc_thread_start);
+               wait_for_completion(&c->gc_thread_start);
        }
+
        return ret;
 }
 
 void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
 {
+       int wait = 0;
        spin_lock(&c->erase_completion_lock);
        if (c->gc_task) {
                D1(printk(KERN_DEBUG "jffs2: Killing GC task %d\n", c->gc_task->pid));
                send_sig(SIGKILL, c->gc_task, 1);
+               wait = 1;
        }
        spin_unlock(&c->erase_completion_lock);
-       wait_for_completion(&c->gc_thread_exit);
+       if (wait)
+               wait_for_completion(&c->gc_thread_exit);
 }
 
 static int jffs2_garbage_collect_thread(void *_c)
@@ -75,7 +78,7 @@ static int jffs2_garbage_collect_thread(void *_c)
        allow_signal(SIGCONT);
 
        c->gc_task = current;
-       up(&c->gc_thread_start);
+       complete(&c->gc_thread_start);
 
        set_user_nice(current, 10);
 
@@ -97,7 +100,7 @@ static int jffs2_garbage_collect_thread(void *_c)
 
                cond_resched();
 
-               /* Put_super will send a SIGKILL and then wait on the sem. 
+               /* Put_super will send a SIGKILL and then wait on the sem.
                 */
                while (signal_pending(current)) {
                        siginfo_t info;