Author: katzj
Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv10083
Modified Files:
kernel.spec linux-2.6-squashfs.patch
Log Message:
* Tue Sep 30 2008 Jeremy Katz <katzj(a)redhat.com>
- update to squashfs 3.4
Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.995
retrieving revision 1.996
diff -u -r1.995 -r1.996
--- kernel.spec 30 Sep 2008 04:49:05 -0000 1.995
+++ kernel.spec 30 Sep 2008 19:20:32 -0000 1.996
@@ -1739,6 +1739,9 @@
%kernel_variant_files -k vmlinux %{with_kdump} kdump
%changelog
+* Tue Sep 30 2008 Jeremy Katz <katzj(a)redhat.com>
+- update to squashfs 3.4
+
* Mon Sep 29 2008 Roland McGrath <roland(a)redhat.com>
- 2.6.27-rc8
- utrace update
linux-2.6-squashfs.patch:
Index: linux-2.6-squashfs.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-squashfs.patch,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- linux-2.6-squashfs.patch 28 Jul 2008 15:25:17 -0000 1.30
+++ linux-2.6-squashfs.patch 30 Sep 2008 19:20:33 -0000 1.31
@@ -1,16 +1,15 @@
-diff --git a/fs/Kconfig b/fs/Kconfig
-index d731282..cab44a1 100644
---- a/fs/Kconfig
-+++ b/fs/Kconfig
-@@ -1367,6 +1367,56 @@ config CRAMFS
+diff -x .gitignore -Nurp linux-2.6.27-rc4/fs/Kconfig
linux-2.6.27-rc4-squashfs3.4/fs/Kconfig
+--- linux-2.6.27-rc4/fs/Kconfig 2008-08-11 15:20:41.000000000 +0100
++++ linux-2.6.27-rc4-squashfs3.4/fs/Kconfig 2008-08-19 18:31:56.000000000 +0100
+@@ -1348,6 +1348,56 @@ config CRAMFS
If unsure, say N.
+config SQUASHFS
-+ tristate "SquashFS 3.3 - Squashed file system support"
++ tristate "SquashFS 3.4 - Squashed file system support"
+ select ZLIB_INFLATE
+ help
-+ Saying Y here includes support for SquashFS 3.3 (a Compressed
++ Saying Y here includes support for SquashFS 3.4 (a 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
@@ -59,11 +58,10 @@
config VXFS_FS
tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
depends on BLOCK
-diff --git a/fs/Makefile b/fs/Makefile
-index 1e7a11b..3faf857 100644
---- a/fs/Makefile
-+++ b/fs/Makefile
-@@ -73,6 +73,7 @@ obj-$(CONFIG_JBD) += jbd/
+diff -x .gitignore -Nurp linux-2.6.27-rc4/fs/Makefile
linux-2.6.27-rc4-squashfs3.4/fs/Makefile
+--- linux-2.6.27-rc4/fs/Makefile 2008-08-11 15:20:41.000000000 +0100
++++ linux-2.6.27-rc4-squashfs3.4/fs/Makefile 2008-08-19 18:31:56.000000000 +0100
+@@ -74,6 +74,7 @@ obj-$(CONFIG_JBD) += jbd/
obj-$(CONFIG_JBD2) += jbd2/
obj-$(CONFIG_EXT2_FS) += ext2/
obj-$(CONFIG_CRAMFS) += cramfs/
@@ -71,29 +69,14 @@
obj-y += ramfs/
obj-$(CONFIG_HUGETLBFS) += hugetlbfs/
obj-$(CONFIG_CODA_FS) += coda/
-diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile
-new file mode 100644
-index 0000000..1bc7b06
---- /dev/null
-+++ b/fs/squashfs/Makefile
-@@ -0,0 +1,7 @@
-+#
-+# Makefile for the linux squashfs routines.
-+#
-+
-+obj-$(CONFIG_SQUASHFS) += squashfs.o
-+squashfs-y += inode.o
-+squashfs-y += squashfs2_0.o
-diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c
-new file mode 100644
-index 0000000..f578528
---- /dev/null
-+++ b/fs/squashfs/inode.c
-@@ -0,0 +1,2178 @@
+diff -x .gitignore -Nurp linux-2.6.27-rc4/fs/squashfs/inode.c
linux-2.6.27-rc4-squashfs3.4/fs/squashfs/inode.c
+--- linux-2.6.27-rc4/fs/squashfs/inode.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.27-rc4-squashfs3.4/fs/squashfs/inode.c 2008-08-26 08:25:23.000000000 +0100
+@@ -0,0 +1,2173 @@
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ * Phillip Lougher <phillip(a)lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
@@ -122,13 +105,16 @@
+#include <linux/buffer_head.h>
+#include <linux/vfs.h>
+#include <linux/vmalloc.h>
++#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/exportfs.h>
+
+#include "squashfs.h"
+
-+int squashfs_cached_blks;
-+
++static struct dentry *squashfs_fh_to_dentry(struct super_block *s,
++ struct fid *fid, int fh_len, int fh_type);
++static struct dentry *squashfs_fh_to_parent(struct super_block *s,
++ struct fid *fid, int fh_len, int fh_type);
+static struct dentry *squashfs_get_parent(struct dentry *child);
+static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode);
+static int squashfs_statfs(struct dentry *, struct kstatfs *);
@@ -169,14 +155,9 @@
+ .remount_fs = squashfs_remount
+};
+
-+static struct super_operations squashfs_export_super_ops = {
-+ .alloc_inode = squashfs_alloc_inode,
-+ .destroy_inode = squashfs_destroy_inode,
-+ .statfs = squashfs_statfs,
-+ .put_super = squashfs_put_super,
-+};
-+
+static struct export_operations squashfs_export_ops = {
++ .fh_to_dentry = squashfs_fh_to_dentry,
++ .fh_to_parent = squashfs_fh_to_parent,
+ .get_parent = squashfs_get_parent
+};
+
@@ -284,7 +265,7 @@
+ goto read_failure;
+
+ if (c_byte) {
-+ bytes = msblk->devblksize - offset;
++ bytes = -offset;
+ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
+ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
+
@@ -294,12 +275,8 @@
+ if (c_byte > srclength || index < 0 || (index + c_byte) >
sblk->bytes_used)
+ goto read_failure;
+
-+ bh[0] = sb_getblk(s, cur_index);
-+ if (bh[0] == NULL)
-+ goto block_release;
-+
-+ for (b = 1; bytes < c_byte; b++) {
-+ bh[b] = sb_getblk(s, ++cur_index);
++ for (b = 0; bytes < (int) c_byte; b++, cur_index++) {
++ bh[b] = sb_getblk(s, cur_index);
+ if (bh[b] == NULL)
+ goto block_release;
+ bytes += msblk->devblksize;
@@ -312,6 +289,7 @@
+ bh[0] = get_block_length(s, &cur_index, &offset, &c_byte);
+ if (bh[0] == NULL)
+ goto read_failure;
++ b = 1;
+
+ bytes = msblk->devblksize - offset;
+ compressed = SQUASHFS_COMPRESSED(c_byte);
@@ -321,9 +299,9 @@
+ ? "" : "un", (unsigned int) c_byte);
+
+ if (c_byte > srclength || (index + c_byte) > sblk->bytes_used)
-+ goto read_failure;
++ goto block_release;
+
-+ for (b = 1; bytes < c_byte; b++) {
++ for (; bytes < c_byte; b++) {
+ bh[b] = sb_getblk(s, ++cur_index);
+ if (bh[b] == NULL)
+ goto block_release;
@@ -433,117 +411,204 @@
+}
+
+
-+SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, void *buffer,
-+ long long block, unsigned int offset,
-+ int length, long long *next_block,
-+ unsigned int *next_offset)
++static struct squashfs_cache_entry *squashfs_cache_get(struct super_block *s,
++ struct squashfs_cache *cache, long long block, int length)
+{
-+ struct squashfs_sb_info *msblk = s->s_fs_info;
-+ int n, i, bytes, return_length = length;
-+ long long next_index;
++ int i, n;
++ struct squashfs_cache_entry *entry;
+
-+ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);
++ spin_lock(&cache->lock);
+
+ while (1) {
-+ for (i = 0; i < squashfs_cached_blks; i++)
-+ if (msblk->block_cache[i].block == block)
-+ break;
-+
-+ mutex_lock(&msblk->block_cache_mutex);
++ for (i = 0; i < cache->entries && cache->entry[i].block != block;
i++);
+
-+ if (i == squashfs_cached_blks) {
-+ /* read inode header block */
-+ if (msblk->unused_cache_blks == 0) {
-+ mutex_unlock(&msblk->block_cache_mutex);
-+ wait_event(msblk->waitq, msblk->unused_cache_blks);
++ if (i == cache->entries) {
++ if (cache->unused_blks == 0) {
++ cache->waiting ++;
++ spin_unlock(&cache->lock);
++ wait_event(cache->wait_queue, cache->unused_blks);
++ spin_lock(&cache->lock);
++ cache->waiting --;
+ continue;
+ }
+
-+ i = msblk->next_cache;
-+ for (n = 0; n < squashfs_cached_blks; n++) {
-+ if (msblk->block_cache[i].block != SQUASHFS_USED_BLK)
++ i = cache->next_blk;
++ for (n = 0; n < cache->entries; n++) {
++ if (cache->entry[i].locked == 0)
+ break;
-+ i = (i + 1) % squashfs_cached_blks;
++ i = (i + 1) % cache->entries;
+ }
+
-+ msblk->next_cache = (i + 1) % squashfs_cached_blks;
++ cache->next_blk = (i + 1) % cache->entries;
++ entry = &cache->entry[i];
+
-+ if (msblk->block_cache[i].block == SQUASHFS_INVALID_BLK) {
-+ msblk->block_cache[i].data = vmalloc(SQUASHFS_METADATA_SIZE);
-+ if (msblk->block_cache[i].data == NULL) {
-+ ERROR("Failed to allocate cache block\n");
-+ mutex_unlock(&msblk->block_cache_mutex);
-+ goto out;
-+ }
-+ }
-+
-+ msblk->block_cache[i].block = SQUASHFS_USED_BLK;
-+ msblk->unused_cache_blks --;
-+ mutex_unlock(&msblk->block_cache_mutex);
-+
-+ msblk->block_cache[i].length = squashfs_read_data(s,
-+ msblk->block_cache[i].data, block, 0, &next_index,
-+ SQUASHFS_METADATA_SIZE);
-+
-+ if (msblk->block_cache[i].length == 0) {
-+ ERROR("Unable to read cache block [%llx:%x]\n", block, offset);
-+ mutex_lock(&msblk->block_cache_mutex);
-+ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
-+ msblk->unused_cache_blks ++;
-+ smp_mb();
-+ vfree(msblk->block_cache[i].data);
-+ wake_up(&msblk->waitq);
-+ mutex_unlock(&msblk->block_cache_mutex);
-+ goto out;
-+ }
++ cache->unused_blks --;
++ entry->block = block;
++ entry->locked = 1;
++ entry->pending = 1;
++ entry->waiting = 0;
++ entry->error = 0;
++ spin_unlock(&cache->lock);
++
++ entry->length = squashfs_read_data(s, entry->data,
++ block, length, &entry->next_index, cache->block_size);
++
++ spin_lock(&cache->lock);
++
++ if (entry->length == 0)
++ entry->error = 1;
++
++ entry->pending = 0;
++ spin_unlock(&cache->lock);
++ if (entry->waiting)
++ wake_up_all(&entry->wait_queue);
++ goto out;
++ }
+
-+ mutex_lock(&msblk->block_cache_mutex);
-+ msblk->block_cache[i].block = block;
-+ msblk->block_cache[i].next_index = next_index;
-+ msblk->unused_cache_blks ++;
-+ smp_mb();
-+ wake_up(&msblk->waitq);
-+ TRACE("Read cache block [%llx:%x]\n", block, offset);
++ entry = &cache->entry[i];
++ if (entry->locked == 0)
++ cache->unused_blks --;
++ entry->locked++;
++
++ if (entry->pending) {
++ entry->waiting ++;
++ spin_unlock(&cache->lock);
++ wait_event(entry->wait_queue, !entry->pending);
++ goto out;
+ }
+
-+ if (msblk->block_cache[i].block != block) {
-+ mutex_unlock(&msblk->block_cache_mutex);
-+ continue;
++ spin_unlock(&cache->lock);
++ goto out;
++ }
++
++out:
++ TRACE("Got %s %d, start block %lld, locked %d, error %d\n", i,
++ cache->name, entry->block, entry->locked, entry->error);
++ if (entry->error)
++ ERROR("Unable to read %s cache entry [%llx]\n", cache->name, block);
++ return entry;
++}
++
++
++static void squashfs_cache_put(struct squashfs_cache *cache,
++ struct squashfs_cache_entry *entry)
++{
++ spin_lock(&cache->lock);
++ entry->locked --;
++ if (entry->locked == 0) {
++ cache->unused_blks ++;
++ spin_unlock(&cache->lock);
++ if (cache->waiting)
++ wake_up(&cache->wait_queue);
++ } else
++ spin_unlock(&cache->lock);
++}
++
++
++static void squashfs_cache_delete(struct squashfs_cache *cache)
++{
++ int i;
++
++ if (cache == NULL)
++ return;
++
++ for (i = 0; i < cache->entries; i++)
++ if (cache->entry[i].data) {
++ if (cache->use_vmalloc)
++ vfree(cache->entry[i].data);
++ else
++ kfree(cache->entry[i].data);
++ }
++
++ kfree(cache);
++}
++
++
++static struct squashfs_cache *squashfs_cache_init(char *name, int entries,
++ int block_size, int use_vmalloc)
++{
++ int i;
++ struct squashfs_cache *cache = kzalloc(sizeof(struct squashfs_cache) +
++ entries * sizeof(struct squashfs_cache_entry), GFP_KERNEL);
++ if (cache == NULL) {
++ ERROR("Failed to allocate %s cache\n", name);
++ goto failed;
++ }
++
++ cache->next_blk = 0;
++ cache->unused_blks = entries;
++ cache->entries = entries;
++ cache->block_size = block_size;
++ cache->use_vmalloc = use_vmalloc;
++ cache->name = name;
++ cache->waiting = 0;
++ spin_lock_init(&cache->lock);
++ init_waitqueue_head(&cache->wait_queue);
++
++ for (i = 0; i < entries; i++) {
++ init_waitqueue_head(&cache->entry[i].wait_queue);
++ cache->entry[i].block = SQUASHFS_INVALID_BLK;
++ cache->entry[i].data = use_vmalloc ? vmalloc(block_size) :
++ kmalloc(block_size, GFP_KERNEL);
++ if (cache->entry[i].data == NULL) {
++ ERROR("Failed to allocate %s cache entry\n", name);
++ goto cleanup;
+ }
++ }
+
-+ bytes = msblk->block_cache[i].length - offset;
++ return cache;
+
-+ if (bytes < 1) {
-+ mutex_unlock(&msblk->block_cache_mutex);
-+ goto out;
++cleanup:
++ squashfs_cache_delete(cache);
++failed:
++ return NULL;
++}
++
++
++SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, void *buffer,
++ long long block, unsigned int offset,
++ int length, long long *next_block,
++ unsigned int *next_offset)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ int bytes, return_length = length;
++ struct squashfs_cache_entry *entry;
++
++ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);
++
++ while (1) {
++ entry = squashfs_cache_get(s, msblk->block_cache, block, 0);
++ bytes = entry->length - offset;
++
++ if (entry->error || bytes < 1) {
++ return_length = 0;
++ goto finish;
+ } else if (bytes >= length) {
+ if (buffer)
-+ memcpy(buffer, msblk->block_cache[i].data + offset, length);
-+ if (msblk->block_cache[i].length - offset == length) {
-+ *next_block = msblk->block_cache[i].next_index;
++ memcpy(buffer, entry->data + offset, length);
++ if (entry->length - offset == length) {
++ *next_block = entry->next_index;
+ *next_offset = 0;
+ } else {
+ *next_block = block;
+ *next_offset = offset + length;
+ }
-+ mutex_unlock(&msblk->block_cache_mutex);
+ goto finish;
+ } else {
+ if (buffer) {
-+ memcpy(buffer, msblk->block_cache[i].data + offset, bytes);
++ memcpy(buffer, entry->data + offset, bytes);
+ buffer = (char *) buffer + bytes;
+ }
-+ block = msblk->block_cache[i].next_index;
-+ mutex_unlock(&msblk->block_cache_mutex);
++ block = entry->next_index;
++ squashfs_cache_put(msblk->block_cache, entry);
+ length -= bytes;
+ offset = 0;
+ }
+ }
+
+finish:
++ squashfs_cache_put(msblk->block_cache, entry);
+ return return_length;
-+out:
-+ return 0;
+}
+
+
@@ -580,98 +645,19 @@
+
+
+SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk,
-+ struct squashfs_fragment_cache *fragment)
++ struct squashfs_cache_entry *fragment)
+{
-+ mutex_lock(&msblk->fragment_mutex);
-+ fragment->locked --;
-+ if (fragment->locked == 0) {
-+ msblk->unused_frag_blks ++;
-+ smp_mb();
-+ wake_up(&msblk->fragment_wait_queue);
-+ }
-+ mutex_unlock(&msblk->fragment_mutex);
++ squashfs_cache_put(msblk->fragment_cache, fragment);
+}
+
+
+SQSH_EXTERN
-+struct squashfs_fragment_cache *get_cached_fragment(struct super_block *s,
++struct squashfs_cache_entry *get_cached_fragment(struct super_block *s,
+ long long start_block, int length)
+{
-+ int i, n;
+ struct squashfs_sb_info *msblk = s->s_fs_info;
-+ struct squashfs_super_block *sblk = &msblk->sblk;
+
-+ while (1) {
-+ mutex_lock(&msblk->fragment_mutex);
-+
-+ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS &&
-+ msblk->fragment[i].block != start_block; i++);
-+
-+ if (i == SQUASHFS_CACHED_FRAGMENTS) {
-+ if (msblk->unused_frag_blks == 0) {
-+ mutex_unlock(&msblk->fragment_mutex);
-+ wait_event(msblk->fragment_wait_queue, msblk->unused_frag_blks);
-+ continue;
-+ }
-+
-+ i = msblk->next_fragment;
-+ for (n = 0; n < SQUASHFS_CACHED_FRAGMENTS; n++) {
-+ if (msblk->fragment[i].locked == 0)
-+ break;
-+ i = (i + 1) % SQUASHFS_CACHED_FRAGMENTS;
-+ }
-+
-+ msblk->next_fragment = (msblk->next_fragment + 1) %
-+ SQUASHFS_CACHED_FRAGMENTS;
-+
-+ if (msblk->fragment[i].data == NULL) {
-+ msblk->fragment[i].data = vmalloc(sblk->block_size);
-+ if (msblk->fragment[i].data == NULL) {
-+ ERROR("Failed to allocate fragment cache block\n");
-+ mutex_unlock(&msblk->fragment_mutex);
-+ goto out;
-+ }
-+ }
-+
-+ msblk->unused_frag_blks --;
-+ msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
-+ msblk->fragment[i].locked = 1;
-+ mutex_unlock(&msblk->fragment_mutex);
-+
-+ msblk->fragment[i].length = squashfs_read_data(s,
-+ msblk->fragment[i].data, start_block, length, NULL,
-+ sblk->block_size);
-+
-+ if (msblk->fragment[i].length == 0) {
-+ ERROR("Unable to read fragment cache block [%llx]\n", start_block);
-+ msblk->fragment[i].locked = 0;
-+ msblk->unused_frag_blks ++;
-+ smp_mb();
-+ wake_up(&msblk->fragment_wait_queue);
-+ goto out;
-+ }
-+
-+ mutex_lock(&msblk->fragment_mutex);
-+ msblk->fragment[i].block = start_block;
-+ TRACE("New fragment %d, start block %lld, locked %d\n",
-+ i, msblk->fragment[i].block, msblk->fragment[i].locked);
-+ mutex_unlock(&msblk->fragment_mutex);
-+ break;
-+ }
-+
-+ if (msblk->fragment[i].locked == 0)
-+ msblk->unused_frag_blks --;
-+ msblk->fragment[i].locked++;
-+ mutex_unlock(&msblk->fragment_mutex);
-+ TRACE("Got fragment %d, start block %lld, locked %d\n", i,
-+ msblk->fragment[i].block, msblk->fragment[i].locked);
-+ break;
-+ }
-+
-+ return &msblk->fragment[i];
-+
-+out:
-+ return NULL;
++ return squashfs_cache_get(s, msblk->fragment_cache, start_block, length);
+}
+
+
@@ -720,30 +706,72 @@
+out:
+ return SQUASHFS_INVALID_BLK;
+}
-+
+
-+static struct dentry *squashfs_get_parent(struct dentry *child)
++
++
++static struct dentry *squashfs_export_iget(struct super_block *s,
++ unsigned int inode_number)
+{
-+ struct inode *i = child->d_inode;
-+ struct inode *parent = iget_locked(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode);
-+ struct dentry *rv;
++ squashfs_inode_t inode;
++ struct inode *i;
++ struct dentry *dentry;
+
-+ TRACE("Entered squashfs_get_parent\n");
++ TRACE("Entered squashfs_export_iget\n");
+
-+ if(parent == NULL) {
-+ rv = ERR_PTR(-EACCES);
-+ goto out;
++ inode = squashfs_inode_lookup(s, inode_number);
++ if(inode == SQUASHFS_INVALID_BLK) {
++ dentry = ERR_PTR(-ENOENT);
++ goto failure;
+ }
+
-+ rv = d_alloc_anon(parent);
-+ if(rv == NULL)
-+ rv = ERR_PTR(-ENOMEM);
++ i = squashfs_iget(s, inode, inode_number);
++ if(i == NULL) {
++ dentry = ERR_PTR(-EACCES);
++ goto failure;
++ }
+
-+out:
-+ return rv;
++ dentry = d_alloc_anon(i);
++ if (dentry == NULL) {
++ iput(i);
++ dentry = ERR_PTR(-ENOMEM);
++ }
++
++failure:
++ return dentry;
+}
+
-+
++
++static struct dentry *squashfs_fh_to_dentry(struct super_block *s,
++ struct fid *fid, int fh_len, int fh_type)
++{
++ if((fh_type != FILEID_INO32_GEN && fh_type != FILEID_INO32_GEN_PARENT) ||
++ fh_len < 2)
++ return NULL;
++
++ return squashfs_export_iget(s, fid->i32.ino);
++}
++
++
++static struct dentry *squashfs_fh_to_parent(struct super_block *s,
++ struct fid *fid, int fh_len, int fh_type)
++{
++ if(fh_type != FILEID_INO32_GEN_PARENT || fh_len < 4)
++ return NULL;
++
++ return squashfs_export_iget(s, fid->i32.parent_ino);
++}
++
++
++static struct dentry *squashfs_get_parent(struct dentry *child)
++{
++ struct inode *i = child->d_inode;
++
++ TRACE("Entered squashfs_get_parent\n");
++
++ return squashfs_export_iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode);
++}
++
++
+SQSH_EXTERN struct inode *squashfs_iget(struct super_block *s,
+ squashfs_inode_t inode, unsigned int inode_number)
+{
@@ -1101,34 +1129,6 @@
+}
+
+
-+static int readahead_metadata(struct super_block *s)
-+{
-+ struct squashfs_sb_info *msblk = s->s_fs_info;
-+ int i;
-+
-+ squashfs_cached_blks = SQUASHFS_CACHED_BLKS;
-+
-+ /* Init inode_table block pointer array */
-+ msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) *
-+ squashfs_cached_blks, GFP_KERNEL);
-+ if (msblk->block_cache == NULL) {
-+ ERROR("Failed to allocate block cache\n");
-+ goto failed;
-+ }
-+
-+ for (i = 0; i < squashfs_cached_blks; i++)
-+ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
-+
-+ msblk->next_cache = 0;
-+ msblk->unused_cache_blks = squashfs_cached_blks;
-+
-+ return 1;
-+
-+failed:
-+ return 0;
-+}
-+
-+
+static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent)
+{
+ struct squashfs_super_block *sblk = &msblk->sblk;
@@ -1167,7 +1167,6 @@
+{
+ struct squashfs_sb_info *msblk;
+ struct squashfs_super_block *sblk;
-+ int i;
+ char b[BDEVNAME_SIZE];
+ struct inode *root;
+
@@ -1192,13 +1191,8 @@
+
+ mutex_init(&msblk->read_data_mutex);
+ mutex_init(&msblk->read_page_mutex);
-+ mutex_init(&msblk->block_cache_mutex);
-+ mutex_init(&msblk->fragment_mutex);
+ mutex_init(&msblk->meta_index_mutex);
+
-+ init_waitqueue_head(&msblk->waitq);
-+ init_waitqueue_head(&msblk->fragment_wait_queue);
-+
+ /* sblk->bytes_used is checked in squashfs_read_data to ensure reads are not
+ * beyond filesystem end. As we're using squashfs_read_data to read sblk here,
+ * first set sblk->bytes_used to a useful value */
@@ -1265,7 +1259,9 @@
+ s->s_flags |= MS_RDONLY;
+ s->s_op = &squashfs_super_ops;
+
-+ if (readahead_metadata(s) == 0)
++ msblk->block_cache = squashfs_cache_init("metadata",
SQUASHFS_CACHED_BLKS,
++ SQUASHFS_METADATA_SIZE, 0);
++ if (msblk->block_cache == NULL)
+ goto failed_mount;
+
+ /* Allocate read_page block */
@@ -1310,19 +1306,10 @@
+ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))
+ goto allocate_root;
+
-+ msblk->fragment = kzalloc(sizeof(struct squashfs_fragment_cache) *
-+ SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL);
-+ if (msblk->fragment == NULL) {
-+ ERROR("Failed to allocate fragment block cache\n");
++ msblk->fragment_cache = squashfs_cache_init("fragment",
++ SQUASHFS_CACHED_FRAGMENTS, sblk->block_size, 1);
++ if (msblk->fragment_cache == NULL)
+ goto failed_mount;
-+ }
-+
-+ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) {
-+ msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
-+ }
-+
-+ msblk->next_fragment = 0;
-+ msblk->unused_frag_blks = SQUASHFS_CACHED_FRAGMENTS;
+
+ /* Allocate and read fragment index table */
+ if (msblk->read_fragment_index_table(s) == 0)
@@ -1335,7 +1322,6 @@
+ if (read_inode_lookup_table(s) == 0)
+ goto failed_mount;
+
-+ s->s_op = &squashfs_export_super_ops;
+ s->s_export_op = &squashfs_export_ops;
+
+allocate_root:
@@ -1357,10 +1343,10 @@
+failed_mount:
+ kfree(msblk->inode_lookup_table);
+ kfree(msblk->fragment_index);
-+ kfree(msblk->fragment);
++ squashfs_cache_delete(msblk->fragment_cache);
+ kfree(msblk->uid);
+ vfree(msblk->read_page);
-+ kfree(msblk->block_cache);
++ squashfs_cache_delete(msblk->block_cache);
+ kfree(msblk->fragment_index_2);
+ vfree(msblk->stream.workspace);
+ kfree(s->s_fs_info);
@@ -1437,7 +1423,7 @@
+}
+
+
-+struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)
++static struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)
+{
+ struct meta_index *meta = NULL;
+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
@@ -1472,7 +1458,7 @@
+}
+
+
-+struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)
++static struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)
+{
+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
+ struct meta_index *meta = NULL;
@@ -1526,7 +1512,7 @@
+}
+
+
-+void release_meta_index(struct inode *inode, struct meta_index *meta)
++static void release_meta_index(struct inode *inode, struct meta_index *meta)
+{
+ meta->locked = 0;
+ smp_mb();
@@ -1712,7 +1698,7 @@
+ int bytes;
+ int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT);
+ void *pageaddr;
-+ struct squashfs_fragment_cache *fragment = NULL;
++ struct squashfs_cache_entry *fragment = NULL;
+ char *data_ptr = msblk->read_page;
+
+ int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1;
@@ -1761,10 +1747,11 @@
+ SQUASHFS_I(inode)-> u.s1.fragment_start_block,
+ SQUASHFS_I(inode)->u.s1.fragment_size);
+
-+ if (fragment == NULL) {
++ if (fragment->error) {
+ ERROR("Unable to read page, block %llx, size %x\n",
+ SQUASHFS_I(inode)->u.s1.fragment_start_block,
+ (int) SQUASHFS_I(inode)->u.s1.fragment_size);
++ release_cached_fragment(msblk, fragment);
+ goto error_out;
+ }
+ bytes = i_size_read(inode) & (sblk->block_size - 1);
@@ -1838,7 +1825,7 @@
+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
+ i_count, (unsigned int) f_pos);
+
-+ f_pos =- 3;
++ f_pos -= 3;
+ if (f_pos == 0)
+ goto finish;
+
@@ -2163,19 +2150,10 @@
+
+static void squashfs_put_super(struct super_block *s)
+{
-+ int i;
-+
+ if (s->s_fs_info) {
+ struct squashfs_sb_info *sbi = s->s_fs_info;
-+ if (sbi->block_cache)
-+ for (i = 0; i < squashfs_cached_blks; i++)
-+ if (sbi->block_cache[i].block != SQUASHFS_INVALID_BLK)
-+ vfree(sbi->block_cache[i].data);
-+ if (sbi->fragment)
-+ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++)
-+ vfree(sbi->fragment[i].data);
-+ kfree(sbi->fragment);
-+ kfree(sbi->block_cache);
++ squashfs_cache_delete(sbi->block_cache);
++ squashfs_cache_delete(sbi->fragment_cache);
+ vfree(sbi->read_page);
+ kfree(sbi->uid);
+ kfree(sbi->fragment_index);
@@ -2202,7 +2180,7 @@
+ if (err)
+ goto out;
+
-+ printk(KERN_INFO "squashfs: version 3.3 (2007/10/31) "
++ printk(KERN_INFO "squashfs: version 3.4 (2008/08/26) "
+ "Phillip Lougher\n");
+
+ err = register_filesystem(&squashfs_fs_type);
@@ -2265,111 +2243,28 @@
+
+module_init(init_squashfs_fs);
+module_exit(exit_squashfs_fs);
-+MODULE_DESCRIPTION("squashfs 3.2-r2-CVS, a compressed read-only filesystem");
++MODULE_DESCRIPTION("squashfs 3.4, a compressed read-only filesystem");
+MODULE_AUTHOR("Phillip Lougher <phillip(a)lougher.demon.co.uk>");
+MODULE_LICENSE("GPL");
-diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h
-new file mode 100644
-index 0000000..ea7b6c3
---- /dev/null
-+++ b/fs/squashfs/squashfs.h
-@@ -0,0 +1,86 @@
-+/*
-+ * Squashfs - a compressed read only filesystem for Linux
-+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
-+ * Phillip Lougher <phillip(a)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 CONFIG_SQUASHFS_1_0_COMPATIBILITY
-+#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
-+#endif
-+
-+#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)
-+
-+static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode)
-+{
-+ return list_entry(inode, struct squashfs_inode_info, vfs_inode);
-+}
-+
-+#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) ||
defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY)
-+#define SQSH_EXTERN
-+extern unsigned int squashfs_read_data(struct super_block *s, char *buffer,
-+ long long index, unsigned int length,
-+ long long *next_index, int srclength);
-+extern int squashfs_get_cached_block(struct super_block *s, void *buffer,
-+ long long block, unsigned int offset,
-+ int length, long long *next_block,
-+ unsigned int *next_offset);
-+extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct
-+ squashfs_fragment_cache *fragment);
-+extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block
-+ *s, long long start_block,
-+ int length);
-+extern struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode,
unsigned int inode_number);
-+extern const struct address_space_operations squashfs_symlink_aops;
-+extern const struct address_space_operations squashfs_aops;
-+extern struct inode_operations squashfs_dir_inode_ops;
-+#else
-+#define SQSH_EXTERN static
-+#endif
-+
-+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
-+extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk);
-+#else
-+static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk)
-+{
-+ return 0;
-+}
-+#endif
+diff -x .gitignore -Nurp linux-2.6.27-rc4/fs/squashfs/Makefile
linux-2.6.27-rc4-squashfs3.4/fs/squashfs/Makefile
+--- linux-2.6.27-rc4/fs/squashfs/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.27-rc4-squashfs3.4/fs/squashfs/Makefile 2008-08-19 18:31:56.000000000
+0100
+@@ -0,0 +1,7 @@
++#
++# Makefile for the linux squashfs routines.
++#
+
-+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
-+extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk);
-+#else
-+static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
-+{
-+ return 0;
-+}
-+#endif
-diff --git a/fs/squashfs/squashfs2_0.c b/fs/squashfs/squashfs2_0.c
-new file mode 100644
-index 0000000..fa909c8
---- /dev/null
-+++ b/fs/squashfs/squashfs2_0.c
++obj-$(CONFIG_SQUASHFS) += squashfs.o
++squashfs-y += inode.o
++squashfs-y += squashfs2_0.o
+diff -x .gitignore -Nurp linux-2.6.27-rc4/fs/squashfs/squashfs2_0.c
linux-2.6.27-rc4-squashfs3.4/fs/squashfs/squashfs2_0.c
+--- linux-2.6.27-rc4/fs/squashfs/squashfs2_0.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.27-rc4-squashfs3.4/fs/squashfs/squashfs2_0.c 2008-08-19 18:31:56.000000000
+0100
@@ -0,0 +1,740 @@
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ * Phillip Lougher <phillip(a)lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
@@ -3106,11 +3001,99 @@
+
+ return 1;
+}
-diff --git a/include/linux/squashfs_fs.h b/include/linux/squashfs_fs.h
-new file mode 100644
-index 0000000..e60308e
---- /dev/null
-+++ b/include/linux/squashfs_fs.h
+diff -x .gitignore -Nurp linux-2.6.27-rc4/fs/squashfs/squashfs.h
linux-2.6.27-rc4-squashfs3.4/fs/squashfs/squashfs.h
+--- linux-2.6.27-rc4/fs/squashfs/squashfs.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.27-rc4-squashfs3.4/fs/squashfs/squashfs.h 2008-08-19 18:31:56.000000000
+0100
+@@ -0,0 +1,86 @@
++/*
++ * Squashfs - a compressed read only filesystem for Linux
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
++ * Phillip Lougher <phillip(a)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 CONFIG_SQUASHFS_1_0_COMPATIBILITY
++#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
++#endif
++
++#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)
++
++static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode)
++{
++ return list_entry(inode, struct squashfs_inode_info, vfs_inode);
++}
++
++#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) ||
defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY)
++#define SQSH_EXTERN
++extern unsigned int squashfs_read_data(struct super_block *s, char *buffer,
++ long long index, unsigned int length,
++ long long *next_index, int srclength);
++extern int squashfs_get_cached_block(struct super_block *s, void *buffer,
++ long long block, unsigned int offset,
++ int length, long long *next_block,
++ unsigned int *next_offset);
++extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct
++ squashfs_cache_entry *fragment);
++extern struct squashfs_cache_entry *get_cached_fragment(struct super_block
++ *s, long long start_block,
++ int length);
++extern struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode,
unsigned int inode_number);
++extern const struct address_space_operations squashfs_symlink_aops;
++extern const struct address_space_operations squashfs_aops;
++extern struct inode_operations squashfs_dir_inode_ops;
++#else
++#define SQSH_EXTERN static
++#endif
++
++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
++extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk);
++#else
++static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk)
++{
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
++extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk);
++#else
++static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
++{
++ return 0;
++}
++#endif
+diff -x .gitignore -Nurp linux-2.6.27-rc4/include/linux/squashfs_fs.h
linux-2.6.27-rc4-squashfs3.4/include/linux/squashfs_fs.h
+--- linux-2.6.27-rc4/include/linux/squashfs_fs.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.27-rc4-squashfs3.4/include/linux/squashfs_fs.h 2008-08-19
18:31:56.000000000 +0100
@@ -0,0 +1,935 @@
+#ifndef SQUASHFS_FS
+#define SQUASHFS_FS
@@ -3118,7 +3101,7 @@
+/*
+ * Squashfs
+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ * Phillip Lougher <phillip(a)lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
@@ -3208,7 +3191,7 @@
+ SQUASHFS_CHECK)
+
+#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
-+ duplicate_checking, exortable) (noi | (nod << 1) | (check_data << 2) \
++ duplicate_checking, exportable) (noi | (nod << 1) | (check_data << 2) \
+ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
+ (duplicate_checking << 6) | (exportable << 7))
+
@@ -3468,7 +3451,7 @@
+struct squashfs_fragment_entry {
+ long long start_block;
+ unsigned int size;
-+ unsigned int pending;
++ unsigned int unused;
+} __attribute__ ((packed));
+
+extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen);
@@ -4047,18 +4030,16 @@
+
+#endif
+#endif
-diff --git a/include/linux/squashfs_fs_i.h b/include/linux/squashfs_fs_i.h
-new file mode 100644
-index 0000000..76a3a5a
---- /dev/null
-+++ b/include/linux/squashfs_fs_i.h
+diff -x .gitignore -Nurp linux-2.6.27-rc4/include/linux/squashfs_fs_i.h
linux-2.6.27-rc4-squashfs3.4/include/linux/squashfs_fs_i.h
+--- linux-2.6.27-rc4/include/linux/squashfs_fs_i.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.27-rc4-squashfs3.4/include/linux/squashfs_fs_i.h 2008-08-19
18:31:56.000000000 +0100
@@ -0,0 +1,45 @@
+#ifndef SQUASHFS_FS_I
+#define SQUASHFS_FS_I
+/*
+ * Squashfs
+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ * Phillip Lougher <phillip(a)lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
@@ -4098,18 +4079,16 @@
+ struct inode vfs_inode;
+};
+#endif
-diff --git a/include/linux/squashfs_fs_sb.h b/include/linux/squashfs_fs_sb.h
-new file mode 100644
-index 0000000..e5fa802
---- /dev/null
-+++ b/include/linux/squashfs_fs_sb.h
-@@ -0,0 +1,76 @@
+diff -x .gitignore -Nurp linux-2.6.27-rc4/include/linux/squashfs_fs_sb.h
linux-2.6.27-rc4-squashfs3.4/include/linux/squashfs_fs_sb.h
+--- linux-2.6.27-rc4/include/linux/squashfs_fs_sb.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.27-rc4-squashfs3.4/include/linux/squashfs_fs_sb.h 2008-08-19
18:31:56.000000000 +0100
+@@ -0,0 +1,79 @@
+#ifndef SQUASHFS_FS_SB
+#define SQUASHFS_FS_SB
+/*
+ * Squashfs
+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ * Phillip Lougher <phillip(a)lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
@@ -4131,18 +4110,29 @@
+
+#include <linux/squashfs_fs.h>
+
-+struct squashfs_cache {
++struct squashfs_cache_entry {
+ long long block;
+ int length;
++ int locked;
+ long long next_index;
++ char pending;
++ char error;
++ int waiting;
++ wait_queue_head_t wait_queue;
+ char *data;
+};
+
-+struct squashfs_fragment_cache {
-+ long long block;
-+ int length;
-+ unsigned int locked;
-+ char *data;
++struct squashfs_cache {
++ char *name;
++ int entries;
++ int block_size;
++ int next_blk;
++ int waiting;
++ int unused_blks;
++ int use_vmalloc;
++ spinlock_t lock;
++ wait_queue_head_t wait_queue;
++ struct squashfs_cache_entry entry[0];
+};
+
+struct squashfs_sb_info {
@@ -4151,9 +4141,7 @@
+ int devblksize_log2;
+ int swap;
+ struct squashfs_cache *block_cache;
-+ struct squashfs_fragment_cache *fragment;
-+ int next_cache;
-+ int next_fragment;
++ struct squashfs_cache *fragment_cache;
+ int next_meta_index;
+ unsigned int *uid;
+ unsigned int *guid;
@@ -4162,16 +4150,10 @@
+ char *read_page;
+ struct mutex read_data_mutex;
+ struct mutex read_page_mutex;
-+ struct mutex block_cache_mutex;
-+ struct mutex fragment_mutex;
+ struct mutex meta_index_mutex;
-+ wait_queue_head_t waitq;
-+ wait_queue_head_t fragment_wait_queue;
+ struct meta_index *meta_index;
+ z_stream stream;
+ long long *inode_lookup_table;
-+ int unused_cache_blks;
-+ int unused_frag_blks;
+ int (*read_inode)(struct inode *i, squashfs_inode_t \
+ inode);
+ long long (*read_blocklist)(struct inode *inode, int \
@@ -4180,10 +4162,9 @@
+ int (*read_fragment_index_table)(struct super_block *s);
+};
+#endif
-diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
-index 3ac5904..0ddd43c 100644
---- a/init/do_mounts_rd.c
-+++ b/init/do_mounts_rd.c
+diff -x .gitignore -Nurp linux-2.6.27-rc4/init/do_mounts_rd.c
linux-2.6.27-rc4-squashfs3.4/init/do_mounts_rd.c
+--- linux-2.6.27-rc4/init/do_mounts_rd.c 2008-08-11 15:20:55.000000000 +0100
++++ linux-2.6.27-rc4-squashfs3.4/init/do_mounts_rd.c 2008-08-19 18:31:56.000000000 +0100
@@ -5,6 +5,7 @@
#include <linux/ext2_fs.h>
#include <linux/romfs_fs.h>
@@ -4192,7 +4173,7 @@
#include <linux/initrd.h>
#include <linux/string.h>
-@@ -39,6 +40,7 @@ static int __init crd_load(int in_fd, int out_fd);
+@@ -37,6 +38,7 @@ static int __init crd_load(int in_fd, in
* numbers could not be found.
*
* We currently check for the following magic numbers:
@@ -4200,7 +4181,7 @@
* minix
* ext2
* romfs
-@@ -53,6 +55,7 @@ identify_ramdisk_image(int fd, int start_block)
+@@ -51,6 +53,7 @@ identify_ramdisk_image(int fd, int start
struct ext2_super_block *ext2sb;
struct romfs_super_block *romfsb;
struct cramfs_super *cramfsb;
@@ -4208,7 +4189,7 @@
int nblocks = -1;
unsigned char *buf;
-@@ -64,6 +67,7 @@ identify_ramdisk_image(int fd, int start_block)
+@@ -62,6 +65,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;
@@ -4216,7 +4197,7 @@
memset(buf, 0xe5, size);
/*
-@@ -101,6 +105,18 @@ identify_ramdisk_image(int fd, int start_block)
+@@ -99,6 +103,18 @@ identify_ramdisk_image(int fd, int start
goto done;
}