Messages in this thread Patch in this message |  | | | Date | Sun, 27 Feb 2000 17:00:35 +0100 (CET) | | From | Frank Bernard <> | | 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); }
|  |