rpms/kernel/devel kernel.spec, 1.995, 1.996 linux-2.6-squashfs.patch, 1.30, 1.31

Jeremy Katz katzj at fedoraproject.org
Tue Sep 30 19:21:03 UTC 2008


Author: katzj

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv10083

Modified Files:
	kernel.spec linux-2.6-squashfs.patch 
Log Message:
* Tue Sep 30 2008 Jeremy Katz <katzj at redhat.com>
- update to squashfs 3.4



Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.995
retrieving revision 1.996
diff -u -r1.995 -r1.996
--- kernel.spec	30 Sep 2008 04:49:05 -0000	1.995
+++ kernel.spec	30 Sep 2008 19:20:32 -0000	1.996
@@ -1739,6 +1739,9 @@
 %kernel_variant_files -k vmlinux %{with_kdump} kdump
 
 %changelog
+* Tue Sep 30 2008 Jeremy Katz <katzj at redhat.com>
+- update to squashfs 3.4
+
 * Mon Sep 29 2008 Roland McGrath <roland at redhat.com>
 - 2.6.27-rc8
 - utrace update

linux-2.6-squashfs.patch:

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




More information about the fedora-extras-commits mailing list