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 <[EMAIL PROTECTED]>
++ * Phillip Lougher <[EMAIL PROTECTED]>
 + *
 + * 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

_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to