SOURCES: kernel-desktop-squashfs.patch - updated from kernel-squas...

glen glen at pld-linux.org
Wed Apr 9 00:17:49 CEST 2008


Author: glen                         Date: Tue Apr  8 22:17:49 2008 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- updated from kernel-squashfs.patch r1.1.2.3

---- Files affected:
SOURCES:
   kernel-desktop-squashfs.patch (1.6 -> 1.7) 

---- Diffs:

================================================================
Index: SOURCES/kernel-desktop-squashfs.patch
diff -u SOURCES/kernel-desktop-squashfs.patch:1.6 SOURCES/kernel-desktop-squashfs.patch:1.7
--- SOURCES/kernel-desktop-squashfs.patch:1.6	Sat Aug 18 19:36:53 2007
+++ SOURCES/kernel-desktop-squashfs.patch	Wed Apr  9 00:17:44 2008
@@ -1,26 +1,27 @@
-diff -x .gitignore -Nurp linux-2.6.20/fs/Kconfig linux-2.6.20-squashfs3.2-r2/fs/Kconfig
---- linux-2.6.20/fs/Kconfig	2006-12-25 01:13:12.000000000 +0000
-+++ linux-2.6.20-squashfs3.2-r2/fs/Kconfig	2007-01-16 02:06:03.000000000 +0000
-@@ -1404,6 +1404,71 @@ config CRAMFS
+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
  
  	  If unsure, say N.
  
 +config SQUASHFS
-+	tristate "SquashFS 3.2 - Squashed file system support"
++	tristate "SquashFS 3.3 - Squashed file system support"
 +	select ZLIB_INFLATE
 +	help
-+	  Saying Y here includes support for SquashFS 3.2 (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 and all blocks are packed to minimise
-+	  data overhead. Block sizes greater than 4K are supported up to a maximum of 64K.
-+	  SquashFS 3.1 supports 64 bit filesystems and files (larger than 4GB), full
-+	  uid/gid information, hard links and timestamps.
-+
-+	  Squashfs is intended for general read-only filesystem use, for archival
-+	  use (i.e. in cases where a .tar.gz file may be used), and in embedded
-+	  systems where low overhead is needed.  Further information and filesystem tools
-+	  are available from http://squashfs.sourceforge.net.
++	  Saying Y here includes support for SquashFS 3.3 (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
++	  and all blocks are packed to minimise data overhead. Block sizes
++	  greater than 4K are supported up to a maximum of 1 Mbytes (default
++	  block size 128K).  SquashFS 3.3 supports 64 bit filesystems and files
++	  (larger than 4GB), full uid/gid information, hard links and timestamps.  
++
++	  Squashfs is intended for general read-only filesystem use, for
++	  archival use (i.e. in cases where a .tar.gz file may be used), and in
++	  embedded systems where low overhead is needed.  Further information
++	  and filesystem tools are available from http://squashfs.sourceforge.net.
 +
 +	  If you want to compile this as a module ( = code which can be
 +	  inserted in and removed from the running kernel whenever you want),
@@ -32,13 +33,11 @@
 +
 +config SQUASHFS_EMBEDDED
 +
-+	bool "Additional options for memory-constrained systems" 
++	bool "Additional option for memory-constrained systems" 
 +	depends on SQUASHFS
 +	default n
 +	help
-+	  Saying Y here allows you to specify cache sizes and how Squashfs
-+	  allocates memory.  This is only intended for memory constrained
-+	  systems.
++	  Saying Y here allows you to specify cache size.
 +
 +	  If unsure, say N.
 +
@@ -56,43 +55,29 @@
 +	  Note there must be at least one cached fragment.  Anything
 +	  much more than three will probably not make much difference.
 +
-+config SQUASHFS_VMALLOC
-+	bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED
-+	depends on SQUASHFS
-+	default n
-+	help
-+	  By default SquashFS uses kmalloc to obtain fragment cache memory.
-+	  Kmalloc memory is the standard kernel allocator, but it can fail
-+	  on memory constrained systems.  Because of the way Vmalloc works,
-+	  Vmalloc can succeed when kmalloc fails.  Specifying this option
-+	  will make SquashFS always use Vmalloc to allocate the
-+	  fragment cache memory.
-+
-+	  If unsure, say N.
-+
  config VXFS_FS
  	tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
  	depends on BLOCK
-diff -x .gitignore -Nurp linux-2.6.20/fs/Makefile linux-2.6.20-squashfs3.2-r2/fs/Makefile
---- linux-2.6.20/fs/Makefile	2006-12-25 01:13:12.000000000 +0000
-+++ linux-2.6.20-squashfs3.2-r2/fs/Makefile	2007-01-16 02:06:03.000000000 +0000
-@@ -68,6 +68,7 @@ obj-$(CONFIG_JBD)		+= jbd/
+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/
  obj-$(CONFIG_JBD2)		+= jbd2/
  obj-$(CONFIG_EXT2_FS)		+= ext2/
  obj-$(CONFIG_CRAMFS)		+= cramfs/
 +obj-$(CONFIG_SQUASHFS)		+= squashfs/
- obj-$(CONFIG_RAMFS)		+= ramfs/
+ obj-y				+= ramfs/
  obj-$(CONFIG_HUGETLBFS)		+= hugetlbfs/
  obj-$(CONFIG_CODA_FS)		+= coda/
-diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/inode.c linux-2.6.20-squashfs3.2-r2/fs/squashfs/inode.c
---- linux-2.6.20/fs/squashfs/inode.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/inode.c	2007-01-16 02:28:36.000000000 +0000
-@@ -0,0 +1,2327 @@
+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 @@
 +/*
 + * Squashfs - a compressed read only filesystem for Linux
 + *
 + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
-+ * Phillip Lougher <phillip at lougher.org.uk>
++ * 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
@@ -121,9 +106,12 @@
 +#include <linux/vfs.h>
 +#include <linux/vmalloc.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_get_parent(struct dentry *child);
 +static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode);
@@ -133,7 +121,6 @@
 +				int readahead_blks, char *block_list,
 +				unsigned short **block_p, unsigned int *bsize);
 +static int squashfs_readpage(struct file *file, struct page *page);
-+static int squashfs_readpage4K(struct file *file, struct page *page);
 +static int squashfs_readdir(struct file *, void *, filldir_t);
 +static struct dentry *squashfs_lookup(struct inode *, struct dentry *,
 +				struct nameidata *);
@@ -186,10 +173,6 @@
 +	.readpage = squashfs_readpage
 +};
 +
-+SQSH_EXTERN const struct address_space_operations squashfs_aops_4K = {
-+	.readpage = squashfs_readpage4K
-+};
-+
 +static const struct file_operations squashfs_dir_ops = {
 +	.read = generic_read_dir,
 +	.readdir = squashfs_readdir
@@ -273,30 +256,36 @@
 +{
 +	struct squashfs_sb_info *msblk = s->s_fs_info;
 +	struct squashfs_super_block *sblk = &msblk->sblk;
-+	struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >>
-+			msblk->devblksize_log2) + 2];
++	struct buffer_head **bh;
 +	unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
 +	unsigned int cur_index = index >> msblk->devblksize_log2;
 +	int bytes, avail_bytes, b = 0, k = 0;
 +	unsigned int compressed;
 +	unsigned int c_byte = length;
 +
++	bh = kmalloc(((sblk->block_size >> msblk->devblksize_log2) + 1) *
++								sizeof(struct buffer_head *), GFP_KERNEL);
++	if (bh == NULL)
++		goto read_failure;
++
 +	if (c_byte) {
 +		bytes = msblk->devblksize - offset;
 +		compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
 +		c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
 +
-+		TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index, compressed
-+					? "" : "un", (unsigned int) c_byte, srclength);
++		TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index,
++					compressed ? "" : "un", (unsigned int) c_byte, srclength);
 +
 +		if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used)
 +			goto read_failure;
 +
-+		if (!(bh[0] = sb_getblk(s, cur_index)))
++		bh[0] = sb_getblk(s, cur_index);
++		if (bh[0] == NULL)
 +			goto block_release;
 +
 +		for (b = 1; bytes < c_byte; b++) {
-+			if (!(bh[b] = sb_getblk(s, ++cur_index)))
++			bh[b] = sb_getblk(s, ++cur_index);
++			if (bh[b] == NULL)
 +				goto block_release;
 +			bytes += msblk->devblksize;
 +		}
@@ -305,8 +294,8 @@
 +		if (index < 0 || (index + 2) > sblk->bytes_used)
 +			goto read_failure;
 +
-+		if (!(bh[0] = get_block_length(s, &cur_index, &offset,
-+								&c_byte)))
++		bh[0] = get_block_length(s, &cur_index, &offset, &c_byte);
++		if (bh[0] == NULL)
 +			goto read_failure;
 +
 +		bytes = msblk->devblksize - offset;
@@ -320,7 +309,8 @@
 +			goto read_failure;
 +
 +		for (b = 1; bytes < c_byte; b++) {
-+			if (!(bh[b] = sb_getblk(s, ++cur_index)))
++			bh[b] = sb_getblk(s, ++cur_index);
++			if (bh[b] == NULL)
 +				goto block_release;
 +			bytes += msblk->devblksize;
 +		}
@@ -340,9 +330,8 @@
 +		msblk->stream.avail_out = srclength;
 +
 +		for (bytes = 0; k < b; k++) {
-+			avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
-+					msblk->devblksize - offset :
-+					c_byte - bytes;
++			avail_bytes = min(c_byte - bytes, msblk->devblksize - offset);
++
 +			wait_on_buffer(bh[k]);
 +			if (!buffer_uptodate(bh[k]))
 +				goto release_mutex;
@@ -353,8 +342,8 @@
 +			if (k == 0) {
 +				zlib_err = zlib_inflateInit(&msblk->stream);
 +				if (zlib_err != Z_OK) {
-+					ERROR("zlib_inflateInit returned unexpected result 0x%x, srclength %d\n",
-+						zlib_err, srclength);
++					ERROR("zlib_inflateInit returned unexpected result 0x%x,"
++						" srclength %d\n", zlib_err, srclength);
 +					goto release_mutex;
 +				}
 +
@@ -367,8 +356,9 @@
 +
 +			zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH);
 +			if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) {
-+				ERROR("zlib_inflate returned unexpected result 0x%x, srclength %d, avail_in %d, avail_out %d\n",
-+					zlib_err, srclength, msblk->stream.avail_in, msblk->stream.avail_out);
++				ERROR("zlib_inflate returned unexpected result 0x%x,"
++					" srclength %d, avail_in %d, avail_out %d\n", zlib_err,
++					srclength, msblk->stream.avail_in, msblk->stream.avail_out);
 +				goto release_mutex;
 +			}
 +
@@ -382,8 +372,8 @@
 +
 +		zlib_err = zlib_inflateEnd(&msblk->stream);
 +		if (zlib_err != Z_OK) {
-+			ERROR("zlib_inflateEnd returned unexpected result 0x%x, srclength %d\n",
-+				zlib_err, srclength);
++			ERROR("zlib_inflateEnd returned unexpected result 0x%x,"
++				" srclength %d\n", zlib_err, srclength);
 +			goto release_mutex;
 +		}
 +		bytes = msblk->stream.total_out;
@@ -393,14 +383,13 @@
 +
 +		for(i = 0; i < b; i++) {
 +			wait_on_buffer(bh[i]);
-+			if(!buffer_uptodate(bh[i]))
++			if (!buffer_uptodate(bh[i]))
 +				goto block_release;
 +		}
 +
 +		for (bytes = 0; k < b; k++) {
-+			avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
-+					msblk->devblksize - offset :
-+					c_byte - bytes;
++			avail_bytes = min(c_byte - bytes, msblk->devblksize - offset);
++
 +			memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes);
 +			bytes += avail_bytes;
 +			offset = 0;
@@ -410,8 +399,9 @@
 +
 +	if (next_index)
 +		*next_index = index + c_byte + (length ? 0 :
-+				(SQUASHFS_CHECK_DATA(msblk->sblk.flags)
-+				 ? 3 : 2));
++				(SQUASHFS_CHECK_DATA(msblk->sblk.flags) ? 3 : 2));
++
++	kfree(bh);
 +	return bytes;
 +
 +release_mutex:
@@ -423,11 +413,12 @@
 +
 +read_failure:
 +	ERROR("sb_bread failed reading block 0x%x\n", cur_index);
++	kfree(bh);
 +	return 0;
 +}
 +
 +
-+SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer,
++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)
@@ -438,68 +429,65 @@
 +
 +	TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);
 +
-+	while ( 1 ) {
-+		for (i = 0; i < SQUASHFS_CACHED_BLKS; i++) 
++	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) {
++		if (i == squashfs_cached_blks) {
 +			/* read inode header block */
-+			for (i = msblk->next_cache, n = SQUASHFS_CACHED_BLKS;
-+					n ; n --, i = (i + 1) %
-+					SQUASHFS_CACHED_BLKS)
-+				if (msblk->block_cache[i].block !=
-+							SQUASHFS_USED_BLK)
-+					break;
-+
-+			if (n == 0) {
-+				wait_queue_t wait;
-+
-+				init_waitqueue_entry(&wait, current);
-+				add_wait_queue(&msblk->waitq, &wait);
-+				set_current_state(TASK_UNINTERRUPTIBLE);
-+ 				mutex_unlock(&msblk->block_cache_mutex);
-+				schedule();
-+				set_current_state(TASK_RUNNING);
-+				remove_wait_queue(&msblk->waitq, &wait);
++			if (msblk->unused_cache_blks == 0) {
++				mutex_unlock(&msblk->block_cache_mutex);
++				wait_event(msblk->waitq, msblk->unused_cache_blks);
 +				continue;
 +			}
-+			msblk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS;
 +
-+			if (msblk->block_cache[i].block ==
-+							SQUASHFS_INVALID_BLK) {
-+				if (!(msblk->block_cache[i].data =
-+						kmalloc(SQUASHFS_METADATA_SIZE,
-+						GFP_KERNEL))) {
-+					ERROR("Failed to allocate cache"
-+							"block\n");
++			i = msblk->next_cache;
++			for (n = 0; n < squashfs_cached_blks; n++) {
++				if (msblk->block_cache[i].block != SQUASHFS_USED_BLK)
++					break;
++				i = (i + 1) % squashfs_cached_blks;
++			}
++
++			msblk->next_cache = (i + 1) % squashfs_cached_blks;
++
++			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);
++				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);
++				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;
-+				kfree(msblk->block_cache[i].data);
++				msblk->unused_cache_blks ++;
++				smp_mb();
++				vfree(msblk->block_cache[i].data);
 +				wake_up(&msblk->waitq);
 +				mutex_unlock(&msblk->block_cache_mutex);
 +				goto out;
 +			}
 +
 +			mutex_lock(&msblk->block_cache_mutex);
-+			wake_up(&msblk->waitq);
 +			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);
 +		}
 +
@@ -515,8 +503,7 @@
 +			goto out;
 +		} else if (bytes >= length) {
 +			if (buffer)
-+				memcpy(buffer, msblk->block_cache[i].data +
-+						offset, length);
++				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;
 +				*next_offset = 0;
@@ -528,9 +515,8 @@
 +			goto finish;
 +		} else {
 +			if (buffer) {
-+				memcpy(buffer, msblk->block_cache[i].data +
-+						offset, bytes);
-+				buffer += bytes;
++				memcpy(buffer, msblk->block_cache[i].data + offset, bytes);
++				buffer = (char *) buffer + bytes;
 +			}
 +			block = msblk->block_cache[i].next_index;
 +			mutex_unlock(&msblk->block_cache_mutex);
@@ -559,17 +545,13 @@
 +	if (msblk->swap) {
 +		struct squashfs_fragment_entry sfragment_entry;
 +
-+		if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
-+					start_block, offset,
-+					sizeof(sfragment_entry), &start_block,
-+					&offset))
++		if (!squashfs_get_cached_block(s, &sfragment_entry, start_block, offset,
++					 sizeof(sfragment_entry), &start_block, &offset))
 +			goto out;
 +		SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry);
 +	} else
-+		if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
-+					start_block, offset,
-+					sizeof(fragment_entry), &start_block,
-+					&offset))
++		if (!squashfs_get_cached_block(s, &fragment_entry, start_block, offset,
++					 sizeof(fragment_entry), &start_block, &offset))
 +			goto out;
 +
 +	*fragment_start_block = fragment_entry.start_block;
@@ -582,90 +564,92 @@
 +}
 +
 +
-+SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, struct
-+					squashfs_fragment_cache *fragment)
++SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk,
++				struct squashfs_fragment_cache *fragment)
 +{
 +	mutex_lock(&msblk->fragment_mutex);
 +	fragment->locked --;
-+	wake_up(&msblk->fragment_wait_queue);
++	if (fragment->locked == 0) {
++		msblk->unused_frag_blks ++;
++		smp_mb();
++		wake_up(&msblk->fragment_wait_queue);
++	}
 +	mutex_unlock(&msblk->fragment_mutex);
 +}
 +
 +
-+SQSH_EXTERN struct squashfs_fragment_cache *get_cached_fragment(struct super_block
-+					*s, long long start_block,
-+					int length)
++SQSH_EXTERN
++struct squashfs_fragment_cache *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 ) {
++	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) {
-+			for (i = msblk->next_fragment, n =
-+				SQUASHFS_CACHED_FRAGMENTS; n &&
-+				msblk->fragment[i].locked; n--, i = (i + 1) %
-+				SQUASHFS_CACHED_FRAGMENTS);
-+
-+			if (n == 0) {
-+				wait_queue_t wait;
-+
-+				init_waitqueue_entry(&wait, current);
-+				add_wait_queue(&msblk->fragment_wait_queue,
-+									&wait);
-+				set_current_state(TASK_UNINTERRUPTIBLE);
++			if (msblk->unused_frag_blks == 0) {
 +				mutex_unlock(&msblk->fragment_mutex);
-+				schedule();
-+				set_current_state(TASK_RUNNING);
-+				remove_wait_queue(&msblk->fragment_wait_queue,
-+									&wait);
++				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)
-+				if (!(msblk->fragment[i].data = SQUASHFS_ALLOC
-+						(SQUASHFS_FILE_MAX_SIZE))) {
-+					ERROR("Failed to allocate fragment "
-+							"cache block\n");
++			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);
 +
-+			if (!(msblk->fragment[i].length = squashfs_read_data(s,
-+						msblk->fragment[i].data,
-+						start_block, length, NULL, sblk->block_size))) {
-+				ERROR("Unable to read fragment cache block "
-+							"[%llx]\n", start_block);
++			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);
++				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);
++			msblk->fragment[i].block, msblk->fragment[i].locked);
 +		break;
 +	}
 +
@@ -677,7 +661,7 @@
 +
 +
 +static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i,
-+		struct squashfs_base_inode_header *inodeb)
++				struct squashfs_base_inode_header *inodeb)
 +{
 +	i->i_ino = inodeb->inode_number;
 +	i->i_mtime.tv_sec = inodeb->mtime;
@@ -686,6 +670,7 @@
 +	i->i_uid = msblk->uid[inodeb->uid];
 +	i->i_mode = inodeb->mode;
 +	i->i_size = 0;
++
 +	if (inodeb->guid == SQUASHFS_GUIDS)
 +		i->i_gid = i->i_uid;
 +	else
@@ -705,11 +690,11 @@
<<Diff was trimmed, longer than 597 lines>>

---- CVS-web:
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/SOURCES/kernel-desktop-squashfs.patch?r1=1.6&r2=1.7&f=u



More information about the pld-cvs-commit mailing list