Re: custom RAMDISK formatting problem



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

.



Relevant Pages