aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2006-03-18 13:21:20 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2006-03-18 18:34:12 -0500
commite17a9489b4a686bb5e9615e1d375c67619cb99c5 (patch)
treee6574d24ad8f16fefe7663c91cf19109e48f8c6c /block
parent25975f863b0fd42c58109e253e7a4c65d9fdaf48 (diff)
[PATCH] stop elv_unregister() from rogering other iosched's data, fix locking
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'block')
-rw-r--r--block/as-iosched.c7
-rw-r--r--block/cfq-iosched.c8
-rw-r--r--block/elevator.c24
3 files changed, 24 insertions, 15 deletions
diff --git a/block/as-iosched.c b/block/as-iosched.c
index 8da3cf66894c..d2ee2af44b58 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -195,6 +195,12 @@ static void free_as_io_context(struct as_io_context *aic)
195 kfree(aic); 195 kfree(aic);
196} 196}
197 197
198static void as_trim(struct io_context *ioc)
199{
200 kfree(ioc->aic);
201 ioc->aic = NULL;
202}
203
198/* Called when the task exits */ 204/* Called when the task exits */
199static void exit_as_io_context(struct as_io_context *aic) 205static void exit_as_io_context(struct as_io_context *aic)
200{ 206{
@@ -1860,6 +1866,7 @@ static struct elevator_type iosched_as = {
1860 .elevator_may_queue_fn = as_may_queue, 1866 .elevator_may_queue_fn = as_may_queue,
1861 .elevator_init_fn = as_init_queue, 1867 .elevator_init_fn = as_init_queue,
1862 .elevator_exit_fn = as_exit_queue, 1868 .elevator_exit_fn = as_exit_queue,
1869 .trim = as_trim,
1863 }, 1870 },
1864 1871
1865 .elevator_ktype = &as_ktype, 1872 .elevator_ktype = &as_ktype,
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 521c56d4fdbc..7102bafc98b3 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1211,6 +1211,13 @@ static void cfq_free_io_context(struct cfq_io_context *cic)
1211 kmem_cache_free(cfq_ioc_pool, cic); 1211 kmem_cache_free(cfq_ioc_pool, cic);
1212} 1212}
1213 1213
1214static void cfq_trim(struct io_context *ioc)
1215{
1216 ioc->set_ioprio = NULL;
1217 if (ioc->cic)
1218 cfq_free_io_context(ioc->cic);
1219}
1220
1214/* 1221/*
1215 * Called with interrupts disabled 1222 * Called with interrupts disabled
1216 */ 1223 */
@@ -2472,6 +2479,7 @@ static struct elevator_type iosched_cfq = {
2472 .elevator_may_queue_fn = cfq_may_queue, 2479 .elevator_may_queue_fn = cfq_may_queue,
2473 .elevator_init_fn = cfq_init_queue, 2480 .elevator_init_fn = cfq_init_queue,
2474 .elevator_exit_fn = cfq_exit_queue, 2481 .elevator_exit_fn = cfq_exit_queue,
2482 .trim = cfq_trim,
2475 }, 2483 },
2476 .elevator_ktype = &cfq_ktype, 2484 .elevator_ktype = &cfq_ktype,
2477 .elevator_name = "cfq", 2485 .elevator_name = "cfq",
diff --git a/block/elevator.c b/block/elevator.c
index 24b702d649a9..0232df2b16e6 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -675,21 +675,15 @@ void elv_unregister(struct elevator_type *e)
675 /* 675 /*
676 * Iterate every thread in the process to remove the io contexts. 676 * Iterate every thread in the process to remove the io contexts.
677 */ 677 */
678 read_lock(&tasklist_lock); 678 if (e->ops.trim) {
679 do_each_thread(g, p) { 679 read_lock(&tasklist_lock);
680 struct io_context *ioc = p->io_context; 680 do_each_thread(g, p) {
681 if (ioc && ioc->cic) { 681 task_lock(p);
682 ioc->cic->exit(ioc->cic); 682 e->ops.trim(p->io_context);
683 ioc->cic->dtor(ioc->cic); 683 task_unlock(p);
684 ioc->cic = NULL; 684 } while_each_thread(g, p);
685 } 685 read_unlock(&tasklist_lock);
686 if (ioc && ioc->aic) { 686 }
687 ioc->aic->exit(ioc->aic);
688 ioc->aic->dtor(ioc->aic);
689 ioc->aic = NULL;
690 }
691 } while_each_thread(g, p);
692 read_unlock(&tasklist_lock);
693 687
694 spin_lock_irq(&elv_list_lock); 688 spin_lock_irq(&elv_list_lock);
695 list_del_init(&e->list); 689 list_del_init(&e->list);