aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFUJITA Tomonori <tomof@acm.org>2008-01-25 23:25:14 +0900
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-30 13:14:25 -0600
commit3d9dd6eef888658d26ebea0cc24d15d2a93ab015 (patch)
treef3882779400f1ac10469e3f76ea544408712c1b2
parentb172b6e99e948b6abb180082cfeb8f9b1450ebff (diff)
[SCSI] handle scsi_init_queue failure properly
scsi_init_queue is expected to clean up allocated things when it fails. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/scsi_lib.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 7bfec7e7a8a..b12fb310e39 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1682,7 +1682,7 @@ int __init scsi_init_queue(void)
0, 0, NULL);
if (!scsi_bidi_sdb_cache) {
printk(KERN_ERR "SCSI: can't init scsi bidi sdb cache\n");
- return -ENOMEM;
+ goto cleanup_io_context;
}
for (i = 0; i < SG_MEMPOOL_NR; i++) {
@@ -1694,6 +1694,7 @@ int __init scsi_init_queue(void)
if (!sgp->slab) {
printk(KERN_ERR "SCSI: can't init sg slab %s\n",
sgp->name);
+ goto cleanup_bidi_sdb;
}
sgp->pool = mempool_create_slab_pool(SG_MEMPOOL_SIZE,
@@ -1701,10 +1702,25 @@ int __init scsi_init_queue(void)
if (!sgp->pool) {
printk(KERN_ERR "SCSI: can't init sg mempool %s\n",
sgp->name);
+ goto cleanup_bidi_sdb;
}
}
return 0;
+
+cleanup_bidi_sdb:
+ for (i = 0; i < SG_MEMPOOL_NR; i++) {
+ struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
+ if (sgp->pool)
+ mempool_destroy(sgp->pool);
+ if (sgp->slab)
+ kmem_cache_destroy(sgp->slab);
+ }
+ kmem_cache_destroy(scsi_bidi_sdb_cache);
+cleanup_io_context:
+ kmem_cache_destroy(scsi_io_context_cache);
+
+ return -ENOMEM;
}
void scsi_exit_queue(void)