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