From: Mike Christie The ram disk driver allocates its queue but never releases it. The attached patch fixes this in the module exit case, and during initialization failures. --- drivers/block/rd.c | 48 +++++++++++++++++++++++++----------------------- 1 files changed, 25 insertions(+), 23 deletions(-) diff -puN drivers/block/rd.c~ramdisk-leak-fix drivers/block/rd.c --- 25/drivers/block/rd.c~ramdisk-leak-fix 2004-01-07 19:09:36.000000000 -0800 +++ 25-akpm/drivers/block/rd.c 2004-01-07 19:09:36.000000000 -0800 @@ -307,6 +307,7 @@ static void __exit rd_cleanup (void) invalidate_bdev(bdev, 1); blkdev_put(bdev, BDEV_FILE); } + blk_put_queue(rd_queue[i]); del_gendisk(rd_disks[i]); put_disk(rd_disks[i]); } @@ -327,36 +328,32 @@ static int __init rd_init (void) rd_blocksize = BLOCK_SIZE; } - for (i = 0; i < NUM_RAMDISKS; i++) { - rd_disks[i] = alloc_disk(1); - if (!rd_disks[i]) - goto out; - } - - if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) { - err = -EIO; - goto out; - } + if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) + return -EIO; devfs_mk_dir("rd"); for (i = 0; i < NUM_RAMDISKS; i++) { - struct gendisk *disk = rd_disks[i]; - rd_queue[i] = blk_alloc_queue(GFP_KERNEL); if (!rd_queue[i]) - goto out_queue; + goto out; blk_queue_make_request(rd_queue[i], &rd_make_request); + rd_disks[i] = alloc_disk(1); + if (!rd_disks[i]) { + blk_put_queue(rd_queue[i]); + goto out; + } + /* rd_size is given in kB */ - disk->major = RAMDISK_MAJOR; - disk->first_minor = i; - disk->fops = &rd_bd_op; - disk->queue = rd_queue[i]; - sprintf(disk->disk_name, "ram%d", i); - sprintf(disk->devfs_name, "rd/%d", i); - set_capacity(disk, rd_size * 2); + rd_disks[i]->major = RAMDISK_MAJOR; + rd_disks[i]->first_minor = i; + rd_disks[i]->fops = &rd_bd_op; + rd_disks[i]->queue = rd_queue[i]; + sprintf(rd_disks[i]->disk_name, "ram%d", i); + sprintf(rd_disks[i]->devfs_name, "rd/%d", i); + set_capacity(rd_disks[i], rd_size * 2); add_disk(rd_disks[i]); } @@ -366,11 +363,16 @@ static int __init rd_init (void) NUM_RAMDISKS, rd_size, rd_blocksize); return 0; -out_queue: - unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); out: - while (i--) + for (i--; i >= 0; i--) { + blk_put_queue(rd_queue[i]); + del_gendisk(rd_disks[i]); put_disk(rd_disks[i]); + } + + devfs_remove("rd"); + unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); + return err; } _