Re: custom RAMDISK formatting problem
- From: Janaka <janakas@xxxxxxxxxxxx>
- Date: Tue, 04 Sep 2007 16:43:30 -0700
On Sep 4, 7:54 pm, Rav <rav.tech...@xxxxxxxxx> wrote:
Hi,
Quite sometime ago, i was trying to develop one simple, non interrupt
diven workable pseudo disk driver for the ramdisk. I downloaded a code
form internet and modified it according to my requirements.
At that time it worked fine. I was able to give the ramdisk size
during the module load time and then format it using mke2fs and then
mount it. But, now the same driver module, when i try to load gets
loaded, but during formatting using mke2fs it gives an error message
saying:
'Not enough space to build proposed filesystem while setting up
superblock.'
What does this thing mean? Please help.
The Driver Code:
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("DESD");
static int major_num = 0;
module_param(major_num, int, 0);
static int hardsect_size = 512;
module_param(hardsect_size, int, 0);
static int dev_size = 4096;
module_param(dev_size, int, S_IRUGO);
static struct request_queue *Queue;
static struct pseudo_device {
unsigned long size;
spinlock_t lock;
u8 *data;
struct gendisk *gd;
} pseudoDev;
static void pseudoDev_transfer(struct pseudo_device *dev, unsigned
long sector, unsigned long nsect, char *buffer, int write)
{
unsigned long offset = sector*hardsect_size;
unsigned long nbytes = nsect*hardsect_size;
if ((offset + nbytes) > dev->size) {
printk (KERN_NOTICE "PSEUDO_DEV: Beyond-end write (%ld %ld)\n",
offset, nbytes);
return;
}
if (write)
memcpy(dev->data + offset, buffer, nbytes);
else
memcpy(buffer, dev->data + offset, nbytes);
}
static void pseudoDev_request(request_queue_t *q)
{
struct request *req;
while ((req = elv_next_request(q)) != NULL) {
if (! blk_fs_request(req)) {
printk (KERN_NOTICE "Skip non-CMD request\n");
end_request(req, 0);
continue;
}
pseudoDev_transfer(&pseudoDev, req->sector, req->current_nr_sectors,
req->buffer, rq_data_dir(req));
end_request(req, 1);
}
}
int pseudoDev_ioctl (struct inode *inode, struct file *filp, unsigned
int cmd, unsigned long arg)
{
long size;
struct hd_geometry geo;
switch(cmd) {
case HDIO_GETGEO:
size = pseudoDev.size;
geo.cylinders = (size & ~0x3f) >> 6;
geo.heads = 4;
geo.sectors = 16;
geo.start = 4;
if (copy_to_user((void *) arg, &geo, sizeof(geo)))
return -EFAULT;
return 0;
}
return -ENOTTY;
}
static struct block_device_operations pseudoDev_ops = {
.owner = "AVARA",
.ioctl = pseudoDev_ioctl
};
static int __init pseudoDev_init(void)
{
pseudoDev.size = dev_size;
spin_lock_init(&pseudoDev.lock);
pseudoDev.data = vmalloc(pseudoDev.size);
if (pseudoDev.data == NULL)
return -ENOMEM;
else
printk(KERN_INFO "vmalloc success\n");
printk(KERN_INFO "The size allocated with vmalloc: %lu \n",
pseudoDev.size);
Queue = blk_init_queue(pseudoDev_request, &pseudoDev.lock);
if (Queue == NULL)
goto out;
blk_queue_hardsect_size(Queue, hardsect_size);
major_num = register_blkdev(major_num, "RAMDISK");
if (major_num <= 0) {
printk(KERN_WARNING "PSEUDO_DEV: unable to get major number\n");
goto out;
}
else printk(KERN_INFO "MAJOR NO: %d", major_num);
pseudoDev.gd = alloc_disk(16);
if (! pseudoDev.gd)
goto out_unregister;
pseudoDev.gd->major = major_num;
pseudoDev.gd->first_minor = 0;
pseudoDev.gd->fops = &pseudoDev_ops;
pseudoDev.gd->private_data = &pseudoDev;
strcpy (pseudoDev.gd->disk_name, "PSEUDO_DEV");
set_capacity(pseudoDev.gd, dev_size/hardsect_size);
pseudoDev.gd->queue = Queue;
add_disk(pseudoDev.gd);
return 0;
out_unregister:
unregister_blkdev(major_num, "RAMDISK");
out:
vfree(pseudoDev.data);
return -ENOMEM;
}
static void __exit pseudoDev_exit(void)
{
del_gendisk(pseudoDev.gd);
put_disk(pseudoDev.gd);
unregister_blkdev(major_num, "RAMDISK");
blk_cleanup_queue(Queue);
vfree(pseudoDev.data);
}
module_init(pseudoDev_init);
module_exit(pseudoDev_exit);
Are you sure the problem is not with the number of Blocks,
ReservedBlocks or the Inodes that you specify during load ?
For my ramdrive needs I use the generic linux ramdrive (eg: mount -t
ramfs ...) which works wonders. And its dynamic, hence grows and
srinks according to usage (you can make it static size as well, if you
want).
Cheers
J
.
- References:
- custom RAMDISK formatting problem
- From: Rav
- custom RAMDISK formatting problem
- Prev by Date: custom RAMDISK formatting problem
- Next by Date: WTD: Open Source drivers for MAX3421E
- Previous by thread: custom RAMDISK formatting problem
- Next by thread: WTD: Open Source drivers for MAX3421E
- Index(es):
Relevant Pages
|