patch-2.1.101 linux/drivers/block/md.c
Next file: linux/drivers/block/raid0.c
Previous file: linux/drivers/block/ll_rw_blk.c
Back to the patch index
Back to the overall index
- Lines: 199
- Date:
Fri May 8 00:17:13 1998
- Orig file:
v2.1.100/linux/drivers/block/md.c
- Orig date:
Thu May 7 22:51:48 1998
diff -u --recursive --new-file v2.1.100/linux/drivers/block/md.c linux/drivers/block/md.c
@@ -70,7 +70,6 @@
static struct hd_struct md_hd_struct[MAX_MD_DEV];
static int md_blocksizes[MAX_MD_DEV];
int md_maxreadahead[MAX_MD_DEV];
-static struct md_thread md_threads[MAX_MD_THREADS];
#if SUPPORT_RECONSTRUCTION
static struct md_thread *md_sync_thread = NULL;
#endif /* SUPPORT_RECONSTRUCTION */
@@ -97,6 +96,8 @@
static struct md_personality *pers[MAX_PERSONALITY]={NULL, };
struct md_dev md_dev[MAX_MD_DEV];
+int md_thread(void * arg);
+
static struct gendisk *find_gendisk (kdev_t dev)
{
struct gendisk *tmp=gendisk_head;
@@ -803,39 +804,98 @@
{
printk ("Got md request, not good...");
return;
-}
+}
+
+void md_wakeup_thread(struct md_thread *thread)
+{
+ set_bit(THREAD_WAKEUP, &thread->flags);
+ wake_up(&thread->wqueue);
+}
-/*
- * We run MAX_MD_THREADS from md_init() and arbitrate them in run time.
- * This is not so elegant, but how can we use kernel_thread() from within
- * loadable modules?
- */
struct md_thread *md_register_thread (void (*run) (void *), void *data)
{
- int i;
- for (i = 0; i < MAX_MD_THREADS; i++) {
- if (md_threads[i].run == NULL) {
- md_threads[i].run = run;
- md_threads[i].data = data;
- return md_threads + i;
- }
+ struct md_thread *thread = (struct md_thread *)
+ kmalloc(sizeof(struct md_thread), GFP_KERNEL);
+ int ret;
+ struct semaphore sem = MUTEX_LOCKED;
+
+ if (!thread) return NULL;
+
+ memset(thread, 0, sizeof(struct md_thread));
+ init_waitqueue(&thread->wqueue);
+
+ thread->sem = &sem;
+ thread->run = run;
+ thread->data = data;
+ ret = kernel_thread(md_thread, thread, 0);
+ if (ret < 0) {
+ kfree(thread);
+ return NULL;
}
- return NULL;
+ down(&sem);
+ return thread;
}
void md_unregister_thread (struct md_thread *thread)
{
+ struct semaphore sem = MUTEX_LOCKED;
+
+ thread->sem = &sem;
thread->run = NULL;
- thread->data = NULL;
- thread->flags = 0;
+ if (thread->tsk)
+ printk("Killing md_thread %d %p %s\n",
+ thread->tsk->pid, thread->tsk, thread->tsk->comm);
+ else
+ printk("Aiee. md_thread has 0 tsk\n");
+ send_sig(SIGKILL, thread->tsk, 1);
+ printk("downing on %p\n", &sem);
+ down(&sem);
}
-void md_wakeup_thread(struct md_thread *thread)
+#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM))
+
+int md_thread(void * arg)
{
- set_bit(THREAD_WAKEUP, &thread->flags);
- wake_up(&thread->wqueue);
-}
+ struct md_thread *thread = arg;
+
+ lock_kernel();
+ exit_mm(current);
+ exit_files(current);
+ exit_fs(current);
+
+ current->session = 1;
+ current->pgrp = 1;
+ sprintf(current->comm, "md_thread");
+ siginitsetinv(¤t->blocked, SHUTDOWN_SIGS);
+ thread->tsk = current;
+ up(thread->sem);
+ for (;;) {
+ cli();
+ if (!test_bit(THREAD_WAKEUP, &thread->flags)) {
+ do {
+ spin_lock(¤t->sigmask_lock);
+ flush_signals(current);
+ spin_unlock(¤t->sigmask_lock);
+ interruptible_sleep_on(&thread->wqueue);
+ cli();
+ if (test_bit(THREAD_WAKEUP, &thread->flags))
+ break;
+ if (!thread->run) {
+ sti();
+ up(thread->sem);
+ return 0;
+ }
+ } while (signal_pending(current));
+ }
+ sti();
+ clear_bit(THREAD_WAKEUP, &thread->flags);
+ if (thread->run) {
+ thread->run(thread->data);
+ run_task_queue(&tq_disk);
+ }
+ }
+}
EXPORT_SYMBOL(md_size);
EXPORT_SYMBOL(md_maxreadahead);
@@ -981,37 +1041,6 @@
return 0;
}
-int md_thread(void * arg)
-{
- struct md_thread *thread = arg;
-
- current->session = 1;
- current->pgrp = 1;
- sprintf(current->comm, "md_thread");
-
- lock_kernel();
- for (;;) {
- sti();
- clear_bit(THREAD_WAKEUP, &thread->flags);
- if (thread->run) {
- thread->run(thread->data);
- run_task_queue(&tq_disk);
- }
- cli();
- if (!test_bit(THREAD_WAKEUP, &thread->flags)) {
- do {
- spin_lock(¤t->sigmask_lock);
- flush_signals(current);
- spin_unlock(¤t->sigmask_lock);
- interruptible_sleep_on(&thread->wqueue);
- cli();
- if (test_bit(THREAD_WAKEUP, &thread->flags))
- break;
- } while (signal_pending(current));
- }
- }
-}
-
static md_descriptor_t *get_spare(struct md_dev *mddev)
{
int i;
@@ -1281,8 +1310,6 @@
__initfunc(int md_init (void))
{
- int i;
-
printk ("md driver %d.%d.%d MAX_MD_DEV=%d, MAX_REAL=%d\n",
MD_MAJOR_VERSION, MD_MINOR_VERSION, MD_PATCHLEVEL_VERSION,
MAX_MD_DEV, MAX_REAL);
@@ -1291,15 +1318,6 @@
{
printk ("Unable to get major %d for md\n", MD_MAJOR);
return (-1);
- }
-
- memset(md_threads, 0, MAX_MD_THREADS * sizeof(struct md_thread));
- printk("md: starting %d kernel threads\n", MAX_MD_THREADS);
- for (i = 0; i < MAX_MD_THREADS; i++) {
- md_threads[i].run = NULL;
- init_waitqueue(&md_threads[i].wqueue);
- md_threads[i].flags = 0;
- kernel_thread (md_thread, md_threads + i, 0);
}
blk_dev[MD_MAJOR].request_fn=DEVICE_REQUEST;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov