Commit 7665869a authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] mtd switched to dynamic allocation

parent c509ddbb
...@@ -1223,18 +1223,17 @@ static void ftl_notify_add(struct mtd_info *mtd) ...@@ -1223,18 +1223,17 @@ static void ftl_notify_add(struct mtd_info *mtd)
} }
partition = kmalloc(sizeof(partition_t), GFP_KERNEL); partition = kmalloc(sizeof(partition_t), GFP_KERNEL);
disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL); disk = alloc_disk();
if (!partition||!disk) { if (!partition||!disk) {
printk(KERN_WARNING "No memory to scan for FTL on %s\n", printk(KERN_WARNING "No memory to scan for FTL on %s\n",
mtd->name); mtd->name);
kfree(partition); kfree(partition);
kfree(disk); put_disk(disk);
return; return;
} }
memset(partition, 0, sizeof(partition_t)); memset(partition, 0, sizeof(partition_t));
memset(disk, 0, sizeof(struct gendisk));
sprintf(disk->disk_name, "ftl%c", 'a' + device); sprintf(disk->disk_name, "ftl%c", 'a' + device);
disk->major = FTL_MAJOR; disk->major = FTL_MAJOR;
disk->first_minor = device << 4; disk->first_minor = device << 4;
...@@ -1255,7 +1254,7 @@ static void ftl_notify_add(struct mtd_info *mtd) ...@@ -1255,7 +1254,7 @@ static void ftl_notify_add(struct mtd_info *mtd)
#endif #endif
} else { } else {
kfree(partition); kfree(partition);
kfree(disk); put_disk(disk);
} }
} }
...@@ -1281,7 +1280,7 @@ static void ftl_notify_remove(struct mtd_info *mtd) ...@@ -1281,7 +1280,7 @@ static void ftl_notify_remove(struct mtd_info *mtd)
myparts[i]->state = 0; myparts[i]->state = 0;
del_gendisk(myparts[i]->disk); del_gendisk(myparts[i]->disk);
kfree(myparts[i]->disk); put_disk(myparts[i]->disk);
kfree(myparts[i]); kfree(myparts[i]);
myparts[i] = NULL; myparts[i] = NULL;
} }
......
...@@ -42,7 +42,7 @@ static struct mtdblk_dev { ...@@ -42,7 +42,7 @@ static struct mtdblk_dev {
unsigned long cache_offset; unsigned long cache_offset;
unsigned int cache_size; unsigned int cache_size;
enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state; enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
struct gendisk disk; struct gendisk *disk;
} *mtdblks[MAX_MTD_DEVICES]; } *mtdblks[MAX_MTD_DEVICES];
static spinlock_t mtdblks_lock; static spinlock_t mtdblks_lock;
...@@ -263,6 +263,7 @@ static int mtdblock_open(struct inode *inode, struct file *file) ...@@ -263,6 +263,7 @@ static int mtdblock_open(struct inode *inode, struct file *file)
struct mtdblk_dev *mtdblk; struct mtdblk_dev *mtdblk;
struct mtd_info *mtd; struct mtd_info *mtd;
int dev = minor(inode->i_rdev); int dev = minor(inode->i_rdev);
struct gendisk *disk;
DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n"); DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
...@@ -294,10 +295,9 @@ static int mtdblock_open(struct inode *inode, struct file *file) ...@@ -294,10 +295,9 @@ static int mtdblock_open(struct inode *inode, struct file *file)
spin_unlock(&mtdblks_lock); spin_unlock(&mtdblks_lock);
mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL); mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
if (!mtdblk) { disk = alloc_disk();
put_mtd_device(mtd); if (!mtdblk || !disk)
return -ENOMEM; goto Enomem;
}
memset(mtdblk, 0, sizeof(*mtdblk)); memset(mtdblk, 0, sizeof(*mtdblk));
mtdblk->count = 1; mtdblk->count = 1;
mtdblk->mtd = mtd; mtdblk->mtd = mtd;
...@@ -308,17 +308,15 @@ static int mtdblock_open(struct inode *inode, struct file *file) ...@@ -308,17 +308,15 @@ static int mtdblock_open(struct inode *inode, struct file *file)
mtdblk->mtd->erasesize) { mtdblk->mtd->erasesize) {
mtdblk->cache_size = mtdblk->mtd->erasesize; mtdblk->cache_size = mtdblk->mtd->erasesize;
mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize); mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
if (!mtdblk->cache_data) { if (!mtdblk->cache_data)
put_mtd_device(mtdblk->mtd); goto Enomem;
kfree(mtdblk);
return -ENOMEM;
}
} }
mtdblk->disk.major = MAJOR_NR; disk->major = MAJOR_NR;
mtdblk->disk.first_minor = dev; disk->first_minor = dev;
mtdblk->disk.minor_shift = 0; disk->minor_shift = 0;
mtdblk->disk.fops = &mtd_fops; disk->fops = &mtd_fops;
sprintf(mtdblk->disk.disk_name, "mtd%d", dev); sprintf(disk->disk_name, "mtd%d", dev);
mtdblk->disk = disk;
/* OK, we've created a new one. Add it to the list. */ /* OK, we've created a new one. Add it to the list. */
...@@ -331,19 +329,25 @@ static int mtdblock_open(struct inode *inode, struct file *file) ...@@ -331,19 +329,25 @@ static int mtdblock_open(struct inode *inode, struct file *file)
put_mtd_device(mtdblk->mtd); put_mtd_device(mtdblk->mtd);
vfree(mtdblk->cache_data); vfree(mtdblk->cache_data);
kfree(mtdblk); kfree(mtdblk);
put_disk(disk);
return 0; return 0;
} }
mtdblks[dev] = mtdblk; mtdblks[dev] = mtdblk;
set_capacity(&mtdblk->disk, mtdblk->mtd->size/512); set_capacity(disk, mtdblk->mtd->size/512);
add_disk(&mtdblk->disk); add_disk(disk);
set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE)); set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE));
spin_unlock(&mtdblks_lock); spin_unlock(&mtdblks_lock);
DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
return 0; return 0;
Enomem:
put_mtd_device(mtd);
put_disk(disk);
kfree(mtdblk);
return -ENOMEM;
} }
static release_t mtdblock_release(struct inode *inode, struct file *file) static release_t mtdblock_release(struct inode *inode, struct file *file)
...@@ -367,7 +371,8 @@ static release_t mtdblock_release(struct inode *inode, struct file *file) ...@@ -367,7 +371,8 @@ static release_t mtdblock_release(struct inode *inode, struct file *file)
/* It was the last usage. Free the device */ /* It was the last usage. Free the device */
mtdblks[dev] = NULL; mtdblks[dev] = NULL;
spin_unlock(&mtdblks_lock); spin_unlock(&mtdblks_lock);
del_gendisk(&mtdblk->disk); del_gendisk(mtdblk->disk);
put_disk(mtdblk->disk);
if (mtdblk->mtd->sync) if (mtdblk->mtd->sync)
mtdblk->mtd->sync(mtdblk->mtd); mtdblk->mtd->sync(mtdblk->mtd);
put_mtd_device(mtdblk->mtd); put_mtd_device(mtdblk->mtd);
......
...@@ -29,13 +29,13 @@ static int debug = MTDBLOCK_DEBUG; ...@@ -29,13 +29,13 @@ static int debug = MTDBLOCK_DEBUG;
MODULE_PARM(debug, "i"); MODULE_PARM(debug, "i");
#endif #endif
static struct gendisk mtd_disks[MAX_MTD_DEVICES]; static struct gendisk *mtd_disks[MAX_MTD_DEVICES];
static int mtdblock_open(struct inode *inode, struct file *file) static int mtdblock_open(struct inode *inode, struct file *file)
{ {
struct mtd_info *mtd = NULL; struct mtd_info *mtd = NULL;
int dev = minor(inode->i_rdev); int dev = minor(inode->i_rdev);
struct gendisk *disk = mtd_disks + dev; struct gendisk *disk = mtd_disks[dev];
DEBUG(1,"mtdblock_open\n"); DEBUG(1,"mtdblock_open\n");
...@@ -73,7 +73,7 @@ static release_t mtdblock_release(struct inode *inode, struct file *file) ...@@ -73,7 +73,7 @@ static release_t mtdblock_release(struct inode *inode, struct file *file)
release_return(-ENODEV); release_return(-ENODEV);
} }
del_gendisk(mtd_disks + dev); del_gendisk(mtd_disks[dev]);
if (mtd->sync) if (mtd->sync)
mtd->sync(mtd); mtd->sync(mtd);
...@@ -218,30 +218,42 @@ static struct block_device_operations mtd_fops = ...@@ -218,30 +218,42 @@ static struct block_device_operations mtd_fops =
int __init init_mtdblock(void) int __init init_mtdblock(void)
{ {
int err = -ENOMEM;
int i; int i;
if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
MTD_BLOCK_MAJOR);
return -EAGAIN;
}
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
for (i = 0; i < MAX_MTD_DEVICES; i++) { for (i = 0; i < MAX_MTD_DEVICES; i++) {
struct gendisk *disk = mtd_disks + i; struct gendisk *disk = alloc_disk();
if (!disk)
goto out;
disk->major = MAJOR_NR; disk->major = MAJOR_NR;
disk->first_minor = i; disk->first_minor = i;
sprintf(disk->disk_name, "mtdblock%d", i); sprintf(disk->disk_name, "mtdblock%d", i);
disk->fops = &mtd_fops; disk->fops = &mtd_fops;
mtd_disks[i] = disk;
} }
if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
MTD_BLOCK_MAJOR);
err = -EAGAIN;
goto out;
}
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
return 0; return 0;
out:
while (i--)
put_disk(mtd_disks[i]);
return err;
} }
static void __exit cleanup_mtdblock(void) static void __exit cleanup_mtdblock(void)
{ {
int i;
unregister_blkdev(MAJOR_NR,DEVICE_NAME); unregister_blkdev(MAJOR_NR,DEVICE_NAME);
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
for (i = 0; i < MAX_MTD_DEVICES; i++)
put_disk(mtd_disks[i]);
} }
module_init(init_mtdblock); module_init(init_mtdblock);
......
...@@ -74,10 +74,10 @@ static void NFTL_setup(struct mtd_info *mtd) ...@@ -74,10 +74,10 @@ static void NFTL_setup(struct mtd_info *mtd)
} }
nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL); nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
gd = kmalloc(sizeof(struct gendisk), GFP_KERNEL); gd = alloc_disk();
if (!nftl || !gd) { if (!nftl || !gd) {
kfree(nftl); kfree(nftl);
kfree(gd); put_disk(gd);
printk(KERN_WARNING "Out of memory for NFTL data structures\n"); printk(KERN_WARNING "Out of memory for NFTL data structures\n");
return; return;
} }
...@@ -92,7 +92,7 @@ static void NFTL_setup(struct mtd_info *mtd) ...@@ -92,7 +92,7 @@ static void NFTL_setup(struct mtd_info *mtd)
if (NFTL_mount(nftl) < 0) { if (NFTL_mount(nftl) < 0) {
printk(KERN_WARNING "Could not mount NFTL device\n"); printk(KERN_WARNING "Could not mount NFTL device\n");
kfree(nftl); kfree(nftl);
kfree(gd); put_disk(gd);
return; return;
} }
...@@ -129,7 +129,6 @@ static void NFTL_setup(struct mtd_info *mtd) ...@@ -129,7 +129,6 @@ static void NFTL_setup(struct mtd_info *mtd)
/* Oh no we don't have nftl->nr_sects = nftl->heads * nftl->cylinders * nftl->sectors; */ /* Oh no we don't have nftl->nr_sects = nftl->heads * nftl->cylinders * nftl->sectors; */
} }
NFTLs[firstfree] = nftl; NFTLs[firstfree] = nftl;
memset(gd, 0, sizeof(struct gendisk));
sprintf(gd->disk_name, "nftl%c", 'a' + firstfree); sprintf(gd->disk_name, "nftl%c", 'a' + firstfree);
gd->major = MAJOR_NR; gd->major = MAJOR_NR;
gd->first_minor = firstfree << NFTL_PARTN_BITS; gd->first_minor = firstfree << NFTL_PARTN_BITS;
...@@ -152,7 +151,7 @@ static void NFTL_unsetup(int i) ...@@ -152,7 +151,7 @@ static void NFTL_unsetup(int i)
if (nftl->EUNtable) if (nftl->EUNtable)
kfree(nftl->EUNtable); kfree(nftl->EUNtable);
del_gendisk(nftl->disk); del_gendisk(nftl->disk);
kfree(nftl->disk); put_disk(nftl->disk);
kfree(nftl); kfree(nftl);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment