custom RAMDISK formatting problem - Embedded

This is a discussion on custom RAMDISK formatting problem - Embedded ; 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. ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: custom RAMDISK formatting problem

  1. custom RAMDISK formatting problem

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


  2. Re: custom RAMDISK formatting problem

    On Sep 4, 7:54 pm, Rav 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
    > #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 <= 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


+ Reply to Thread