Commit d60e29c3 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Linus Torvalds

[PATCH] fix 4K ext2fs support in 2.6 initrd's

The ramdisk_blocksize option has been broken for quite a while in 2.6.
Making an initrd with a 4K ext2 filesystem impossible to use.

After digging into this, the problem turned out to that rd.c was not
setting the hard sector size.  There were a few secondary problems like
i_blkbits was not being set, and the number KiB in uncompressed ext2 images
was not taking into account the block size.

I have also corrected the surrounding comments as they were not just
incorrect but misleading.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent df7d32af
...@@ -349,13 +349,17 @@ static int rd_open(struct inode *inode, struct file *filp) ...@@ -349,13 +349,17 @@ static int rd_open(struct inode *inode, struct file *filp)
if (rd_bdev[unit] == NULL) { if (rd_bdev[unit] == NULL) {
struct block_device *bdev = inode->i_bdev; struct block_device *bdev = inode->i_bdev;
struct address_space *mapping; struct address_space *mapping;
unsigned bsize;
int gfp_mask; int gfp_mask;
inode = igrab(bdev->bd_inode); inode = igrab(bdev->bd_inode);
rd_bdev[unit] = bdev; rd_bdev[unit] = bdev;
bdev->bd_openers++; bdev->bd_openers++;
bdev->bd_block_size = rd_blocksize; bsize = bdev_hardsect_size(bdev);
inode->i_size = get_capacity(rd_disks[unit])<<9; bdev->bd_block_size = bsize;
inode->i_blkbits = blksize_bits(bsize);
inode->i_size = get_capacity(bdev->bd_disk)<<9;
mapping = inode->i_mapping; mapping = inode->i_mapping;
mapping->a_ops = &ramdisk_aops; mapping->a_ops = &ramdisk_aops;
mapping->backing_dev_info = &rd_backing_dev_info; mapping->backing_dev_info = &rd_backing_dev_info;
...@@ -449,6 +453,7 @@ static int __init rd_init(void) ...@@ -449,6 +453,7 @@ static int __init rd_init(void)
goto out_queue; goto out_queue;
blk_queue_make_request(rd_queue[i], &rd_make_request); blk_queue_make_request(rd_queue[i], &rd_make_request);
blk_queue_hardsect_size(rd_queue[i], rd_blocksize);
/* rd_size is given in kB */ /* rd_size is given in kB */
disk->major = RAMDISK_MAJOR; disk->major = RAMDISK_MAJOR;
......
...@@ -122,7 +122,8 @@ identify_ramdisk_image(int fd, int start_block) ...@@ -122,7 +122,8 @@ identify_ramdisk_image(int fd, int start_block)
printk(KERN_NOTICE printk(KERN_NOTICE
"RAMDISK: ext2 filesystem found at block %d\n", "RAMDISK: ext2 filesystem found at block %d\n",
start_block); start_block);
nblocks = le32_to_cpu(ext2sb->s_blocks_count); nblocks = le32_to_cpu(ext2sb->s_blocks_count) <<
le32_to_cpu(ext2sb->s_log_block_size);
goto done; goto done;
} }
...@@ -173,10 +174,15 @@ int __init rd_load_image(char *from) ...@@ -173,10 +174,15 @@ int __init rd_load_image(char *from)
} }
/* /*
* NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so * NOTE NOTE: nblocks is not actually blocks but
* rd_load_image will work only with filesystem BLOCK_SIZE wide! * the number of kibibytes of data to load into a ramdisk.
* So make sure to use 1k blocksize while generating ext2fs * So any ramdisk block size that is a multiple of 1KiB should
* ramdisk-images. * work when the appropriate ramdisk_blocksize is specified
* on the command line.
*
* The default ramdisk_blocksize is 1KiB and it is generally
* silly to use anything else, so make sure to use 1KiB
* blocksize while generating ext2fs ramdisk-images.
*/ */
if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0) if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
rd_blocks = 0; rd_blocks = 0;
...@@ -184,7 +190,7 @@ int __init rd_load_image(char *from) ...@@ -184,7 +190,7 @@ int __init rd_load_image(char *from)
rd_blocks >>= 1; rd_blocks >>= 1;
if (nblocks > rd_blocks) { if (nblocks > rd_blocks) {
printk("RAMDISK: image too big! (%d/%ld blocks)\n", printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n",
nblocks, rd_blocks); nblocks, rd_blocks);
goto done; goto done;
} }
...@@ -211,7 +217,7 @@ int __init rd_load_image(char *from) ...@@ -211,7 +217,7 @@ int __init rd_load_image(char *from)
goto done; goto done;
} }
printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%ld disk%s] into ram disk... ", printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ",
nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : ""); nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
for (i = 0, disk = 1; i < nblocks; i++) { for (i = 0, disk = 1; i < nblocks; i++) {
if (i && (i % devblocks == 0)) { if (i && (i % devblocks == 0)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment