diff options
author | Thomas Bächler <thomas@archlinux.org> | 2008-07-21 20:35:27 +0200 |
---|---|---|
committer | Thomas Bächler <thomas@archlinux.org> | 2008-07-21 20:35:27 +0200 |
commit | 04cdb515326c5eb461da2793cf4745a52c8c5b2d (patch) | |
tree | 9903f3168d06be11e5e961bfc0ac40a04ceade7a /patches | |
parent | daaa7a2c43699c3b2acffaef1a4fed863194d29f (diff) |
Update to 2.6.26-1
Diffstat (limited to 'patches')
-rw-r--r-- | patches/fs-unionfs-use-new-umount_begin-prototype.patch | 41 | ||||
-rw-r--r-- | patches/revert-acpi-ec-msleep.patch | 12 | ||||
-rw-r--r-- | patches/revert-cpuidle-simplification.patch | 146 | ||||
-rw-r--r-- | patches/squashfs-2.6.25.patch | 103 | ||||
-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; } |