diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
commit | c7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch) | |
tree | 3682407a599b8f9f03fc096298134cafba1c9b2f /drivers/block/md.c | |
parent | 1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff) |
o Merge with Linux 2.1.116.
o New Newport console code.
o New G364 console code.
Diffstat (limited to 'drivers/block/md.c')
-rw-r--r-- | drivers/block/md.c | 154 |
1 files changed, 86 insertions, 68 deletions
diff --git a/drivers/block/md.c b/drivers/block/md.c index 8b4b487e1..d0eae5a29 100644 --- a/drivers/block/md.c +++ b/drivers/block/md.c @@ -70,7 +70,6 @@ extern kdev_t name_to_kdev_t(char *line) __init; 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 gendisk md_gendisk= 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; @@ -289,7 +290,7 @@ static int analyze_sbs (int minor, int pnum) } /* - * Ok, we have all disks and the array is ready to run. Lets + * OK, we have all disks and the array is ready to run. Let's * find the freshest superblock, that one will be the superblock * that represents the whole array. */ @@ -593,9 +594,9 @@ static int do_md_add (int minor, kdev_t dev) if (hot_add) { /* * Check the superblock for consistency. - * the personality itself has to check wether it's getting - * added with the proper flags ... also, personality has to - * be checked too ;) + * The personality itself has to check whether it's getting + * added with the proper flags. The personality has to be + * checked too. ;) */ if (analyze_one_sb (realdev)) return -EINVAL; @@ -803,39 +804,98 @@ static void do_md_request (void) { 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 @@ int unregister_md_personality (int p_num) 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; @@ -1105,7 +1134,7 @@ int md_do_sync(struct md_dev *mddev) } /* - * Lets sleep some if we are faster than our speed limit: + * Let's sleep some if we are faster than our speed limit: */ while (blocksize*j/(jiffies-starttime+1)*HZ/1024 > SPEED_LIMIT) { @@ -1281,8 +1310,6 @@ void raid5_init (void); __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); @@ -1293,15 +1320,6 @@ __initfunc(int md_init (void)) 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; blk_dev[MD_MAJOR].current_request=NULL; read_ahead[MD_MAJOR]=INT_MAX; |