From: Tejun Heo <htejun@gmail.com>

When a process has more than one cic's associated with it, only the first one
was kmem_cache_free'd in the original code.  This patch frees all cic's in
cfq_free_io_context().

While at it, remove unnecessary refcounting from cic's to ioc.  This reference
is created when each cic is created and removed altogether when the ioc is
exited, and, thus, serves no purpose.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Jens Axboe <axboe@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 drivers/block/cfq-iosched.c |   19 ++++++++++---------
 1 files changed, 10 insertions(+), 9 deletions(-)

diff -puN drivers/block/cfq-iosched.c~cfq-cfq_io_context-leak-fix drivers/block/cfq-iosched.c
--- 25/drivers/block/cfq-iosched.c~cfq-cfq_io_context-leak-fix	2005-06-18 02:48:56.000000000 -0700
+++ 25-akpm/drivers/block/cfq-iosched.c	2005-06-18 02:48:56.000000000 -0700
@@ -1239,6 +1239,14 @@ cfq_find_cfq_hash(struct cfq_data *cfqd,
 
 static void cfq_free_io_context(struct cfq_io_context *cic)
 {
+	struct cfq_io_context *__cic;
+	struct list_head *entry, *next;
+
+	list_for_each_safe(entry, next, &cic->list) {
+		__cic = list_entry(entry, struct cfq_io_context, list);
+		kmem_cache_free(cfq_ioc_pool, __cic);
+	}
+
 	kmem_cache_free(cfq_ioc_pool, cic);
 }
 
@@ -1261,7 +1269,6 @@ static void cfq_exit_single_io_context(s
 
 	cfq_put_queue(cic->cfqq);
 	cic->cfqq = NULL;
-	put_io_context(cic->ioc);
 	spin_unlock(q->queue_lock);
 }
 
@@ -1272,7 +1279,7 @@ static void cfq_exit_single_io_context(s
 static void cfq_exit_io_context(struct cfq_io_context *cic)
 {
 	struct cfq_io_context *__cic;
-	struct list_head *entry, *nxt;
+	struct list_head *entry;
 	unsigned long flags;
 
 	local_irq_save(flags);
@@ -1280,10 +1287,8 @@ static void cfq_exit_io_context(struct c
 	/*
 	 * put the reference this task is holding to the various queues
 	 */
-	list_for_each_safe(entry, nxt, &cic->list) {
+	list_for_each(entry, &cic->list) {
 		__cic = list_entry(entry, struct cfq_io_context, list);
-
-		list_del(&__cic->list);
 		cfq_exit_single_io_context(__cic);
 	}
 
@@ -1472,8 +1477,6 @@ cfq_get_io_context(struct cfq_data *cfqd
 		ioc->cic = cic;
 		ioc->set_ioprio = cfq_ioc_set_ioprio;
 		cic->ioc = ioc;
-		atomic_inc(&ioc->refcount);
-
 		cic->key = cfqd;
 		atomic_inc(&cfqd->ref);
 	} else {
@@ -1510,8 +1513,6 @@ cfq_get_io_context(struct cfq_data *cfqd
 			goto err;
 
 		__cic->ioc = ioc;
-		atomic_inc(&ioc->refcount);
-
 		__cic->key = cfqd;
 		atomic_inc(&cfqd->ref);
 		list_add(&__cic->list, &cic->list);
_