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)
}
partition = kmalloc(sizeof(partition_t), GFP_KERNEL);
disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
disk = alloc_disk();
if (!partition||!disk) {
printk(KERN_WARNING "No memory to scan for FTL on %s\n",
mtd->name);
kfree(partition);
kfree(disk);
put_disk(disk);
return;
}
memset(partition, 0, sizeof(partition_t));
memset(disk, 0, sizeof(struct gendisk));
sprintf(disk->disk_name, "ftl%c", 'a' + device);
disk->major = FTL_MAJOR;
disk->first_minor = device << 4;
......@@ -1255,7 +1254,7 @@ static void ftl_notify_add(struct mtd_info *mtd)
#endif
} else {
kfree(partition);
kfree(disk);
put_disk(disk);
}
}
......@@ -1281,7 +1280,7 @@ static void ftl_notify_remove(struct mtd_info *mtd)
myparts[i]->state = 0;
del_gendisk(myparts[i]->disk);
kfree(myparts[i]->disk);
put_disk(myparts[i]->disk);
kfree(myparts[i]);
myparts[i] = NULL;
}
......
......@@ -42,7 +42,7 @@ static struct mtdblk_dev {
unsigned long cache_offset;
unsigned int cache_size;
enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
struct gendisk disk;
struct gendisk *disk;
} *mtdblks[MAX_MTD_DEVICES];
static spinlock_t mtdblks_lock;
......@@ -263,6 +263,7 @@ static int mtdblock_open(struct inode *inode, struct file *file)
struct mtdblk_dev *mtdblk;
struct mtd_info *mtd;
int dev = minor(inode->i_rdev);
struct gendisk *disk;
DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
......@@ -294,10 +295,9 @@ static int mtdblock_open(struct inode *inode, struct file *file)
spin_unlock(&mtdblks_lock);
mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
if (!mtdblk) {
put_mtd_device(mtd);
return -ENOMEM;
}
disk = alloc_disk();
if (!mtdblk || !disk)
goto Enomem;
memset(mtdblk, 0, sizeof(*mtdblk));
mtdblk->count = 1;
mtdblk->mtd = mtd;
......@@ -308,17 +308,15 @@ static int mtdblock_open(struct inode *inode, struct file *file)
mtdblk->mtd->erasesize) {
mtdblk->cache_size = mtdblk->mtd->erasesize;
mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
if (!mtdblk->cache_data) {
put_mtd_device(mtdblk->mtd);
kfree(mtdblk);
return -ENOMEM;
}
if (!mtdblk->cache_data)
goto Enomem;
}
mtdblk->disk.major = MAJOR_NR;
mtdblk->disk.first_minor = dev;
mtdblk->disk.minor_shift = 0;
mtdblk->disk.fops = &mtd_fops;
sprintf(mtdblk->disk.disk_name, "mtd%d", dev);
disk->major = MAJOR_NR;
disk->first_minor = dev;
disk->minor_shift = 0;
disk->fops = &mtd_fops;
sprintf(disk->disk_name, "mtd%d", dev);
mtdblk->disk = disk;
/* 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)
put_mtd_device(mtdblk->mtd);
vfree(mtdblk->cache_data);
kfree(mtdblk);
put_disk(disk);
return 0;
}
mtdblks[dev] = mtdblk;
set_capacity(&mtdblk->disk, mtdblk->mtd->size/512);
add_disk(&mtdblk->disk);
set_capacity(disk, mtdblk->mtd->size/512);
add_disk(disk);
set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE));
spin_unlock(&mtdblks_lock);
DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
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)
......@@ -367,7 +371,8 @@ static release_t mtdblock_release(struct inode *inode, struct file *file)
/* It was the last usage. Free the device */
mtdblks[dev] = NULL;
spin_unlock(&mtdblks_lock);
del_gendisk(&mtdblk->disk);
del_gendisk(mtdblk->disk);
put_disk(mtdblk->disk);
if (mtdblk->mtd->sync)
mtdblk->mtd->sync(mtdblk->mtd);
put_mtd_device(mtdblk->mtd);
......
......@@ -29,13 +29,13 @@ static int debug = MTDBLOCK_DEBUG;
MODULE_PARM(debug, "i");
#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)
{
struct mtd_info *mtd = NULL;
int dev = minor(inode->i_rdev);
struct gendisk *disk = mtd_disks + dev;
struct gendisk *disk = mtd_disks[dev];
DEBUG(1,"mtdblock_open\n");
......@@ -73,7 +73,7 @@ static release_t mtdblock_release(struct inode *inode, struct file *file)
release_return(-ENODEV);
}
del_gendisk(mtd_disks + dev);
del_gendisk(mtd_disks[dev]);
if (mtd->sync)
mtd->sync(mtd);
......@@ -218,30 +218,42 @@ static struct block_device_operations mtd_fops =
int __init init_mtdblock(void)
{
int err = -ENOMEM;
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++) {
struct gendisk *disk = mtd_disks + i;
struct gendisk *disk = alloc_disk();
if (!disk)
goto out;
disk->major = MAJOR_NR;
disk->first_minor = i;
sprintf(disk->disk_name, "mtdblock%d", i);
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;
out:
while (i--)
put_disk(mtd_disks[i]);
return err;
}
static void __exit cleanup_mtdblock(void)
{
int i;
unregister_blkdev(MAJOR_NR,DEVICE_NAME);
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);
......
......@@ -74,10 +74,10 @@ static void NFTL_setup(struct mtd_info *mtd)
}
nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
gd = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
gd = alloc_disk();
if (!nftl || !gd) {
kfree(nftl);
kfree(gd);
put_disk(gd);
printk(KERN_WARNING "Out of memory for NFTL data structures\n");
return;
}
......@@ -92,7 +92,7 @@ static void NFTL_setup(struct mtd_info *mtd)
if (NFTL_mount(nftl) < 0) {
printk(KERN_WARNING "Could not mount NFTL device\n");
kfree(nftl);
kfree(gd);
put_disk(gd);
return;
}
......@@ -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; */
}
NFTLs[firstfree] = nftl;
memset(gd, 0, sizeof(struct gendisk));
sprintf(gd->disk_name, "nftl%c", 'a' + firstfree);
gd->major = MAJOR_NR;
gd->first_minor = firstfree << NFTL_PARTN_BITS;
......@@ -152,7 +151,7 @@ static void NFTL_unsetup(int i)
if (nftl->EUNtable)
kfree(nftl->EUNtable);
del_gendisk(nftl->disk);
kfree(nftl->disk);
put_disk(nftl->disk);
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