diff options
Diffstat (limited to 'init/do_mounts_rd.c')
| -rw-r--r-- | init/do_mounts_rd.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 6e1ee6987c7..a8227022e3a 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -1,10 +1,19 @@ +/* + * Many of the syscalls used in this file expect some of the arguments + * to be __user pointers not __kernel pointers. To limit the sparse + * noise, turn off sparse checking for this file. + */ +#ifdef __CHECKER__ +#undef __CHECKER__ +#warning "Sparse checking disabled for this file" +#endif #include <linux/kernel.h> #include <linux/fs.h> #include <linux/minix_fs.h> #include <linux/ext2_fs.h> #include <linux/romfs_fs.h> -#include <linux/cramfs_fs.h> +#include <uapi/linux/cramfs_fs.h> #include <linux/initrd.h> #include <linux/string.h> #include <linux/slab.h> @@ -48,26 +57,30 @@ static int __init crd_load(int in_fd, int out_fd, decompress_fn deco); * cramfs * squashfs * gzip + * bzip2 + * lzma + * xz + * lzo + * lz4 */ static int __init identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) { const int size = 512; struct minix_super_block *minixsb; - struct ext2_super_block *ext2sb; struct romfs_super_block *romfsb; struct cramfs_super *cramfsb; struct squashfs_super_block *squashfsb; int nblocks = -1; unsigned char *buf; const char *compress_name; + unsigned long n; buf = kmalloc(size, GFP_KERNEL); if (!buf) - return -1; + return -ENOMEM; minixsb = (struct minix_super_block *) buf; - ext2sb = (struct ext2_super_block *) buf; romfsb = (struct romfs_super_block *) buf; cramfsb = (struct cramfs_super *) buf; squashfsb = (struct squashfs_super_block *) buf; @@ -120,6 +133,20 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) } /* + * Read 512 bytes further to check if cramfs is padded + */ + sys_lseek(fd, start_block * BLOCK_SIZE + 0x200, 0); + sys_read(fd, buf, size); + + if (cramfsb->magic == CRAMFS_MAGIC) { + printk(KERN_NOTICE + "RAMDISK: cramfs filesystem found at block %d\n", + start_block); + nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS; + goto done; + } + + /* * Read block 1 to test for minix and ext2 superblock */ sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); @@ -136,12 +163,12 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) } /* Try ext2 */ - if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { + n = ext2_image_size(buf); + if (n) { printk(KERN_NOTICE "RAMDISK: ext2 filesystem found at block %d\n", start_block); - nblocks = le32_to_cpu(ext2sb->s_blocks_count) << - le32_to_cpu(ext2sb->s_log_block_size); + nblocks = n; goto done; } @@ -164,11 +191,11 @@ int __init rd_load_image(char *from) char *buf = NULL; unsigned short rotate = 0; decompress_fn decompressor = NULL; -#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) +#if !defined(CONFIG_S390) char rotator[4] = { '|' , '/' , '-' , '\\' }; #endif - out_fd = sys_open((const char __user __force *) "/dev/ram", O_RDWR, 0); + out_fd = sys_open("/dev/ram", O_RDWR, 0); if (out_fd < 0) goto out; @@ -250,7 +277,7 @@ int __init rd_load_image(char *from) } sys_read(in_fd, buf, BLOCK_SIZE); sys_write(out_fd, buf, BLOCK_SIZE); -#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) +#if !defined(CONFIG_S390) if (!(i % 16)) { printk("%c\b", rotator[rotate & 0x3]); rotate++; @@ -267,7 +294,7 @@ noclose_input: sys_close(out_fd); out: kfree(buf); - sys_unlink((const char __user __force *) "/dev/ram"); + sys_unlink("/dev/ram"); return res; } @@ -320,6 +347,13 @@ static int __init crd_load(int in_fd, int out_fd, decompress_fn deco) int result; crd_infd = in_fd; crd_outfd = out_fd; + + if (!deco) { + pr_emerg("Invalid ramdisk decompression routine. " + "Select appropriate config option.\n"); + panic("Could not decompress initial ramdisk image."); + } + result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error); if (decompress_error) result = 1; |
