lkml.org 
[lkml]   [2000]   [Feb]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH 2.3.48] initrd fix (Mike Galbraith)

Linus,

please apply the attached fix to one of the next kernel versions.
With it the broken initrd now works again.

It's originally from Mike Galbraith <mikeg@weiden.de>, I've just done the
line numbering for 2.3.48 and the "diff -ur" to apply it easier.

Mit freundlichen Grüßen / kind regards

Frank

Frank Bernard Informationstechnik GmbH
vanity +49 700 FIREWALL (0700 FIREWALL) phone : +49 69 477169
Dipl.-Inform. Frank Bernard fax : +49 69 47885616
Wehrheimerstr. 9 email : fb@fbit.de
60389 Frankfurt www : http://www.fbit.de
Germany http://www.linuxwall.de

diff -ur linux-2.3.48-pre3/arch/i386/mm/init.c linux/arch/i386/mm/init.c
--- linux-2.3.48-pre3/arch/i386/mm/init.c Sat Feb 26 19:05:11 2000
+++ linux/arch/i386/mm/init.c Sat Feb 26 18:55:16 2000
@@ -631,13 +631,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

diff -ur linux-2.3.48-pre3/drivers/block/rd.c linux/drivers/block/rd.c
--- linux-2.3.48-pre3/drivers/block/rd.c Thu Feb 17 00:42:05 2000
+++ linux/drivers/block/rd.c Sat Feb 26 18:55:16 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);
}


diff -ur linux-2.3.48-pre3/fs/block_dev.c linux/fs/block_dev.c
--- linux-2.3.48-pre3/fs/block_dev.c Sat Feb 26 19:05:17 2000
+++ linux/fs/block_dev.c Sat Feb 26 18:55:16 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);
}
\
 
 \ /
  Last update: 2005-03-22 13:56    [from the cache]
©2003-2011 Jasper Spaans