diff -Nru linux-2.4.20-pre10-mjc1/fs/block_dev.c linux-2.4.20-pre10-mjc2/fs/block_dev.c
--- linux-2.4.20-pre10-mjc1/fs/block_dev.c	2002-10-23 22:55:41.000000000 -0400
+++ linux-2.4.20-pre10-mjc2/fs/block_dev.c	2002-10-25 00:11:55.000000000 -0400
@@ -19,6 +19,9 @@
 #include <linux/highmem.h>
 #include <linux/blkdev.h>
 #include <linux/module.h>
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/blk.h>
+#endif
 
 #include <asm/uaccess.h>
 
@@ -571,7 +574,25 @@
 		if (bdev->bd_op->open)
 			ret = bdev->bd_op->open(inode, file);
 		if (!ret) {
-			bdev->bd_openers++;
+			/*
+			 * INITRD is special, since its ->open succeeds
+			 * but it has no MINOR slot for the softblocksize
+			 * (despite the MAJOR slot is initialized),
+			 * so we cannot run set_blocksize() on the initrd
+			 * or we'd corrupt memory randomly. Hackish check
+			 * but optimal (so no need of 251 entries
+			 * in the ramdisk blocksize array).
+			 */
+			if (!bdev->bd_openers++
+#ifdef CONFIG_BLK_DEV_INITRD
+			    && dev != mk_kdev(RAMDISK_MAJOR, INITRD_MINOR)
+#endif
+			    ) {
+				int blksize = BLOCK_SIZE;
+				if (file->f_flags & O_DIRECT)
+					blksize = get_hardsect_size(dev);
+				set_blocksize(dev, blksize);
+			}
 			bdev->bd_inode->i_size = blkdev_size(dev);
 			bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev));
 		} else {
