public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH][2/2] SquashFS
@ 2005-03-14 16:30 Phillip Lougher
  2005-03-15  1:06 ` Andrew Morton
                   ` (2 more replies)
  0 siblings, 3 replies; 36+ messages in thread
From: Phillip Lougher @ 2005-03-14 16:30 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Greg KH, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



[-- Attachment #2: patch2 --]
[-- Type: text/plain, Size: 44263 bytes --]

diff --new-file -urp linux-2.6.11.3/fs/Kconfig linux-2.6.11.3-squashfs/fs/Kconfig
--- linux-2.6.11.3/fs/Kconfig	2005-03-13 06:44:28.000000000 +0000
+++ linux-2.6.11.3-squashfs/fs/Kconfig	2005-03-14 00:53:28.011572040 +0000
@@ -1170,6 +1170,45 @@ config CRAMFS
 
 	  If unsure, say N.
 
+config SQUASHFS
+	tristate "SquashFS 2.1 - Squashed file system support"
+	select ZLIB_INFLATE
+	help
+	  Saying Y here includes support for SquashFS 2.1 (Compressed Read-Only
+	  File System).  SquashFS is a highly compressed read-only filesystem
+	  for Linux.  It uses zlib compression to compress both files, inodes
+	  and directories.  Inodes in the system are very small and all blocks
+	  are packed to minimise data overhead. Block sizes greater than 4K are
+	  supported up to a maximum of 64K.
+
+	  SquashFS is intended for general read-only filesystem use, for
+	  archival use (i.e. in cases where a .tar.gz file may be used), and in
+	  embedded systems where low overhead is needed.  Further information
+	  and filesystem tools are available from
+	  http://squashfs.sourceforge.net.
+
+	  If you want to compile this as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want),
+	  say M here and read <file:Documentation/modules.txt>.  The module
+	  will be called squashfs.  Note that the root file system (the one
+	  containing the directory /) cannot be compiled as a module.
+
+	  If unsure, say N.
+
+config SQUASHFS_1_0_COMPATIBILITY
+	bool "Include support for mounting SquashFS 1.x filesystems"
+	depends on SQUASHFS
+	default n
+	help
+	  Saying Y here will include support for mounting SquashFS 1.x
+	  filesystems.  SquashFS 1.x filesystems were generated by earlier
+	  versions of SquashFS, but there are quite a few systems around
+	  which still use them.  If you're going to be mounting
+	  third party generated SquashFS filesystems and if you're
+	  not sure the filesystems are 2.x, then say it's okay to say Y here.
+
+	  If unsure, say N.
+
 config VXFS_FS
 	tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
 	help
diff --new-file -urp linux-2.6.11.3/fs/Makefile linux-2.6.11.3-squashfs/fs/Makefile
--- linux-2.6.11.3/fs/Makefile	2005-03-13 06:44:28.000000000 +0000
+++ linux-2.6.11.3-squashfs/fs/Makefile	2005-03-14 00:53:28.017571128 +0000
@@ -52,6 +52,7 @@ obj-$(CONFIG_EXT3_FS)		+= ext3/ # Before
 obj-$(CONFIG_JBD)		+= jbd/
 obj-$(CONFIG_EXT2_FS)		+= ext2/
 obj-$(CONFIG_CRAMFS)		+= cramfs/
+obj-$(CONFIG_SQUASHFS)		+= squashfs/
 obj-$(CONFIG_RAMFS)		+= ramfs/
 obj-$(CONFIG_HUGETLBFS)		+= hugetlbfs/
 obj-$(CONFIG_CODA_FS)		+= coda/
diff --new-file -urp linux-2.6.11.3/fs/squashfs/Makefile linux-2.6.11.3-squashfs/fs/squashfs/Makefile
--- linux-2.6.11.3/fs/squashfs/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11.3-squashfs/fs/squashfs/Makefile	2005-03-14 00:53:28.043567176 +0000
@@ -0,0 +1,9 @@
+#
+# Makefile for the linux squashfs routines.
+#
+
+obj-$(CONFIG_SQUASHFS) += squashfs.o
+
+squashfs-y := inode.o
+
+squashfs-$(CONFIG_SQUASHFS_1_0_COMPATIBILITY) += squashfs1_0.o
diff --new-file -urp linux-2.6.11.3/fs/squashfs/squashfs1_0.c linux-2.6.11.3-squashfs/fs/squashfs/squashfs1_0.c
--- linux-2.6.11.3/fs/squashfs/squashfs1_0.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11.3-squashfs/fs/squashfs/squashfs1_0.c	2005-03-14 00:53:28.052565808 +0000
@@ -0,0 +1,439 @@
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005
+ * Phillip Lougher <phillip@lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * squashfs1_0.c
+ */
+#include <linux/types.h>
+#include <linux/squashfs_fs.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/squashfs_fs_sb.h>
+#include <linux/squashfs_fs_i.h>
+#include <linux/buffer_head.h>
+#include <linux/vfs.h>
+#include <linux/init.h>
+#include <linux/dcache.h>
+#include <asm/uaccess.h>
+#include <linux/wait.h>
+#include <asm/semaphore.h>
+#include <linux/zlib.h>
+#include <linux/blkdev.h>
+#include <linux/vmalloc.h>
+#include "squashfs.h"
+
+static int squashfs_readpage_lessthan4K(struct file *file, struct page *page);
+static struct inode *squashfs_iget_1(struct super_block *s, squashfs_inode
+				inode);
+static unsigned int read_blocklist_1(struct inode *inode, int index, int
+				readahead_blks, char *block_list,
+				unsigned short **block_p, unsigned int *bsize);
+
+static struct address_space_operations squashfs_aops_lessthan4K = {
+	.readpage = squashfs_readpage_lessthan4K
+};
+
+int squashfs_1_0_supported(squashfs_sb_info *msBlk)
+{
+	msBlk->iget = squashfs_iget_1;
+	msBlk->read_blocklist = read_blocklist_1;
+	msBlk->sBlk.block_size = msBlk->sBlk.block_size_1;
+
+	return 1;
+}
+
+#define SIZE 256
+static int squashfs_readpage_lessthan4K(struct file *file, struct page *page)
+{
+	struct inode *inode = page->mapping->host;
+	squashfs_sb_info *msBlk = (squashfs_sb_info *)inode->i_sb->s_fs_info;
+	squashfs_super_block *sBlk = &msBlk->sBlk;
+	unsigned char block_list[SIZE];
+	unsigned short *block_listp, block, bytes = 0;
+	int index = page->index << (PAGE_CACHE_SHIFT - sBlk->block_log);
+	int file_blocks = ((inode->i_size - 1) >> sBlk->block_log) + 1;
+	int readahead_blks = 1 << (PAGE_CACHE_SHIFT - sBlk->block_log);
+ 	void *pageaddr = kmap(page);
+	
+	int i_end = index + (1 << (PAGE_CACHE_SHIFT - sBlk->block_log));
+	int byte;
+
+	TRACE("Entered squashfs_readpage_lessthan4K, page index %x, start "
+					"block %x\n", (unsigned int)
+					page->index, SQUASHFS_I(inode)->
+					start_block);
+	block = read_blocklist_1(inode, index, readahead_blks, block_list,
+					&block_listp, NULL);
+	if (i_end > file_blocks)
+		i_end = file_blocks;
+
+	while (index < i_end) {
+		int c_byte = !SQUASHFS_COMPRESSED(*block_listp) ?
+					SQUASHFS_COMPRESSED_SIZE(*block_listp) |
+					SQUASHFS_COMPRESSED_BIT_BLOCK :
+					*block_listp;
+
+		if (!(byte = squashfs_read_data(inode->i_sb, pageaddr, block,
+					c_byte, NULL))) {
+			ERROR("Unable to read page, block %x, size %x\n", block,
+					*block_listp);
+			goto skip_read;
+		}
+		block += SQUASHFS_COMPRESSED_SIZE(*block_listp);
+		pageaddr += byte;
+		bytes += byte;
+		index ++;
+		block_listp ++;
+	}
+skip_read:
+	memset(pageaddr, 0, PAGE_CACHE_SIZE - bytes);
+	kunmap(page);
+	flush_dcache_page(page);
+	SetPageUptodate(page);
+	unlock_page(page);
+	return 0;
+}
+
+
+static unsigned int read_blocklist_1(struct inode *inode, int index, int
+				readahead_blks, char *block_list,
+				unsigned short **block_p, unsigned int *bsize)
+{
+	squashfs_sb_info *msBlk = (squashfs_sb_info *)inode->i_sb->s_fs_info;
+	unsigned short *block_listp;
+	int i = 0;
+	int block_ptr = SQUASHFS_I(inode)->block_list_start;
+	int offset = SQUASHFS_I(inode)->offset;
+	unsigned int block = SQUASHFS_I(inode)->start_block;
+
+	for (;;) {
+		int blocks = (index + readahead_blks - i);
+
+		if (blocks > (SIZE >> 1)) {
+			if ((index - i) <= (SIZE >> 1))
+				blocks = index - i;
+			else
+				blocks = SIZE >> 1;
+		}
+
+		if (msBlk->swap) {
+			unsigned char sblock_list[SIZE];
+
+			if (!squashfs_get_cached_block(inode->i_sb, (char *)
+					sblock_list, block_ptr, offset,
+					blocks << 1, &block_ptr, &offset)) {
+				ERROR("Unable to read block list [%d:%x]\n",
+					block_ptr, offset);
+				return 0;
+			}
+			SQUASHFS_SWAP_SHORTS(((unsigned short *)block_list),
+					((unsigned short *)sblock_list),
+					blocks);
+		} else
+			if (!squashfs_get_cached_block(inode->i_sb, (char *)
+					block_list, block_ptr, offset,
+					blocks << 1, &block_ptr, &offset)) {
+				ERROR("Unable to read block list [%d:%x]\n",
+					block_ptr, offset);
+				return 0;
+			}
+
+		for (block_listp = (unsigned short *) block_list; i < index &&
+					blocks; i ++, block_listp ++, blocks --)
+			block += SQUASHFS_COMPRESSED_SIZE(*block_listp);
+		if (blocks >= readahead_blks)
+			break;
+	}
+	if (bsize)
+		*bsize = SQUASHFS_COMPRESSED_SIZE(*block_listp) |
+					(!SQUASHFS_COMPRESSED(*block_listp) ?
+					SQUASHFS_COMPRESSED_BIT_BLOCK : 0);
+	else
+		*block_p = block_listp;
+	return block;
+}
+
+
+static struct inode *squashfs_new_inode(struct super_block *s,
+			squashfs_base_inode_header_1 *inodeb, unsigned int ino)
+{
+	squashfs_sb_info *msBlk = (squashfs_sb_info *)s->s_fs_info;
+	squashfs_super_block *sBlk = &msBlk->sBlk;
+	struct inode *i = new_inode(s);
+
+	if (i) {
+		i->i_ino = ino;
+		i->i_nlink = 1;
+		i->i_mtime.tv_sec = sBlk->mkfs_time;
+		i->i_atime.tv_sec = sBlk->mkfs_time;
+		i->i_ctime.tv_sec = sBlk->mkfs_time;
+		i->i_mode = inodeb->mode;
+		i->i_size = 0;
+		if (inodeb->inode_type != SQUASHFS_IPC_TYPE)
+			i->i_uid = msBlk->uid[((inodeb->inode_type - 1) /
+				SQUASHFS_TYPES) * 16 + inodeb->uid];
+	}
+
+	return i;
+}
+
+static struct inode *squashfs_iget_1(struct super_block *s, squashfs_inode
+inode)
+{
+	struct inode *i;
+	squashfs_sb_info *msBlk = (squashfs_sb_info *)s->s_fs_info;
+	squashfs_super_block *sBlk = &msBlk->sBlk;
+	unsigned int block = SQUASHFS_INODE_BLK(inode) +
+			sBlk->inode_table_start;
+	unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
+	unsigned int ino = SQUASHFS_MK_VFS_INODE(block -
+			sBlk->inode_table_start, offset);
+	unsigned int next_block, next_offset;
+	squashfs_base_inode_header_1 inodeb;
+
+	TRACE("Entered squashfs_iget_1\n");
+
+	if (msBlk->swap) {
+		squashfs_base_inode_header_1 sinodeb;
+
+		if (!squashfs_get_cached_block(s, (char *) &sinodeb, block,
+						offset, sizeof(sinodeb),
+						&next_block, &next_offset))
+			goto failed_read;
+		SQUASHFS_SWAP_BASE_INODE_HEADER_1(&inodeb, &sinodeb,
+						sizeof(sinodeb));
+	} else
+		if (!squashfs_get_cached_block(s, (char *) &inodeb, block,
+						offset, sizeof(inodeb),
+						&next_block, &next_offset))
+			goto failed_read;
+
+	switch(inodeb.inode_type == SQUASHFS_IPC_TYPE ? SQUASHFS_IPC_TYPE :
+			(inodeb.inode_type - 1) % SQUASHFS_TYPES + 1) {
+		case SQUASHFS_FILE_TYPE: {
+			squashfs_reg_inode_header_1 inodep;
+
+			if (msBlk->swap) {
+				squashfs_reg_inode_header_1 sinodep;
+
+				if (!squashfs_get_cached_block(s, (char *)
+						&sinodep, block, offset,
+						sizeof(sinodep), &next_block,
+						&next_offset))
+					goto failed_read;
+				SQUASHFS_SWAP_REG_INODE_HEADER_1(&inodep,
+						&sinodep);
+			} else
+				if (!squashfs_get_cached_block(s, (char *)
+						&inodep, block, offset,
+						sizeof(inodep), &next_block,
+						&next_offset))
+					goto failed_read;
+
+			if ((i = squashfs_new_inode(s, &inodeb, ino)) == NULL)
+				goto failed_read1;
+			i->i_size = inodep.file_size;
+			i->i_fop = &generic_ro_fops;
+			i->i_mode |= S_IFREG;
+			i->i_mtime.tv_sec = inodep.mtime;
+			i->i_atime.tv_sec = inodep.mtime;
+			i->i_ctime.tv_sec = inodep.mtime;
+			i->i_blocks = ((i->i_size - 1) >> 9) + 1;
+			i->i_blksize = PAGE_CACHE_SIZE;
+			SQUASHFS_I(i)->u.s1.fragment_start_block =
+							SQUASHFS_INVALID_BLK;
+			SQUASHFS_I(i)->u.s1.fragment_offset = 0;
+			SQUASHFS_I(i)->start_block = inodep.start_block;
+			SQUASHFS_I(i)->block_list_start = next_block;
+			SQUASHFS_I(i)->offset = next_offset;
+			if (sBlk->block_size > 4096)
+				i->i_data.a_ops = &squashfs_aops;
+			else if (sBlk->block_size == 4096)
+				i->i_data.a_ops = &squashfs_aops_4K;
+			else
+				i->i_data.a_ops = &squashfs_aops_lessthan4K;
+
+			TRACE("File inode %x:%x, start_block %x, "
+					"block_list_start %x, offset %x\n",
+					SQUASHFS_INODE_BLK(inode), offset,
+					inodep.start_block, next_block,
+					next_offset);
+			break;
+		}
+		case SQUASHFS_DIR_TYPE: {
+			squashfs_dir_inode_header_1 inodep;
+
+			if (msBlk->swap) {
+				squashfs_dir_inode_header_1 sinodep;
+
+				if (!squashfs_get_cached_block(s, (char *)
+						&sinodep, block, offset,
+						sizeof(sinodep), &next_block,
+						&next_offset))
+					goto failed_read;
+				SQUASHFS_SWAP_DIR_INODE_HEADER_1(&inodep,
+								&sinodep);
+			} else
+				if (!squashfs_get_cached_block(s, (char *)
+						&inodep, block, offset,
+						sizeof(inodep), &next_block,
+						&next_offset))
+					goto failed_read;
+
+			if ((i = squashfs_new_inode(s, &inodeb, ino)) == NULL)
+				goto failed_read1;
+			i->i_size = inodep.file_size;
+			i->i_op = &squashfs_dir_inode_ops;
+			i->i_fop = &squashfs_dir_ops;
+			i->i_mode |= S_IFDIR;
+			i->i_mtime.tv_sec = inodep.mtime;
+			i->i_atime.tv_sec = inodep.mtime;
+			i->i_ctime.tv_sec = inodep.mtime;
+			SQUASHFS_I(i)->start_block = inodep.start_block;
+			SQUASHFS_I(i)->offset = inodep.offset;
+			SQUASHFS_I(i)->u.s2.directory_index_count = 0;
+
+			TRACE("Directory inode %x:%x, start_block %x, offset "
+					"%x\n", SQUASHFS_INODE_BLK(inode),
+					offset, inodep.start_block,
+					inodep.offset);
+			break;
+		}
+		case SQUASHFS_SYMLINK_TYPE: {
+			squashfs_symlink_inode_header_1 inodep;
+	
+			if (msBlk->swap) {
+				squashfs_symlink_inode_header_1 sinodep;
+
+				if (!squashfs_get_cached_block(s, (char *)
+						&sinodep, block, offset,
+						sizeof(sinodep), &next_block,
+						&next_offset))
+					goto failed_read;
+				SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(&inodep,
+								&sinodep);
+			} else
+				if (!squashfs_get_cached_block(s, (char *)
+						&inodep, block, offset,
+						sizeof(inodep), &next_block,
+						&next_offset))
+					goto failed_read;
+
+			if ((i = squashfs_new_inode(s, &inodeb, ino)) == NULL)
+				goto failed_read1;
+			i->i_size = inodep.symlink_size;
+			i->i_op = &page_symlink_inode_operations;
+			i->i_data.a_ops = &squashfs_symlink_aops;
+			i->i_mode |= S_IFLNK;
+			SQUASHFS_I(i)->start_block = next_block;
+			SQUASHFS_I(i)->offset = next_offset;
+
+			TRACE("Symbolic link inode %x:%x, start_block %x, "
+						"offset %x\n",
+						SQUASHFS_INODE_BLK(inode),
+						offset, next_block,
+						next_offset);
+			break;
+		 }
+		 case SQUASHFS_BLKDEV_TYPE:
+		 case SQUASHFS_CHRDEV_TYPE: {
+			squashfs_dev_inode_header_1 inodep;
+
+			if (msBlk->swap) {
+				squashfs_dev_inode_header_1 sinodep;
+
+				if (!squashfs_get_cached_block(s, (char *)
+						&sinodep, block, offset,
+						sizeof(sinodep), &next_block,
+						&next_offset))
+					goto failed_read;
+				SQUASHFS_SWAP_DEV_INODE_HEADER_1(&inodep,
+						&sinodep);
+			} else	
+				if (!squashfs_get_cached_block(s, (char *)
+						&inodep, block,  offset,
+						sizeof(inodep), &next_block,
+						&next_offset))
+					goto failed_read;
+
+			if ((i = squashfs_new_inode(s, &inodeb, ino)) == NULL)
+				goto failed_read1;
+			i->i_mode |= (inodeb.inode_type ==
+						SQUASHFS_CHRDEV_TYPE) ?
+						S_IFCHR : S_IFBLK;
+			init_special_inode(i, i->i_mode,
+						old_decode_dev(inodep.rdev));
+
+			TRACE("Device inode %x:%x, rdev %x\n",
+						SQUASHFS_INODE_BLK(inode),
+						offset, inodep.rdev);
+			break;
+		 }
+		 case SQUASHFS_IPC_TYPE: {
+			squashfs_ipc_inode_header_1 inodep;
+
+			if (msBlk->swap) {
+				squashfs_ipc_inode_header_1 sinodep;
+
+				if (!squashfs_get_cached_block(s, (char *)
+						&sinodep, block, offset,
+						sizeof(sinodep), &next_block,
+						&next_offset))
+					goto failed_read;
+				SQUASHFS_SWAP_IPC_INODE_HEADER_1(&inodep,
+								&sinodep);
+			} else	
+				if (!squashfs_get_cached_block(s, (char *)
+						&inodep, block, offset,
+						sizeof(inodep), &next_block,
+						&next_offset))
+					goto failed_read;
+
+			if ((i = squashfs_new_inode(s, &inodeb, ino)) == NULL)
+				goto failed_read1;
+			i->i_mode |= (inodep.type == SQUASHFS_FIFO_TYPE) ?
+						S_IFIFO : S_IFSOCK;
+			i->i_uid = msBlk->uid[inodep.offset * 16 + inodeb.uid];
+			init_special_inode(i, i->i_mode, 0);
+			break;
+		 }
+		 default:
+			ERROR("Unknown inode type %d in squashfs_iget!\n",
+						inodeb.inode_type);
+			goto failed_read1;
+	}
+	
+	if (inodeb.guid == 15)
+		i->i_gid = i->i_uid;
+	else
+		i->i_gid = msBlk->guid[inodeb.guid];
+
+	insert_inode_hash(i);
+	return i;
+
+failed_read:
+	ERROR("Unable to read inode [%x:%x]\n", block, offset);
+
+failed_read1:
+	return NULL;
+}
diff --new-file -urp linux-2.6.11.3/fs/squashfs/squashfs.h linux-2.6.11.3-squashfs/fs/squashfs/squashfs.h
--- linux-2.6.11.3/fs/squashfs/squashfs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11.3-squashfs/fs/squashfs/squashfs.h	2005-03-14 00:53:28.058564896 +0000
@@ -0,0 +1,68 @@
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005
+ * Phillip Lougher <phillip@lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * squashfs.h
+ */
+
+
+#ifdef SQUASHFS_TRACE
+#define TRACE(s, args...)	printk(KERN_NOTICE "SQUASHFS: "s, ## args)
+#else
+#define TRACE(s, args...)	{}
+#endif
+
+#define ERROR(s, args...)	printk(KERN_ERR "SQUASHFS error: "s, ## args)
+
+#define SERROR(s, args...)	do { \
+				if (!silent) \
+				printk(KERN_ERR "SQUASHFS error: "s, ## args);\
+				} while(0)
+
+#define WARNING(s, args...)	printk(KERN_WARNING "SQUASHFS: "s, ## args)
+
+extern unsigned int squashfs_read_data(struct super_block *s, char *buffer,
+				unsigned int index, unsigned int length,
+				unsigned int *next_index);
+extern int squashfs_get_cached_block(struct super_block *s, char *buffer,
+				unsigned int block, unsigned int offset,
+				int length, unsigned int *next_block,
+				unsigned int *next_offset);
+
+extern struct address_space_operations squashfs_symlink_aops;
+extern struct address_space_operations squashfs_aops;
+extern struct address_space_operations squashfs_aops_4K;
+extern struct file_operations squashfs_dir_ops;
+extern struct inode_operations squashfs_dir_inode_ops;
+
+
+static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode)
+{
+	return list_entry(inode, struct squashfs_inode_info, vfs_inode);
+}
+
+
+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
+extern int squashfs_1_0_supported(squashfs_sb_info *msBlk);
+#else
+static inline int squashfs_1_0_supported(squashfs_sb_info *msBlk)
+{
+	return 0;
+}
+#endif
diff --new-file -urp linux-2.6.11.3/include/linux/squashfs_fs.h linux-2.6.11.3-squashfs/include/linux/squashfs_fs.h
--- linux-2.6.11.3/include/linux/squashfs_fs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11.3-squashfs/include/linux/squashfs_fs.h	2005-03-14 00:53:28.068563376 +0000
@@ -0,0 +1,576 @@
+#ifndef SQUASHFS_FS
+#define SQUASHFS_FS
+
+/*
+ * Squashfs
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005
+ * Phillip Lougher <phillip@lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * squashfs_fs.h
+ */
+
+#define SQUASHFS_MAJOR			2
+#define SQUASHFS_MINOR			1
+#define SQUASHFS_MAGIC			0x73717368
+#define SQUASHFS_MAGIC_SWAP		0x68737173
+#define SQUASHFS_START			0
+
+/* size of metadata (inode and directory) blocks */
+#define SQUASHFS_METADATA_SIZE		8192
+#define SQUASHFS_METADATA_LOG		13
+
+/* default size of data blocks */
+#define SQUASHFS_FILE_SIZE		65536
+#define SQUASHFS_FILE_LOG		16
+
+#define SQUASHFS_FILE_MAX_SIZE		65536
+
+/* Max number of uids and gids */
+#define SQUASHFS_UIDS			256
+#define SQUASHFS_GUIDS			255
+
+/* Max length of filename (not 255) */
+#define SQUASHFS_NAME_LEN		256
+
+#define SQUASHFS_INVALID		((long long) 0xffffffffffff)
+#define SQUASHFS_INVALID_BLK		((long long) 0xffffffff)
+#define SQUASHFS_USED_BLK		((long long) 0xfffffffe)
+
+/* Filesystem flags */
+#define SQUASHFS_NOI			0
+#define SQUASHFS_NOD			1
+#define SQUASHFS_CHECK			2
+#define SQUASHFS_NOF			3
+#define SQUASHFS_NO_FRAG		4
+#define SQUASHFS_ALWAYS_FRAG		5
+#define SQUASHFS_DUPLICATE		6
+
+#define SQUASHFS_BIT(flag, bit)		((flag >> bit) & 1)
+
+#define SQUASHFS_UNCOMPRESSED_INODES(flags)	SQUASHFS_BIT(flags, \
+						SQUASHFS_NOI)
+
+#define SQUASHFS_UNCOMPRESSED_DATA(flags)	SQUASHFS_BIT(flags, \
+						SQUASHFS_NOD)
+
+#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags)	SQUASHFS_BIT(flags, \
+						SQUASHFS_NOF)
+
+#define SQUASHFS_NO_FRAGMENTS(flags)		SQUASHFS_BIT(flags, \
+						SQUASHFS_NO_FRAG)
+
+#define SQUASHFS_ALWAYS_FRAGMENTS(flags)	SQUASHFS_BIT(flags, \
+						SQUASHFS_ALWAYS_FRAG)
+
+#define SQUASHFS_DUPLICATES(flags)		SQUASHFS_BIT(flags, \
+						SQUASHFS_DUPLICATE)
+
+#define SQUASHFS_CHECK_DATA(flags)		SQUASHFS_BIT(flags, \
+						SQUASHFS_CHECK)
+
+#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
+		duplicate_checking)	(noi | (nod << 1) | (check_data << 2) \
+		| (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
+		(duplicate_checking << 6))
+
+/* Max number of types and file types */
+#define SQUASHFS_DIR_TYPE		1
+#define SQUASHFS_FILE_TYPE		2
+#define SQUASHFS_SYMLINK_TYPE		3
+#define SQUASHFS_BLKDEV_TYPE		4
+#define SQUASHFS_CHRDEV_TYPE		5
+#define SQUASHFS_FIFO_TYPE		6
+#define SQUASHFS_SOCKET_TYPE		7
+#define SQUASHFS_LDIR_TYPE		8
+
+/* 1.0 filesystem type definitions */
+#define SQUASHFS_TYPES			5
+#define SQUASHFS_IPC_TYPE		0
+
+/* Flag whether block is compressed or uncompressed, bit is set if block is
+ * uncompressed */
+#define SQUASHFS_COMPRESSED_BIT		(1 << 15)
+
+#define SQUASHFS_COMPRESSED_SIZE(B)	(((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
+		(B) & ~SQUASHFS_COMPRESSED_BIT :  SQUASHFS_COMPRESSED_BIT)
+
+#define SQUASHFS_COMPRESSED(B)		(!((B) & SQUASHFS_COMPRESSED_BIT))
+
+#define SQUASHFS_COMPRESSED_BIT_BLOCK		(1 << 24)
+
+#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B)	(((B) & \
+	~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \
+	~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK)
+
+#define SQUASHFS_COMPRESSED_BLOCK(B)	(!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
+
+/*
+ * Inode number ops.  Inodes consist of a compressed block number, and an
+ * uncompressed  offset within that block
+ */
+#define SQUASHFS_INODE_BLK(a)		((unsigned int) ((a) >> 16))
+
+#define SQUASHFS_INODE_OFFSET(a)	((unsigned int) ((a) & 0xffff))
+
+#define SQUASHFS_MKINODE(A, B)		((squashfs_inode)(((squashfs_inode) (A)\
+					<< 16) + (B)))
+
+/* Compute 32 bit VFS inode number from squashfs inode number */
+#define SQUASHFS_MK_VFS_INODE(a, b)	((unsigned int) (((a) << 8) + \
+					((b) >> 2) + 1))
+
+/* Translate between VFS mode and squashfs mode */
+#define SQUASHFS_MODE(a)		((a) & 0xfff)
+
+/* fragment and fragment table defines */
+typedef unsigned int			squashfs_fragment_index;
+#define SQUASHFS_FRAGMENT_BYTES(A)	(A * sizeof(squashfs_fragment_entry))
+
+#define SQUASHFS_FRAGMENT_INDEX(A)	(SQUASHFS_FRAGMENT_BYTES(A) / \
+					SQUASHFS_METADATA_SIZE)
+
+#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A)	(SQUASHFS_FRAGMENT_BYTES(A) % \
+						SQUASHFS_METADATA_SIZE)
+
+#define SQUASHFS_FRAGMENT_INDEXES(A)	((SQUASHFS_FRAGMENT_BYTES(A) + \
+					SQUASHFS_METADATA_SIZE - 1) / \
+					SQUASHFS_METADATA_SIZE)
+
+#define SQUASHFS_FRAGMENT_INDEX_BYTES(A)	(SQUASHFS_FRAGMENT_INDEXES(A) *\
+						sizeof(squashfs_fragment_index))
+
+#define SQUASHFS_CACHED_FRAGMENTS	3
+
+/* cached data constants for filesystem */
+#define SQUASHFS_CACHED_BLKS		8
+
+#define SQUASHFS_MAX_FILE_SIZE_LOG	32
+
+#define SQUASHFS_MAX_FILE_SIZE		((long long) 1 << \
+					(SQUASHFS_MAX_FILE_SIZE_LOG - 1))
+
+#define SQUASHFS_MARKER_BYTE		0xff
+
+
+/*
+ * definitions for structures on disk
+ */
+
+typedef unsigned int		squashfs_block;
+typedef long long		squashfs_inode;
+
+typedef unsigned int		squashfs_uid;
+
+typedef struct squashfs_super_block {
+	unsigned int		s_magic;
+	unsigned int		inodes;
+	unsigned int		bytes_used;
+	unsigned int		uid_start;
+	unsigned int		guid_start;
+	unsigned int		inode_table_start;
+	unsigned int		directory_table_start;
+	unsigned int		s_major:16;
+	unsigned int		s_minor:16;
+	unsigned int		block_size_1:16;
+	unsigned int		block_log:16;
+	unsigned int		flags:8;
+	unsigned int		no_uids:8;
+	unsigned int		no_guids:8;
+	unsigned int		mkfs_time /* time of filesystem creation */;
+	squashfs_inode		root_inode;
+	unsigned int		block_size;
+	unsigned int		fragments;
+	unsigned int		fragment_table_start;
+} __attribute__ ((packed)) squashfs_super_block;
+
+typedef struct {
+	unsigned int		index:27;
+	unsigned int		start_block:29;
+	unsigned char		size;
+	unsigned char		name[0];
+} __attribute__ ((packed)) squashfs_dir_index;
+
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:8; /* index into uid table */
+	unsigned int		guid:8; /* index into guid table */
+} __attribute__ ((packed)) squashfs_base_inode_header;
+
+typedef squashfs_base_inode_header squashfs_ipc_inode_header;
+
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:8; /* index into uid table */
+	unsigned int		guid:8; /* index into guid table */
+	unsigned short		rdev;
+} __attribute__ ((packed)) squashfs_dev_inode_header;
+	
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:8; /* index into uid table */
+	unsigned int		guid:8; /* index into guid table */
+	unsigned short		symlink_size;
+	char			symlink[0];
+} __attribute__ ((packed)) squashfs_symlink_inode_header;
+
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:8; /* index into uid table */
+	unsigned int		guid:8; /* index into guid table */
+	unsigned int		mtime;
+	squashfs_block		start_block;
+	unsigned int		fragment;
+	unsigned int		offset;
+	unsigned int		file_size:SQUASHFS_MAX_FILE_SIZE_LOG;
+	unsigned short		block_list[0];
+} __attribute__ ((packed)) squashfs_reg_inode_header;
+
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:8; /* index into uid table */
+	unsigned int		guid:8; /* index into guid table */
+	unsigned int		file_size:19;
+	unsigned int		offset:13;
+	unsigned int		mtime;
+	unsigned int		start_block:24;
+} __attribute__  ((packed)) squashfs_dir_inode_header;
+
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:8; /* index into uid table */
+	unsigned int		guid:8; /* index into guid table */
+	unsigned int		file_size:27;
+	unsigned int		offset:13;
+	unsigned int		mtime;
+	unsigned int		start_block:24;
+	unsigned int		i_count:16;
+	squashfs_dir_index	index[0];
+} __attribute__  ((packed)) squashfs_ldir_inode_header;
+
+typedef union {
+	squashfs_base_inode_header	base;
+	squashfs_dev_inode_header	dev;
+	squashfs_symlink_inode_header	symlink;
+	squashfs_reg_inode_header	reg;
+	squashfs_dir_inode_header	dir;
+	squashfs_ldir_inode_header	ldir;
+	squashfs_ipc_inode_header	ipc;
+} squashfs_inode_header;
+	
+typedef struct {
+	unsigned int		offset:13;
+	unsigned int		type:3;
+	unsigned int		size:8;
+	char			name[0];
+} __attribute__ ((packed)) squashfs_dir_entry;
+
+typedef struct {
+	unsigned int		count:8;
+	unsigned int		start_block:24;
+} __attribute__ ((packed)) squashfs_dir_header;
+
+typedef struct {
+	unsigned int		start_block;
+	unsigned int		size;
+} __attribute__ ((packed)) squashfs_fragment_entry;
+
+extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen);
+extern int squashfs_uncompress_init(void);
+extern int squashfs_uncompress_exit(void);
+
+/*
+ * macros to convert each packed bitfield structure from little endian to big
+ * endian and vice versa.  These are needed when creating or using a filesystem
+ * on a machine with different byte ordering to the target architecture.
+ *
+ */
+
+#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\
+	SQUASHFS_MEMSET(s, d, sizeof(squashfs_super_block));\
+	SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
+	SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
+	SQUASHFS_SWAP((s)->bytes_used, d, 64, 32);\
+	SQUASHFS_SWAP((s)->uid_start, d, 96, 32);\
+	SQUASHFS_SWAP((s)->guid_start, d, 128, 32);\
+	SQUASHFS_SWAP((s)->inode_table_start, d, 160, 32);\
+	SQUASHFS_SWAP((s)->directory_table_start, d, 192, 32);\
+	SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
+	SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
+	SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
+	SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
+	SQUASHFS_SWAP((s)->flags, d, 288, 8);\
+	SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
+	SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
+	SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
+	SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
+	SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
+	SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
+	SQUASHFS_SWAP((s)->fragment_table_start, d, 472, 32);\
+}
+
+#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\
+	SQUASHFS_MEMSET(s, d, n);\
+	SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
+	SQUASHFS_SWAP((s)->mode, d, 4, 12);\
+	SQUASHFS_SWAP((s)->uid, d, 16, 8);\
+	SQUASHFS_SWAP((s)->guid, d, 24, 8);\
+}
+
+#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) \
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_ipc_inode_header))
+
+#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, \
+			sizeof(squashfs_dev_inode_header)); \
+	SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
+}
+
+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, \
+			sizeof(squashfs_symlink_inode_header));\
+	SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
+}
+
+#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, \
+			sizeof(squashfs_reg_inode_header));\
+	SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
+	SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
+	SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
+	SQUASHFS_SWAP((s)->offset, d, 128, 32);\
+	SQUASHFS_SWAP((s)->file_size, d, 160, SQUASHFS_MAX_FILE_SIZE_LOG);\
+}
+
+#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, \
+			sizeof(squashfs_dir_inode_header));\
+	SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
+	SQUASHFS_SWAP((s)->offset, d, 51, 13);\
+	SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
+	SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
+}
+
+#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, \
+			sizeof(squashfs_ldir_inode_header));\
+	SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
+	SQUASHFS_SWAP((s)->offset, d, 59, 13);\
+	SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
+	SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
+	SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
+}
+
+#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\
+	SQUASHFS_MEMSET(s, d, sizeof(squashfs_dir_index));\
+	SQUASHFS_SWAP((s)->index, d, 0, 27);\
+	SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
+	SQUASHFS_SWAP((s)->size, d, 56, 8);\
+}
+
+#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\
+	SQUASHFS_MEMSET(s, d, sizeof(squashfs_dir_header));\
+	SQUASHFS_SWAP((s)->count, d, 0, 8);\
+	SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
+}
+
+#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\
+	SQUASHFS_MEMSET(s, d, sizeof(squashfs_dir_entry));\
+	SQUASHFS_SWAP((s)->offset, d, 0, 13);\
+	SQUASHFS_SWAP((s)->type, d, 13, 3);\
+	SQUASHFS_SWAP((s)->size, d, 16, 8);\
+}
+
+#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\
+	SQUASHFS_MEMSET(s, d, sizeof(squashfs_fragment_entry));\
+	SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
+	SQUASHFS_SWAP((s)->size, d, 32, 32);\
+}
+
+#define SQUASHFS_SWAP_SHORTS(s, d, n) {\
+	int entry;\
+	int bit_position;\
+	SQUASHFS_MEMSET(s, d, n * 2);\
+	for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
+			16)\
+		SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
+}
+
+#define SQUASHFS_SWAP_INTS(s, d, n) {\
+	int entry;\
+	int bit_position;\
+	SQUASHFS_MEMSET(s, d, n * 4);\
+	for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
+			32)\
+		SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
+}
+
+#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
+	int entry;\
+	int bit_position;\
+	SQUASHFS_MEMSET(s, d, n * bits / 8);\
+	for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
+			bits)\
+		SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
+}
+
+#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_INTS(s, d, n)
+
+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
+
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:4; /* index into uid table */
+	unsigned int		guid:4; /* index into guid table */
+} __attribute__ ((packed)) squashfs_base_inode_header_1;
+
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:4; /* index into uid table */
+	unsigned int		guid:4; /* index into guid table */
+	unsigned int		type:4;
+	unsigned int		offset:4;
+} __attribute__ ((packed)) squashfs_ipc_inode_header_1;
+
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:4; /* index into uid table */
+	unsigned int		guid:4; /* index into guid table */
+	unsigned short		rdev;
+} __attribute__ ((packed)) squashfs_dev_inode_header_1;
+	
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:4; /* index into uid table */
+	unsigned int		guid:4; /* index into guid table */
+	unsigned short		symlink_size;
+	char			symlink[0];
+} __attribute__ ((packed)) squashfs_symlink_inode_header_1;
+
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:4; /* index into uid table */
+	unsigned int		guid:4; /* index into guid table */
+	unsigned int		mtime;
+	squashfs_block		start_block;
+	unsigned int		file_size:SQUASHFS_MAX_FILE_SIZE_LOG;
+	unsigned short		block_list[0];
+} __attribute__ ((packed)) squashfs_reg_inode_header_1;
+
+typedef struct {
+	unsigned int		inode_type:4;
+	unsigned int		mode:12; /* protection */
+	unsigned int		uid:4; /* index into uid table */
+	unsigned int		guid:4; /* index into guid table */
+	unsigned int		file_size:19;
+	unsigned int		offset:13;
+	unsigned int		mtime;
+	unsigned int		start_block:24;
+} __attribute__  ((packed)) squashfs_dir_inode_header_1;
+
+#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
+	SQUASHFS_MEMSET(s, d, n);\
+	SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
+	SQUASHFS_SWAP((s)->mode, d, 4, 12);\
+	SQUASHFS_SWAP((s)->uid, d, 16, 4);\
+	SQUASHFS_SWAP((s)->guid, d, 20, 4);\
+}
+
+#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, \
+			sizeof(squashfs_ipc_inode_header_1));\
+	SQUASHFS_SWAP((s)->type, d, 24, 4);\
+	SQUASHFS_SWAP((s)->offset, d, 28, 4);\
+}
+
+#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, \
+			sizeof(squashfs_dev_inode_header_1));\
+	SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
+}
+
+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, \
+			sizeof(squashfs_symlink_inode_header_1));\
+	SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
+}
+
+#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, \
+			sizeof(squashfs_reg_inode_header_1));\
+	SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
+	SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
+	SQUASHFS_SWAP((s)->file_size, d, 88, SQUASHFS_MAX_FILE_SIZE_LOG);\
+}
+
+#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
+	SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, \
+			sizeof(squashfs_dir_inode_header_1));\
+	SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
+	SQUASHFS_SWAP((s)->offset, d, 43, 13);\
+	SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
+	SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
+}
+
+#endif
+
+#ifdef __KERNEL__
+
+/*
+ * macros used to swap each structure entry, taking into account
+ * bitfields and different bitfield placing conventions on differing
+ * architectures
+ */
+
+#include <asm/byteorder.h>
+
+#ifdef __BIG_ENDIAN
+	/* convert from little endian to big endian */
+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
+		tbits, b_pos)
+#else
+	/* convert from big endian to little endian */ 
+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
+		tbits, 64 - tbits - b_pos)
+#endif
+
+#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
+	int bits;\
+	int b_pos = pos % 8;\
+	unsigned long long val = 0;\
+	unsigned char *s = (unsigned char *)p + (pos / 8);\
+	unsigned char *d = ((unsigned char *) &val) + 7;\
+	for(bits = 0; bits < (tbits + b_pos); bits += 8) \
+		*d-- = *s++;\
+	value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
+}
+
+#define SQUASHFS_MEMSET(s, d, n)	memset(s, 0, n);
+
+#endif
+#endif
diff --new-file -urp linux-2.6.11.3/include/linux/squashfs_fs_i.h linux-2.6.11.3-squashfs/include/linux/squashfs_fs_i.h
--- linux-2.6.11.3/include/linux/squashfs_fs_i.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11.3-squashfs/include/linux/squashfs_fs_i.h	2005-03-14 00:53:28.078561856 +0000
@@ -0,0 +1,44 @@
+#ifndef SQUASHFS_FS_I
+#define SQUASHFS_FS_I
+/*
+ * Squashfs
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005
+ * Phillip Lougher <phillip@lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * squashfs_fs_i.h
+ */
+
+typedef struct squashfs_inode_info {
+	unsigned int	start_block;
+	unsigned int	block_list_start;
+	unsigned int	offset;
+	union {
+		struct {
+			unsigned int	fragment_start_block;
+			unsigned int	fragment_size;
+			unsigned int	fragment_offset;
+		} s1;
+		struct {
+			unsigned int	directory_index_start;
+			unsigned int	directory_index_offset;
+			unsigned int	directory_index_count;
+		} s2;
+	} u;
+	struct inode	vfs_inode;
+	} squashfs_inode_info;
+#endif
diff --new-file -urp linux-2.6.11.3/include/linux/squashfs_fs_sb.h linux-2.6.11.3-squashfs/include/linux/squashfs_fs_sb.h
--- linux-2.6.11.3/include/linux/squashfs_fs_sb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.11.3-squashfs/include/linux/squashfs_fs_sb.h	2005-03-14 00:53:28.085560792 +0000
@@ -0,0 +1,68 @@
+#ifndef SQUASHFS_FS_SB
+#define SQUASHFS_FS_SB
+/*
+ * Squashfs
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005
+ * Phillip Lougher <phillip@lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * squashfs_fs_sb.h
+ */
+
+#include <linux/squashfs_fs.h>
+
+typedef struct {
+	unsigned int	block;
+	int		length;
+	unsigned int	next_index;
+	char		*data;
+	} squashfs_cache;
+
+struct squashfs_fragment_cache {
+	unsigned int	block;
+	int		length;
+	unsigned int	locked;
+	char		*data;
+	};
+
+typedef struct squashfs_sb_info {
+	squashfs_super_block	sBlk;
+	int			devblksize;
+	int			devblksize_log2;
+	int			swap;
+	squashfs_cache		*block_cache;
+	struct squashfs_fragment_cache	*fragment;
+	int			next_cache;
+	int			next_fragment;
+	squashfs_uid		*uid;
+	squashfs_uid		*guid;
+	squashfs_fragment_index		*fragment_index;
+	unsigned int		read_size;
+	char			*read_data;
+	char			*read_page;
+	struct semaphore	read_page_mutex;
+	struct semaphore	block_cache_mutex;
+	struct semaphore	fragment_mutex;
+	wait_queue_head_t	waitq;
+	wait_queue_head_t	fragment_wait_queue;
+	struct inode		*(*iget)(struct super_block *s, squashfs_inode \
+				inode);
+	unsigned int		(*read_blocklist)(struct inode *inode, int \
+				index, int readahead_blks, char *block_list, \
+				unsigned short **block_p, unsigned int *bsize);
+	} squashfs_sb_info;
+#endif
diff --new-file -urp linux-2.6.11.3/init/do_mounts_rd.c linux-2.6.11.3-squashfs/init/do_mounts_rd.c
--- linux-2.6.11.3/init/do_mounts_rd.c	2005-03-13 06:44:30.000000000 +0000
+++ linux-2.6.11.3-squashfs/init/do_mounts_rd.c	2005-03-14 00:53:28.092559728 +0000
@@ -5,6 +5,7 @@
 #include <linux/ext2_fs.h>
 #include <linux/romfs_fs.h>
 #include <linux/cramfs_fs.h>
+#include <linux/squashfs_fs.h>
 #include <linux/initrd.h>
 #include <linux/string.h>
 
@@ -39,6 +40,7 @@ static int __init crd_load(int in_fd, in
  * numbers could not be found.
  *
  * We currently check for the following magic numbers:
+ *      squashfs
  * 	minix
  * 	ext2
  *	romfs
@@ -53,6 +55,7 @@ identify_ramdisk_image(int fd, int start
 	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;
 
@@ -64,6 +67,7 @@ identify_ramdisk_image(int fd, int start
 	ext2sb = (struct ext2_super_block *) buf;
 	romfsb = (struct romfs_super_block *) buf;
 	cramfsb = (struct cramfs_super *) buf;
+	squashfsb = (struct squashfs_super_block *) buf;
 	memset(buf, 0xe5, size);
 
 	/*
@@ -101,6 +105,15 @@ identify_ramdisk_image(int fd, int start
 		goto done;
 	}
 
+	/* squashfs is at block zero too */
+	if (squashfsb->s_magic == SQUASHFS_MAGIC) {
+		printk(KERN_NOTICE
+		       "RAMDISK: squashfs filesystem found at block %d\n",
+		       start_block);
+		nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
+		goto done;
+	}
+
 	/*
 	 * Read block 1 to test for minix and ext2 superblock
 	 */
diff --new-file -urp linux-2.6.11.3/MAINTAINERS linux-2.6.11.3-squashfs/MAINTAINERS
--- linux-2.6.11.3/MAINTAINERS	2005-03-13 06:44:28.000000000 +0000
+++ linux-2.6.11.3-squashfs/MAINTAINERS	2005-03-14 00:53:28.101558360 +0000
@@ -2125,6 +2125,13 @@ M:	jschlst@samba.org
 L:	linux-net@vger.kernel.org
 S:	Supported
 
+SQUASHFS FILESYSTEM
+P: Phillip Lougher
+M: phillip@lougher.demon.co.uk
+W: http://squashfs.sourceforge.net
+L: squashfs-devel@lists.sourceforge.net
+S: Maintained
+
 SRM (Alpha) environment access
 P:	Jan-Benedict Glaw
 M:	jbglaw@lug-owl.de

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2005-03-22  7:26 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-14 16:30 [PATCH][2/2] SquashFS Phillip Lougher
2005-03-15  1:06 ` Andrew Morton
2005-03-15  1:14   ` Phillip Lougher
2005-03-15  3:01     ` Andrew Morton
2005-03-15 17:16       ` Phillip Lougher
2005-03-15 18:21       ` Paulo Marques
2005-03-21 10:14         ` Pavel Machek
2005-03-21 15:56           ` Phillip Lougher
2005-03-21 19:00             ` Pavel Machek
2005-03-21 18:03               ` Phillip Lougher
2005-03-21 22:49                 ` Pavel Machek
2005-03-22  2:41                   ` Josh Boyer
2005-03-22  2:58                     ` David Lang
2005-03-22  3:04                     ` Andrew Morton
2005-03-22  2:59                       ` Phillip Lougher
2005-03-22  5:32                         ` Paul Jackson
2005-03-22  3:34                   ` Phillip Lougher
2005-03-22  5:37                     ` Stefan Smietanowski
2005-03-21 22:32               ` Mws
2005-03-21 22:44                 ` Pavel Machek
2005-03-21 22:54                   ` Mws
2005-03-22  3:36                   ` Phillip Lougher
2005-03-22  7:19                 ` Stefan Smietanowski
2005-03-22  5:20               ` Willy Tarreau
2005-03-21 18:08           ` Mws
2005-03-21 18:54             ` Pavel Machek
2005-03-21 22:23               ` Mws
2005-03-21 22:31                 ` Pavel Machek
2005-03-21 22:47                   ` Mws
2005-03-21 22:56                     ` Pavel Machek
2005-03-15  3:12 ` Matt Mackall
2005-03-15 23:25   ` Phillip Lougher
2005-03-16  0:57     ` Andrew Morton
2005-03-16  1:04     ` Matt Mackall
2005-03-16  4:19       ` Matt Mackall
2005-03-15  5:38 ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox