custom RAMDISK formatting problem

Sep 04, 2007 1 Replies

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



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

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required