 if (try_to_freeze()) continue; 
jffs_garbage_collect_thread(void *ptr){        struct jffs_control *c = (struct jffs_control *) ptr;	struct jffs_fmcontrol *fmc = c->fmc;	long erased;	int result = 0;	D1(int i = 1);	daemonize("jffs_gcd");	c->gc_task = current;	lock_kernel();	init_completion(&c->gc_thread_comp); /* barrier */ 	spin_lock_irq(&current->sighand->siglock);	siginitsetinv (&current->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));	recalc_sigpending();	spin_unlock_irq(&current->sighand->siglock);	D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): Starting infinite loop.\n"));	for (;;) {		/* See if we need to start gc.  If we don't, go to sleep.		   		   Current implementation is a BAD THING(tm).  If we try 		   to unmount the FS, the unmount operation will sleep waiting		   for this thread to exit.  We need to arrange to send it a		   sig before the umount process sleeps.		*/		if (!thread_should_wake(c))			set_current_state (TASK_INTERRUPTIBLE);				schedule(); /* Yes, we do this even if we want to go				       on immediately - we're a low priority 				       background task. */		/* Put_super will send a SIGKILL and then wait on the sem. 		 */		while (signal_pending(current)) {			siginfo_t info;			unsigned long signr = 0;			spin_lock_irq(&current->sighand->siglock);			signr = dequeue_signal(current, &current->blocked, &info);			spin_unlock_irq(&current->sighand->siglock);			switch(signr) {			case SIGSTOP:				D1(printk("jffs_garbage_collect_thread(): SIGSTOP received.\n"));				set_current_state(TASK_STOPPED);				schedule();				break;			case SIGKILL:				D1(printk("jffs_garbage_collect_thread(): SIGKILL received.\n"));				c->gc_task = NULL;				complete_and_exit(&c->gc_thread_comp, 0);			}		}		D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): collecting.\n"));		D3(printk (KERN_NOTICE "g_c_thread(): down biglock\n"));		down(&fmc->biglock);				D1(printk("***jffs_garbage_collect_thread(): round #%u, "			  "fmc->dirty_size = %u\n", i++, fmc->dirty_size));		D2(jffs_print_fmcontrol(fmc));		if ((erased = jffs_try_to_erase(c)) < 0) {			printk(KERN_WARNING "JFFS: Error in "			       "garbage collector: %ld.\n", erased);		}		if (erased)			goto gc_end;		if (fmc->free_size == 0) {			/* Argh. Might as well commit suicide. */			printk(KERN_ERR "jffs_garbage_collect_thread(): free_size == 0. This is BAD.\n");			send_sig(SIGQUIT, c->gc_task, 1);			// panic()			goto gc_end;		}				/* Let's dare to make a garbage collect.  */		if ((result = jffs_garbage_collect_next(c)) < 0) {			printk(KERN_ERR "JFFS: Something "			       "has gone seriously wrong "			       "with a garbage collect: %d\n", result);		}			gc_end:		D3(printk (KERN_NOTICE "g_c_thread(): up biglock\n"));		up(&fmc->biglock);	} /* for (;;) */} /* jffs_garbage_collect_thread() */
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/ef2a701d444a4ea9790146e92756b0dde5070a15/intrep.c/clean/fs/jffs/intrep.c