--- linux/drivers/block/loop.c.org	Sat Oct 14 21:01:32 2000
+++ linux//drivers/block/loop.c	Sat Oct 14 21:22:15 2000
@@ -883,13 +883,18 @@
 EXPORT_SYMBOL(loop_register_transfer);
 EXPORT_SYMBOL(loop_unregister_transfer);
 
+static volatile int loopd_running = 0; /* Ugly/hackish refcount hack */
+static volatile int stop_loopd = 0; /* Ugly/hackish internal signal */
+
 static int loopd (void *unused)
 {
 	struct wait_queue wait = { current, NULL };
 
 	lock_kernel();
+	loopd_running = 1;
 	/* printk("loopback system thread started ...\n"); */
 	strcpy(current->comm, "loopd");
+	exit_mm(current);
 	init_waitqueue(&loopd_wait);
 	init_waitqueue(&loopd_done_wait);
 
@@ -903,6 +908,7 @@
 	if (!async_queue) {
 		spin_unlock_irq(&io_request_lock);
 		wake_up(&loopd_done_wait);
+		current->state = TASK_INTERRUPTIBLE;
 		schedule();
 		spin_lock_irq(&io_request_lock);
 	}
@@ -910,7 +916,10 @@
 	remove_wait_queue(&loopd_wait, &wait);
 	current->state = TASK_RUNNING;
 
-	goto repeat;
+	if (!stop_loopd) 
+		goto repeat;
+	spin_unlock_irq(&io_request_lock);
+	loopd_running = 0;
 
 	return 0;
 }
@@ -949,7 +958,18 @@
 #ifdef MODULE
 void cleanup_module (void) 
 {
+	int count=0;
 	if (unregister_blkdev(MAJOR_NR, "loop"))
 		printk(KERN_WARNING "loop: cannot unregister blkdev\n");
+	stop_loopd = 1;
+	while (loopd_running) {
+		count++;
+		wake_up(&loopd_wait);
+		current->state = TASK_RUNNING;
+		schedule();
+		if (count>50)
+			break; /* uh oh. but prevent an infinite loop */
+	}
+	
 }
 #endif
