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 #include #include
#include #include #include #include #include #include #include #include
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 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);