Re: ramdisk-support

From: Mike Galbraith (mikeg@weiden.de)
Date: Wed Feb 23 2000 - 11:03:26 EST


On Sun, 20 Feb 2000, Ralf Burger wrote:

> hi all,
>
> maybe, I'm bothering you, but since 2.3.10 I've tried to build a working
> root/bootdisk - every version results in an Oops :(
>
> I'm tired now...
>
> I'm not a c-coder, but some weeks ago, I've posted informations about
> this bug-behaviour - but got no response.
> So, what else can I do ?
> In a private mail, Alan Cox answer was "The ramdisk stuff is still rather
> broken".
>
> Is there anybody working on this subject?
> If so, please mail me!

Hi,

The below seems to work ok here. I didn't build floppies, but think
it should work well enough for that.. an initrd works. If 'works' is
good enough for now (correctness could be somewhat.. absent), give it
a try.

        -Mike

--- linux-2.3.47.test/arch/i386/mm/init.c.org Wed Feb 23 13:20:08 2000
+++ linux-2.3.47.test/arch/i386/mm/init.c Wed Feb 23 13:20:58 2000
@@ -637,13 +637,14 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
+ if (start < end)
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
         for (; start < end; start += PAGE_SIZE) {
                 ClearPageReserved(mem_map + MAP_NR(start));
                 set_page_count(mem_map+MAP_NR(start), 1);
                 free_page(start);
                 totalram_pages++;
         }
- printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
 }
 #endif
 
--- linux-2.3.47.test/fs/block_dev.c.org Wed Feb 23 15:34:47 2000
+++ linux-2.3.47.test/fs/block_dev.c Wed Feb 23 15:35:02 2000
@@ -630,7 +630,7 @@
         /* syncing will go here */
         if (kind == BDEV_FILE || kind == BDEV_FS)
                 fsync_dev(rdev);
- if (atomic_dec_and_test(&bdev->bd_openers)) {
+ if (atomic_dec_and_test(&bdev->bd_openers) && MAJOR(rdev) != RAMDISK_MAJOR) {
                 /* invalidating buffers will go here */
                 invalidate_buffers(rdev);
         }
--- linux-2.3.47.test/drivers/block/rd.c.org Wed Feb 23 08:54:04 2000
+++ linux-2.3.47.test/drivers/block/rd.c Wed Feb 23 16:34:43 2000
@@ -126,7 +126,7 @@
 int rd_prompt = 1; /* 1 = prompt for RAM disk, 0 = don't prompt */
 int rd_image_start = 0; /* starting block # of image */
 #ifdef CONFIG_BLK_DEV_INITRD
-unsigned long initrd_start,initrd_end;
+unsigned long initrd_start = 0,initrd_end = 0;
 int mount_initrd = 1; /* zero if initrd should not be mounted */
 int initrd_below_start_ok = 0;
 
@@ -293,11 +293,15 @@
 
         switch (cmd) {
                 case BLKFLSBUF:
- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
                         /* special: we want to release the ramdisk memory,
                            it's not like with the other blockdevices where
                            this ioctl only flushes away the buffer cache. */
+ if ((atomic_read(&inode->i_bdev->bd_openers) > 1))
+ return -EBUSY;
                         destroy_buffers(inode->i_rdev);
+ rd_blocksizes[minor] = 0;
                         break;
 
                  case BLKGETSIZE: /* Return device size */
@@ -338,6 +342,8 @@
         extern void free_initrd_mem(unsigned long, unsigned long);
 
         if (--initrd_users) return 0;
+ blkdev_put(inode->i_bdev, BDEV_FILE);
+ iput(inode);
         free_initrd_mem(initrd_start, initrd_end);
         initrd_start = 0;
         return 0;
@@ -358,7 +364,6 @@
         if (DEVICE_NR(inode->i_rdev) == INITRD_MINOR) {
                 if (!initrd_start) return -ENODEV;
                 initrd_users++;
- filp->f_op = &initrd_fops;
                 return 0;
         }
 #endif
@@ -366,7 +371,6 @@
         if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
                 return -ENXIO;
 
- filp->f_op = &def_blk_fops;
         MOD_INC_USE_COUNT;
 
         return 0;
@@ -395,6 +399,8 @@
         devfs_unregister (devfs_handle);
         unregister_blkdev( MAJOR_NR, "ramdisk" );
         blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+ blksize_size[MAJOR_NR] = NULL;
+ blk_size[MAJOR_NR] = NULL;
 }
 
 /* This is the registration and initialization section of the RAM disk driver */
@@ -432,7 +438,6 @@
 
         hardsect_size[MAJOR_NR] = rd_hardsec; /* Size of the RAM disk blocks */
         blksize_size[MAJOR_NR] = rd_blocksizes; /* Avoid set_blocksize() check */
- blk_size[MAJOR_NR] = rd_kbsize; /* Size of the RAM disk in kB */
 
         for (i = 0; i < NUM_RAMDISKS; i++)
                 register_disk(NULL, MKDEV(MAJOR_NR,i), 1, &fd_fops, rd_size<<1);
@@ -442,6 +447,8 @@
         register_disk(NULL, MKDEV(MAJOR_NR,INITRD_MINOR), 1, &fd_fops, rd_size<<1);
 #endif
 
+ blk_size[MAJOR_NR] = rd_kbsize; /* Size of the RAM disk in kB */
+
                 /* rd_size is given in kB */
         printk("RAMDISK driver initialized: "
                "%d RAM disks of %dK size %d blocksize\n",
@@ -584,26 +591,28 @@
 
         ram_device = MKDEV(MAJOR_NR, unit);
 
+ if ((inode = get_empty_inode()) == NULL)
+ return;
         memset(&infile, 0, sizeof(infile));
         memset(&in_dentry, 0, sizeof(in_dentry));
- inode = get_empty_inode();
- inode->i_rdev = device;
- inode->i_bdev = bdget(kdev_t_to_nr(device));
         infile.f_mode = 1; /* read only */
         infile.f_dentry = &in_dentry;
         in_dentry.d_inode = inode;
+ infile.f_op = &initrd_fops;
+ init_special_inode(inode, S_IFBLK | S_IRUSR, kdev_t_to_nr(device));
 
+ if ((out_inode = get_empty_inode()) == NULL)
+ goto free_inode;
         memset(&outfile, 0, sizeof(outfile));
         memset(&out_dentry, 0, sizeof(out_dentry));
- out_inode = get_empty_inode();
- out_inode->i_rdev = ram_device;
- out_inode->i_bdev = bdget(kdev_t_to_nr(ram_device));
         outfile.f_mode = 3; /* read/write */
         outfile.f_dentry = &out_dentry;
         out_dentry.d_inode = out_inode;
+ outfile.f_op = &def_blk_fops;
+ init_special_inode(out_inode, S_IFBLK | S_IRUSR | S_IWUSR, kdev_t_to_nr(ram_device));
 
         if (blkdev_open(inode, &infile) != 0)
- goto free_inodes;
+ goto free_inode;
         if (blkdev_open(out_inode, &outfile) != 0)
                 goto free_inodes;
 
@@ -697,9 +706,12 @@
         if (infile.f_op->release)
                 infile.f_op->release(inode, &infile);
         set_fs(fs);
-free_inodes:
- iput(inode);
+ return;
+free_inodes: /* free inodes on error */
         iput(out_inode);
+ blkdev_put(inode->i_bdev, BDEV_FILE);
+free_inode:
+ iput(inode);
 }
 
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Feb 23 2000 - 21:00:33 EST