summaryrefslogtreecommitdiff
path: root/patches
diff options
context:
space:
mode:
authorThomas Bächler <thomas@archlinux.org>2008-07-21 20:35:27 +0200
committerThomas Bächler <thomas@archlinux.org>2008-07-21 20:35:27 +0200
commit04cdb515326c5eb461da2793cf4745a52c8c5b2d (patch)
tree9903f3168d06be11e5e961bfc0ac40a04ceade7a /patches
parentdaaa7a2c43699c3b2acffaef1a4fed863194d29f (diff)
Update to 2.6.26-1
Diffstat (limited to 'patches')
-rw-r--r--patches/fs-unionfs-use-new-umount_begin-prototype.patch41
-rw-r--r--patches/revert-acpi-ec-msleep.patch12
-rw-r--r--patches/revert-cpuidle-simplification.patch146
-rw-r--r--patches/squashfs-2.6.25.patch103
-rw-r--r--patches/squashfs-cvs-2.6.26.patch (renamed from patches/squashfs3.3-patch)828
5 files changed, 459 insertions, 671 deletions
diff --git a/patches/fs-unionfs-use-new-umount_begin-prototype.patch b/patches/fs-unionfs-use-new-umount_begin-prototype.patch
new file mode 100644
index 0000000..3806a61
--- /dev/null
+++ b/patches/fs-unionfs-use-new-umount_begin-prototype.patch
@@ -0,0 +1,41 @@
+diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c
+index 82b4045..b110760 100644
+--- a/fs/unionfs/super.c
++++ b/fs/unionfs/super.c
+@@ -961,32 +961,21 @@ static int unionfs_write_inode(struct inode *inode, int sync)
+ * Used only in nfs, to kill any pending RPC tasks, so that subsequent
+ * code can actually succeed and won't leave tasks that need handling.
+ */
+-static void unionfs_umount_begin(struct vfsmount *mnt, int flags)
++static void unionfs_umount_begin(struct super_block *sb)
+ {
+- struct super_block *sb, *lower_sb;
+- struct vfsmount *lower_mnt;
++ struct super_block *lower_sb;
+ int bindex, bstart, bend;
+
+- if (!(flags & MNT_FORCE))
+- /*
+- * we are not being MNT_FORCE'd, therefore we should emulate
+- * old behavior
+- */
+- return;
+-
+- sb = mnt->mnt_sb;
+-
+ unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD);
+
+ bstart = sbstart(sb);
+ bend = sbend(sb);
+ for (bindex = bstart; bindex <= bend; bindex++) {
+- lower_mnt = unionfs_lower_mnt_idx(sb->s_root, bindex);
+ lower_sb = unionfs_lower_super_idx(sb, bindex);
+
+- if (lower_mnt && lower_sb && lower_sb->s_op &&
++ if (lower_sb && lower_sb->s_op &&
+ lower_sb->s_op->umount_begin)
+- lower_sb->s_op->umount_begin(lower_mnt, flags);
++ lower_sb->s_op->umount_begin(lower_sb);
+ }
+
+ unionfs_read_unlock(sb);
diff --git a/patches/revert-acpi-ec-msleep.patch b/patches/revert-acpi-ec-msleep.patch
new file mode 100644
index 0000000..d041828
--- /dev/null
+++ b/patches/revert-acpi-ec-msleep.patch
@@ -0,0 +1,12 @@
+reverted:
+--- b/drivers/acpi/ec.c
++++ a/drivers/acpi/ec.c
+@@ -194,7 +194,7 @@
+ while (time_before(jiffies, delay)) {
+ if (acpi_ec_check_status(ec, event))
+ return 0;
++ udelay(ACPI_EC_UDELAY);
+- msleep(1);
+ }
+ }
+ pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event =
diff --git a/patches/revert-cpuidle-simplification.patch b/patches/revert-cpuidle-simplification.patch
deleted file mode 100644
index cec5196..0000000
--- a/patches/revert-cpuidle-simplification.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-reverted:
---- b/arch/x86/kernel/process_32.c
-+++ a/arch/x86/kernel/process_32.c
-@@ -82,6 +82,7 @@
- */
- void (*pm_idle)(void);
- EXPORT_SYMBOL(pm_idle);
-+static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
-
- void disable_hlt(void)
- {
-@@ -189,6 +190,9 @@
- while (!need_resched()) {
- void (*idle)(void);
-
-+ if (__get_cpu_var(cpu_idle_state))
-+ __get_cpu_var(cpu_idle_state) = 0;
-+
- check_pgt_cache();
- rmb();
- idle = pm_idle;
-@@ -216,19 +220,40 @@
- {
- }
-
--/*
-- * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
-- * pm_idle and update to new pm_idle value. Required while changing pm_idle
-- * handler on SMP systems.
-- *
-- * Caller must have changed pm_idle to the new value before the call. Old
-- * pm_idle value will not be used by any CPU after the return of this function.
-- */
- void cpu_idle_wait(void)
- {
-+ unsigned int cpu, this_cpu = get_cpu();
-+ cpumask_t map, tmp = current->cpus_allowed;
-+
-+ set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
-+ put_cpu();
-+
-+ cpus_clear(map);
-+ for_each_online_cpu(cpu) {
-+ per_cpu(cpu_idle_state, cpu) = 1;
-+ cpu_set(cpu, map);
-+ }
-+
-+ __get_cpu_var(cpu_idle_state) = 0;
-+
-+ wmb();
-+ do {
-+ ssleep(1);
-+ for_each_online_cpu(cpu) {
-+ if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
-+ cpu_clear(cpu, map);
-+ }
-+ cpus_and(map, map, cpu_online_map);
-+ /*
-+ * We waited 1 sec, if a CPU still did not call idle
-+ * it may be because it is in idle and not waking up
-+ * because it has nothing to do.
-+ * Give all the remaining CPUS a kick.
-+ */
-+ smp_call_function_mask(map, do_nothing, NULL, 0);
-+ } while (!cpus_empty(map));
-+
-+ set_cpus_allowed(current, tmp);
-- smp_mb();
-- /* kick all the CPUs so that they exit out of pm_idle */
-- smp_call_function(do_nothing, NULL, 0, 1);
- }
- EXPORT_SYMBOL_GPL(cpu_idle_wait);
-
-reverted:
---- b/arch/x86/kernel/process_64.c
-+++ a/arch/x86/kernel/process_64.c
-@@ -63,6 +63,7 @@
- */
- void (*pm_idle)(void);
- EXPORT_SYMBOL(pm_idle);
-+static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
-
- static ATOMIC_NOTIFIER_HEAD(idle_notifier);
-
-@@ -172,6 +173,9 @@
- while (!need_resched()) {
- void (*idle)(void);
-
-+ if (__get_cpu_var(cpu_idle_state))
-+ __get_cpu_var(cpu_idle_state) = 0;
-+
- rmb();
- idle = pm_idle;
- if (!idle)
-@@ -203,19 +207,40 @@
- {
- }
-
--/*
-- * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
-- * pm_idle and update to new pm_idle value. Required while changing pm_idle
-- * handler on SMP systems.
-- *
-- * Caller must have changed pm_idle to the new value before the call. Old
-- * pm_idle value will not be used by any CPU after the return of this function.
-- */
- void cpu_idle_wait(void)
- {
-+ unsigned int cpu, this_cpu = get_cpu();
-+ cpumask_t map, tmp = current->cpus_allowed;
-+
-+ set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
-+ put_cpu();
-+
-+ cpus_clear(map);
-+ for_each_online_cpu(cpu) {
-+ per_cpu(cpu_idle_state, cpu) = 1;
-+ cpu_set(cpu, map);
-+ }
-+
-+ __get_cpu_var(cpu_idle_state) = 0;
-+
-+ wmb();
-+ do {
-+ ssleep(1);
-+ for_each_online_cpu(cpu) {
-+ if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
-+ cpu_clear(cpu, map);
-+ }
-+ cpus_and(map, map, cpu_online_map);
-+ /*
-+ * We waited 1 sec, if a CPU still did not call idle
-+ * it may be because it is in idle and not waking up
-+ * because it has nothing to do.
-+ * Give all the remaining CPUS a kick.
-+ */
-+ smp_call_function_mask(map, do_nothing, 0, 0);
-+ } while (!cpus_empty(map));
-+
-+ set_cpus_allowed(current, tmp);
-- smp_mb();
-- /* kick all the CPUs so that they exit out of pm_idle */
-- smp_call_function(do_nothing, NULL, 0, 1);
- }
- EXPORT_SYMBOL_GPL(cpu_idle_wait);
-
diff --git a/patches/squashfs-2.6.25.patch b/patches/squashfs-2.6.25.patch
deleted file mode 100644
index 225b3cd..0000000
--- a/patches/squashfs-2.6.25.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-diff -r -u squashfs-dist/kernel/fs/squashfs/inode.c squashfs-ck/kernel/fs/squashfs/inode.c
---- squashfs-dist/kernel/fs/squashfs/inode.c 2007-11-08 14:21:23.000000000 -0500
-+++ squashfs-ck/kernel/fs/squashfs/inode.c 2008-02-27 13:09:42.000000000 -0500
-@@ -28,6 +28,7 @@
- #include <linux/squashfs_fs_sb.h>
- #include <linux/squashfs_fs_i.h>
- #include <linux/buffer_head.h>
-+#include <linux/exportfs.h>
- #include <linux/vfs.h>
- #include <linux/vmalloc.h>
- #include <linux/smp_lock.h>
-@@ -36,7 +37,6 @@
-
- static int squashfs_cached_blks;
-
--static void vfs_read_inode(struct inode *i);
- 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 *);
-@@ -82,7 +82,6 @@
- .destroy_inode = squashfs_destroy_inode,
- .statfs = squashfs_statfs,
- .put_super = squashfs_put_super,
-- .read_inode = vfs_read_inode
- };
-
- static struct export_operations squashfs_export_ops = {
-@@ -600,53 +599,12 @@
- else
- i->i_gid = msblk->guid[inodeb->guid];
- }
--
--
--static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino)
--{
-- struct squashfs_sb_info *msblk = s->s_fs_info;
-- long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)];
-- int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1);
-- squashfs_inode_t inode;
--
-- TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino);
--
-- if (msblk->swap) {
-- squashfs_inode_t sinode;
--
-- if (!squashfs_get_cached_block(s, &sinode, start, offset,
-- sizeof(sinode), &start, &offset))
-- goto out;
-- SQUASHFS_SWAP_INODE_T((&inode), &sinode);
-- } else if (!squashfs_get_cached_block(s, &inode, start, offset,
-- sizeof(inode), &start, &offset))
-- goto out;
--
-- TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode);
--
-- return inode;
--
--out:
-- return SQUASHFS_INVALID_BLK;
--}
-
-
--static void vfs_read_inode(struct inode *i)
--{
-- struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
-- squashfs_inode_t inode = squashfs_inode_lookup(i->i_sb, i->i_ino);
--
-- TRACE("Entered vfs_read_inode\n");
--
-- if(inode != SQUASHFS_INVALID_BLK)
-- (msblk->read_inode)(i, inode);
--}
--
--
- static struct dentry *squashfs_get_parent(struct dentry *child)
- {
- struct inode *i = child->d_inode;
-- struct inode *parent = iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode);
-+ struct inode *parent = iget_locked(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode);
- struct dentry *rv;
-
- TRACE("Entered squashfs_get_parent\n");
-@@ -657,6 +615,10 @@
- }
-
- rv = d_alloc_anon(parent);
-+ if(parent->i_state & I_NEW) {
-+ unlock_new_inode(parent);
-+ }
-+
- if(rv == NULL)
- rv = ERR_PTR(-ENOMEM);
-
-@@ -673,6 +635,9 @@
-
- TRACE("Entered squashfs_iget\n");
-
-+ if(!i)
-+ return ERR_PTR(-ENOMEM);
-+
- if(i && (i->i_state & I_NEW)) {
- (msblk->read_inode)(i, inode);
- unlock_new_inode(i);
diff --git a/patches/squashfs3.3-patch b/patches/squashfs-cvs-2.6.26.patch
index cb9a5c4..36fdf99 100644
--- a/patches/squashfs3.3-patch
+++ b/patches/squashfs-cvs-2.6.26.patch
@@ -1,7 +1,7 @@
-diff -x .gitignore -Nurp linux-2.6.24/fs/Kconfig linux-2.6.24-squashfs3.3/fs/Kconfig
---- linux-2.6.24/fs/Kconfig 2007-10-25 17:41:45.000000000 +0100
-+++ linux-2.6.24-squashfs3.3/fs/Kconfig 2007-11-01 05:06:25.000000000 +0000
-@@ -1396,6 +1396,56 @@ config CRAMFS
+diff -Nur linux-2.6.26.orig/fs/Kconfig linux-2.6.26/fs/Kconfig
+--- linux-2.6.26.orig/fs/Kconfig 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/fs/Kconfig 2008-07-21 17:19:24.445406145 +0200
+@@ -1395,6 +1395,56 @@
If unsure, say N.
@@ -58,10 +58,10 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/Kconfig linux-2.6.24-squashfs3.3/fs/Kco
config VXFS_FS
tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
depends on BLOCK
-diff -x .gitignore -Nurp linux-2.6.24/fs/Makefile linux-2.6.24-squashfs3.3/fs/Makefile
---- linux-2.6.24/fs/Makefile 2007-10-25 17:41:45.000000000 +0100
-+++ linux-2.6.24-squashfs3.3/fs/Makefile 2007-11-01 05:08:09.000000000 +0000
-@@ -72,6 +72,7 @@ obj-$(CONFIG_JBD) += jbd/
+diff -Nur linux-2.6.26.orig/fs/Makefile linux-2.6.26/fs/Makefile
+--- linux-2.6.26.orig/fs/Makefile 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/fs/Makefile 2008-07-21 17:19:24.448736386 +0200
+@@ -73,6 +73,7 @@
obj-$(CONFIG_JBD2) += jbd2/
obj-$(CONFIG_EXT2_FS) += ext2/
obj-$(CONFIG_CRAMFS) += cramfs/
@@ -69,14 +69,25 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/Makefile linux-2.6.24-squashfs3.3/fs/Ma
obj-y += ramfs/
obj-$(CONFIG_HUGETLBFS) += hugetlbfs/
obj-$(CONFIG_CODA_FS) += coda/
-diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3.3/fs/squashfs/inode.c
---- linux-2.6.24/fs/squashfs/inode.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-squashfs3.3/fs/squashfs/inode.c 2007-11-01 05:05:00.000000000 +0000
-@@ -0,0 +1,2192 @@
+diff -Nur linux-2.6.26.orig/fs/squashfs/Makefile linux-2.6.26/fs/squashfs/Makefile
+--- linux-2.6.26.orig/fs/squashfs/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.26/fs/squashfs/Makefile 2008-07-21 17:20:13.261250197 +0200
+@@ -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 -Nur linux-2.6.26.orig/fs/squashfs/inode.c linux-2.6.26/fs/squashfs/inode.c
+--- linux-2.6.26.orig/fs/squashfs/inode.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.26/fs/squashfs/inode.c 2008-07-21 17:20:13.261250197 +0200
+@@ -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@lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
@@ -105,14 +116,16 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+#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 void vfs_read_inode(struct inode *i);
++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 *);
@@ -153,15 +166,9 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ .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,
-+ .read_inode = vfs_read_inode
-+};
-+
+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
+};
+
@@ -269,7 +276,7 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ 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);
+
@@ -279,12 +286,8 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ 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;
@@ -297,6 +300,7 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ 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);
@@ -306,9 +310,9 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ ? "" : "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;
@@ -418,117 +422,204 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+}
+
+
-+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);
-+
-+ 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);
++ for (i = 0; i < cache->entries && cache->entry[i].block != block; i++);
++
++ 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);
+
-+ 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->length = squashfs_read_data(s, entry->data,
++ block, length, &entry->next_index, cache->block_size);
+
-+ if (msblk->block_cache[i].block != block) {
-+ mutex_unlock(&msblk->block_cache_mutex);
-+ continue;
++ 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;
+ }
+
-+ bytes = msblk->block_cache[i].length - offset;
++ entry = &cache->entry[i];
++ if (entry->locked == 0)
++ cache->unused_blks --;
++ entry->locked++;
+
-+ if (bytes < 1) {
-+ mutex_unlock(&msblk->block_cache_mutex);
++ if (entry->pending) {
++ entry->waiting ++;
++ spin_unlock(&cache->lock);
++ wait_event(entry->wait_queue, !entry->pending);
+ goto out;
++ }
++
++ 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;
++ }
++ }
++
++ return cache;
++
++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;
+}
+
+
@@ -565,98 +656,19 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+
+
+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);
+}
+
+
@@ -705,42 +717,72 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+out:
+ return SQUASHFS_INVALID_BLK;
+}
-+
+
-+static void vfs_read_inode(struct inode *i)
++
++
++static struct dentry *squashfs_export_iget(struct super_block *s,
++ unsigned int inode_number)
+{
-+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
-+ squashfs_inode_t inode = squashfs_inode_lookup(i->i_sb, i->i_ino);
++ squashfs_inode_t inode;
++ struct inode *i;
++ struct dentry *dentry;
+
-+ TRACE("Entered vfs_read_inode\n");
++ TRACE("Entered squashfs_export_iget\n");
+
-+ if(inode != SQUASHFS_INVALID_BLK)
-+ (msblk->read_inode)(i, inode);
++ inode = squashfs_inode_lookup(s, inode_number);
++ if(inode == SQUASHFS_INVALID_BLK) {
++ dentry = ERR_PTR(-ENOENT);
++ goto failure;
++ }
++
++ i = squashfs_iget(s, inode, inode_number);
++ if(i == NULL) {
++ dentry = ERR_PTR(-EACCES);
++ goto failure;
++ }
++
++ 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;
-+ struct inode *parent = iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode);
-+ struct dentry *rv;
+
+ TRACE("Entered squashfs_get_parent\n");
+
-+ if(parent == NULL) {
-+ rv = ERR_PTR(-EACCES);
-+ goto out;
-+ }
-+
-+ rv = d_alloc_anon(parent);
-+ if(rv == NULL)
-+ rv = ERR_PTR(-ENOMEM);
-+
-+out:
-+ return rv;
++ 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)
+{
@@ -1098,34 +1140,6 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+}
+
+
-+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;
@@ -1164,7 +1178,6 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+{
+ struct squashfs_sb_info *msblk;
+ struct squashfs_super_block *sblk;
-+ int i;
+ char b[BDEVNAME_SIZE];
+ struct inode *root;
+
@@ -1189,13 +1202,8 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+
+ 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 */
@@ -1262,7 +1270,9 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ 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 */
@@ -1307,19 +1317,10 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ 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)
@@ -1332,7 +1333,6 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ 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:
@@ -1354,10 +1354,10 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+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);
@@ -1434,7 +1434,7 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+}
+
+
-+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;
@@ -1469,7 +1469,7 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+}
+
+
-+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;
@@ -1523,7 +1523,7 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+}
+
+
-+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();
@@ -1709,7 +1709,7 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ 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;
@@ -1758,10 +1758,11 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ 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);
@@ -1835,7 +1836,7 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ 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;
+
@@ -2160,19 +2161,10 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+
+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);
@@ -2199,7 +2191,7 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+ if (err)
+ goto out;
+
-+ printk(KERN_INFO "squashfs: version 3.3 (2007/10/31) "
++ printk(KERN_INFO "squashfs: version 3.3-CVS (2008/06/12) "
+ "Phillip Lougher\n");
+
+ err = register_filesystem(&squashfs_fs_type);
@@ -2262,28 +2254,107 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/inode.c linux-2.6.24-squashfs3
+
+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.3-CVS, a compressed read-only filesystem");
+MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>");
+MODULE_LICENSE("GPL");
-diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/Makefile linux-2.6.24-squashfs3.3/fs/squashfs/Makefile
---- linux-2.6.24/fs/squashfs/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-squashfs3.3/fs/squashfs/Makefile 2005-11-20 14:31:00.000000000 +0000
-@@ -0,0 +1,7 @@
-+#
-+# Makefile for the linux squashfs routines.
-+#
+diff -Nur linux-2.6.26.orig/fs/squashfs/squashfs.h linux-2.6.26/fs/squashfs/squashfs.h
+--- linux-2.6.26.orig/fs/squashfs/squashfs.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.26/fs/squashfs/squashfs.h 2008-07-21 17:20:13.261250197 +0200
+@@ -0,0 +1,86 @@
++/*
++ * Squashfs - a compressed read only filesystem for Linux
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
++ * 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
++ */
+
-+obj-$(CONFIG_SQUASHFS) += squashfs.o
-+squashfs-y += inode.o
-+squashfs-y += squashfs2_0.o
-diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/squashfs2_0.c linux-2.6.24-squashfs3.3/fs/squashfs/squashfs2_0.c
---- linux-2.6.24/fs/squashfs/squashfs2_0.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-squashfs3.3/fs/squashfs/squashfs2_0.c 2007-10-25 00:43:59.000000000 +0100
++#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 -Nur linux-2.6.26.orig/fs/squashfs/squashfs2_0.c linux-2.6.26/fs/squashfs/squashfs2_0.c
+--- linux-2.6.26.orig/fs/squashfs/squashfs2_0.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.26/fs/squashfs/squashfs2_0.c 2008-07-21 17:20:13.261250197 +0200
@@ -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@lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
@@ -3020,99 +3091,9 @@ diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/squashfs2_0.c linux-2.6.24-squ
+
+ return 1;
+}
-diff -x .gitignore -Nurp linux-2.6.24/fs/squashfs/squashfs.h linux-2.6.24-squashfs3.3/fs/squashfs/squashfs.h
---- linux-2.6.24/fs/squashfs/squashfs.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-squashfs3.3/fs/squashfs/squashfs.h 2007-08-19 04:23:16.000000000 +0100
-@@ -0,0 +1,86 @@
-+/*
-+ * Squashfs - a compressed read only filesystem for Linux
-+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
-+ * 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 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
-+
-+#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.24/include/linux/squashfs_fs.h linux-2.6.24-squashfs3.3/include/linux/squashfs_fs.h
---- linux-2.6.24/include/linux/squashfs_fs.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-squashfs3.3/include/linux/squashfs_fs.h 2007-11-01 03:50:57.000000000 +0000
+diff -Nur linux-2.6.26.orig/include/linux/squashfs_fs.h linux-2.6.26/include/linux/squashfs_fs.h
+--- linux-2.6.26.orig/include/linux/squashfs_fs.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.26/include/linux/squashfs_fs.h 2008-07-21 17:19:32.891235712 +0200
@@ -0,0 +1,935 @@
+#ifndef SQUASHFS_FS
+#define SQUASHFS_FS
@@ -3120,7 +3101,7 @@ diff -x .gitignore -Nurp linux-2.6.24/include/linux/squashfs_fs.h linux-2.6.24-s
+/*
+ * Squashfs
+ *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ * Phillip Lougher <phillip@lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
@@ -3210,7 +3191,7 @@ diff -x .gitignore -Nurp linux-2.6.24/include/linux/squashfs_fs.h linux-2.6.24-s
+ 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))
+
@@ -3470,7 +3451,7 @@ diff -x .gitignore -Nurp linux-2.6.24/include/linux/squashfs_fs.h linux-2.6.24-s
+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);
@@ -4049,16 +4030,16 @@ diff -x .gitignore -Nurp linux-2.6.24/include/linux/squashfs_fs.h linux-2.6.24-s
+
+#endif
+#endif
-diff -x .gitignore -Nurp linux-2.6.24/include/linux/squashfs_fs_i.h linux-2.6.24-squashfs3.3/include/linux/squashfs_fs_i.h
---- linux-2.6.24/include/linux/squashfs_fs_i.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-squashfs3.3/include/linux/squashfs_fs_i.h 2007-08-19 04:24:08.000000000 +0100
+diff -Nur linux-2.6.26.orig/include/linux/squashfs_fs_i.h linux-2.6.26/include/linux/squashfs_fs_i.h
+--- linux-2.6.26.orig/include/linux/squashfs_fs_i.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.26/include/linux/squashfs_fs_i.h 2008-07-21 17:19:32.891235712 +0200
@@ -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@lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
@@ -4098,16 +4079,16 @@ diff -x .gitignore -Nurp linux-2.6.24/include/linux/squashfs_fs_i.h linux-2.6.24
+ struct inode vfs_inode;
+};
+#endif
-diff -x .gitignore -Nurp linux-2.6.24/include/linux/squashfs_fs_sb.h linux-2.6.24-squashfs3.3/include/linux/squashfs_fs_sb.h
---- linux-2.6.24/include/linux/squashfs_fs_sb.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-squashfs3.3/include/linux/squashfs_fs_sb.h 2007-08-19 04:24:26.000000000 +0100
-@@ -0,0 +1,76 @@
+diff -Nur linux-2.6.26.orig/include/linux/squashfs_fs_sb.h linux-2.6.26/include/linux/squashfs_fs_sb.h
+--- linux-2.6.26.orig/include/linux/squashfs_fs_sb.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.26/include/linux/squashfs_fs_sb.h 2008-07-21 17:19:32.891235712 +0200
+@@ -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@lougher.demon.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
@@ -4129,18 +4110,29 @@ diff -x .gitignore -Nurp linux-2.6.24/include/linux/squashfs_fs_sb.h linux-2.6.2
+
+#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 {
@@ -4149,9 +4141,7 @@ diff -x .gitignore -Nurp linux-2.6.24/include/linux/squashfs_fs_sb.h linux-2.6.2
+ 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;
@@ -4160,16 +4150,10 @@ diff -x .gitignore -Nurp linux-2.6.24/include/linux/squashfs_fs_sb.h linux-2.6.2
+ 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 \
@@ -4178,9 +4162,9 @@ diff -x .gitignore -Nurp linux-2.6.24/include/linux/squashfs_fs_sb.h linux-2.6.2
+ int (*read_fragment_index_table)(struct super_block *s);
+};
+#endif
-diff -x .gitignore -Nurp linux-2.6.24/init/do_mounts_rd.c linux-2.6.24-squashfs3.3/init/do_mounts_rd.c
---- linux-2.6.24/init/do_mounts_rd.c 2007-10-25 17:41:49.000000000 +0100
-+++ linux-2.6.24-squashfs3.3/init/do_mounts_rd.c 2007-11-01 05:06:25.000000000 +0000
+diff -Nur linux-2.6.26.orig/init/do_mounts_rd.c linux-2.6.26/init/do_mounts_rd.c
+--- linux-2.6.26.orig/init/do_mounts_rd.c 2008-07-13 23:51:29.000000000 +0200
++++ linux-2.6.26/init/do_mounts_rd.c 2008-07-21 17:19:24.478746206 +0200
@@ -5,6 +5,7 @@
#include <linux/ext2_fs.h>
#include <linux/romfs_fs.h>
@@ -4189,7 +4173,7 @@ diff -x .gitignore -Nurp linux-2.6.24/init/do_mounts_rd.c linux-2.6.24-squashfs3
#include <linux/initrd.h>
#include <linux/string.h>
-@@ -39,6 +40,7 @@ static int __init crd_load(int in_fd, in
+@@ -39,6 +40,7 @@
* numbers could not be found.
*
* We currently check for the following magic numbers:
@@ -4197,7 +4181,7 @@ diff -x .gitignore -Nurp linux-2.6.24/init/do_mounts_rd.c linux-2.6.24-squashfs3
* minix
* ext2
* romfs
-@@ -53,6 +55,7 @@ identify_ramdisk_image(int fd, int start
+@@ -53,6 +55,7 @@
struct ext2_super_block *ext2sb;
struct romfs_super_block *romfsb;
struct cramfs_super *cramfsb;
@@ -4205,7 +4189,7 @@ diff -x .gitignore -Nurp linux-2.6.24/init/do_mounts_rd.c linux-2.6.24-squashfs3
int nblocks = -1;
unsigned char *buf;
-@@ -64,6 +67,7 @@ identify_ramdisk_image(int fd, int start
+@@ -64,6 +67,7 @@
ext2sb = (struct ext2_super_block *) buf;
romfsb = (struct romfs_super_block *) buf;
cramfsb = (struct cramfs_super *) buf;
@@ -4213,7 +4197,7 @@ diff -x .gitignore -Nurp linux-2.6.24/init/do_mounts_rd.c linux-2.6.24-squashfs3
memset(buf, 0xe5, size);
/*
-@@ -101,6 +105,18 @@ identify_ramdisk_image(int fd, int start
+@@ -101,6 +105,18 @@
goto done;
}