]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.33 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 21 Apr 2010 19:21:25 +0000 (12:21 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 21 Apr 2010 19:21:25 +0000 (12:21 -0700)
14 files changed:
queue-2.6.33/acpi-ec-allow-multibyte-access-to-ec.patch [new file with mode: 0644]
queue-2.6.33/e1000e-stop-cleaning-when-we-reach-tx_ring-next_to_use.patch [new file with mode: 0644]
queue-2.6.33/ecryptfs-decrypt-symlink-target-for-stat-size.patch [new file with mode: 0644]
queue-2.6.33/ecryptfs-fix-error-code-for-missing-xattrs-in-lower-fs.patch [new file with mode: 0644]
queue-2.6.33/ecryptfs-fix-use-with-tmpfs-by-removing-d_drop-from-ecryptfs_destroy_inode.patch [new file with mode: 0644]
queue-2.6.33/iwlwifi-clear-all-tx-queues-when-firmware-ready.patch [new file with mode: 0644]
queue-2.6.33/iwlwifi-fix-scan-race.patch [new file with mode: 0644]
queue-2.6.33/perf_events-x86-implement-intel-westmere-nehalem-ex-support.patch [new file with mode: 0644]
queue-2.6.33/series
queue-2.6.33/usb-cdc-acm-fix-stupid-null-pointer-in-resume.patch [new file with mode: 0644]
queue-2.6.33/usb-cdc-acm-update-to-new-autopm-api.patch [new file with mode: 0644]
queue-2.6.33/xfs-check-for-more-work-before-sleeping-in-xfssyncd.patch [new file with mode: 0644]
queue-2.6.33/xfs-fix-locking-for-inode-cache-radix-tree-tag-updates.patch [new file with mode: 0644]
queue-2.6.33/xfs-non-blocking-inode-locking-in-io-completion.patch [new file with mode: 0644]

diff --git a/queue-2.6.33/acpi-ec-allow-multibyte-access-to-ec.patch b/queue-2.6.33/acpi-ec-allow-multibyte-access-to-ec.patch
new file mode 100644 (file)
index 0000000..24521d2
--- /dev/null
@@ -0,0 +1,105 @@
+From ben@decadent.org.uk  Wed Apr 21 12:11:57 2010
+From: Alexey Starikovskiy <astarikovskiy@suse.de>
+Date: Sat, 10 Apr 2010 02:18:35 +0100
+Subject: ACPI: EC: Allow multibyte access to EC
+To: stable@kernel.org
+Cc: Len Brown <len.brown@intel.com>, 563313@bugs.debian.org, Alexey Starikovskiy <astarikovskiy@suse.de>
+Message-ID: <1270862315.2176.69.camel@localhost>
+
+
+From: Alexey Starikovskiy <astarikovskiy@suse.de>
+
+commit dadf28a10c3eb29421837a2e413ab869ebd upstream
+
+http://bugzilla.kernel.org/show_bug.cgi?id=14667
+
+[bwh: Backport to 2.6.32; same applies to 2.6.33]
+
+Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/acpica/exprep.c |   12 ++++++++++++
+ drivers/acpi/ec.c            |   35 +++++++++--------------------------
+ 2 files changed, 21 insertions(+), 26 deletions(-)
+
+--- a/drivers/acpi/acpica/exprep.c
++++ b/drivers/acpi/acpica/exprep.c
+@@ -468,6 +468,18 @@ acpi_status acpi_ex_prep_field_value(str
+               acpi_ut_add_reference(obj_desc->field.region_obj);
++              /* allow full data read from EC address space */
++              if (obj_desc->field.region_obj->region.space_id ==
++                      ACPI_ADR_SPACE_EC) {
++                      if (obj_desc->common_field.bit_length > 8)
++                              obj_desc->common_field.access_bit_width =
++                              ACPI_ROUND_UP(obj_desc->common_field.
++                                                      bit_length, 8);
++                              obj_desc->common_field.access_byte_width =
++                              ACPI_DIV_8(obj_desc->common_field.
++                                                      access_bit_width);
++              }
++
+               ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
+                                 "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
+                                 obj_desc->field.start_field_bit_offset,
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -589,12 +589,12 @@ static u32 acpi_ec_gpe_handler(void *dat
+ static acpi_status
+ acpi_ec_space_handler(u32 function, acpi_physical_address address,
+-                    u32 bits, acpi_integer *value,
++                    u32 bits, acpi_integer *value64,
+                     void *handler_context, void *region_context)
+ {
+       struct acpi_ec *ec = handler_context;
+-      int result = 0, i;
+-      u8 temp = 0;
++      int result = 0, i, bytes = bits / 8;
++      u8 *value = (u8 *)value64;
+       if ((address > 0xFF) || !value || !handler_context)
+               return AE_BAD_PARAMETER;
+@@ -602,32 +602,15 @@ acpi_ec_space_handler(u32 function, acpi
+       if (function != ACPI_READ && function != ACPI_WRITE)
+               return AE_BAD_PARAMETER;
+-      if (bits != 8 && acpi_strict)
+-              return AE_BAD_PARAMETER;
+-
+-      if (EC_FLAGS_MSI)
++      if (EC_FLAGS_MSI || bits > 8)
+               acpi_ec_burst_enable(ec);
+-      if (function == ACPI_READ) {
+-              result = acpi_ec_read(ec, address, &temp);
+-              *value = temp;
+-      } else {
+-              temp = 0xff & (*value);
+-              result = acpi_ec_write(ec, address, temp);
+-      }
+-
+-      for (i = 8; unlikely(bits - i > 0); i += 8) {
+-              ++address;
+-              if (function == ACPI_READ) {
+-                      result = acpi_ec_read(ec, address, &temp);
+-                      (*value) |= ((acpi_integer)temp) << i;
+-              } else {
+-                      temp = 0xff & ((*value) >> i);
+-                      result = acpi_ec_write(ec, address, temp);
+-              }
+-      }
++      for (i = 0; i < bytes; ++i, ++address, ++value)
++              result = (function == ACPI_READ) ?
++                      acpi_ec_read(ec, address, value) :
++                      acpi_ec_write(ec, address, *value);
+-      if (EC_FLAGS_MSI)
++      if (EC_FLAGS_MSI || bits > 8)
+               acpi_ec_burst_disable(ec);
+       switch (result) {
diff --git a/queue-2.6.33/e1000e-stop-cleaning-when-we-reach-tx_ring-next_to_use.patch b/queue-2.6.33/e1000e-stop-cleaning-when-we-reach-tx_ring-next_to_use.patch
new file mode 100644 (file)
index 0000000..29d096d
--- /dev/null
@@ -0,0 +1,35 @@
+From dac876193cd79ced36d0462749ea47c05844fb49 Mon Sep 17 00:00:00 2001
+From: Terry Loftin <terry.loftin@hp.com>
+Date: Fri, 9 Apr 2010 10:29:49 +0000
+Subject: e1000e: stop cleaning when we reach tx_ring->next_to_use
+
+From: Terry Loftin <terry.loftin@hp.com>
+
+commit dac876193cd79ced36d0462749ea47c05844fb49 upstream.
+
+Tx ring buffers after tx_ring->next_to_use are volatile and could
+change, possibly causing a crash.  Stop cleaning when we hit
+tx_ring->next_to_use.
+
+Signed-off-by: Terry Loftin <terry.loftin@hp.com>
+Acked-by: Bruce Allan <bruce.w.allan@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Matthew Burgess <matthew@linuxfromscratch.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/e1000e/netdev.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/e1000e/netdev.c
++++ b/drivers/net/e1000e/netdev.c
+@@ -660,6 +660,8 @@ static bool e1000_clean_tx_irq(struct e1
+                               i = 0;
+               }
++              if (i == tx_ring->next_to_use)
++                      break;
+               eop = tx_ring->buffer_info[i].next_to_watch;
+               eop_desc = E1000_TX_DESC(*tx_ring, eop);
+       }
diff --git a/queue-2.6.33/ecryptfs-decrypt-symlink-target-for-stat-size.patch b/queue-2.6.33/ecryptfs-decrypt-symlink-target-for-stat-size.patch
new file mode 100644 (file)
index 0000000..62b8bf8
--- /dev/null
@@ -0,0 +1,166 @@
+From 3a60a1686f0d51c99bd0df8ac93050fb6dfce647 Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
+Date: Mon, 22 Mar 2010 00:41:35 -0500
+Subject: eCryptfs: Decrypt symlink target for stat size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
+
+commit 3a60a1686f0d51c99bd0df8ac93050fb6dfce647 upstream.
+
+Create a getattr handler for eCryptfs symlinks that is capable of
+reading the lower target and decrypting its path.  Prior to this patch,
+a stat's st_size field would represent the strlen of the encrypted path,
+while readlink() would return the strlen of the decrypted path.  This
+could lead to confusion in some userspace applications, since the two
+values should be equal.
+
+https://bugs.launchpad.net/bugs/524919
+
+Reported-by: Loïc Minier <loic.minier@canonical.com>
+Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ecryptfs/inode.c |  100 +++++++++++++++++++++++++++-------------------------
+ 1 file changed, 52 insertions(+), 48 deletions(-)
+
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -647,38 +647,17 @@ out_lock:
+       return rc;
+ }
+-static int
+-ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
++static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
++                                 size_t *bufsiz)
+ {
++      struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       char *lower_buf;
+-      size_t lower_bufsiz;
+-      struct dentry *lower_dentry;
+-      struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+-      char *plaintext_name;
+-      size_t plaintext_name_size;
++      size_t lower_bufsiz = PATH_MAX;
+       mm_segment_t old_fs;
+       int rc;
+-      lower_dentry = ecryptfs_dentry_to_lower(dentry);
+-      if (!lower_dentry->d_inode->i_op->readlink) {
+-              rc = -EINVAL;
+-              goto out;
+-      }
+-      mount_crypt_stat = &ecryptfs_superblock_to_private(
+-                                              dentry->d_sb)->mount_crypt_stat;
+-      /*
+-       * If the lower filename is encrypted, it will result in a significantly
+-       * longer name.  If needed, truncate the name after decode and decrypt.
+-       */
+-      if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
+-              lower_bufsiz = PATH_MAX;
+-      else
+-              lower_bufsiz = bufsiz;
+-      /* Released in this function */
+       lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
+-      if (lower_buf == NULL) {
+-              printk(KERN_ERR "%s: Out of memory whilst attempting to "
+-                     "kmalloc [%zd] bytes\n", __func__, lower_bufsiz);
++      if (!lower_buf) {
+               rc = -ENOMEM;
+               goto out;
+       }
+@@ -688,29 +667,31 @@ ecryptfs_readlink(struct dentry *dentry,
+                                                  (char __user *)lower_buf,
+                                                  lower_bufsiz);
+       set_fs(old_fs);
+-      if (rc >= 0) {
+-              rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
+-                                                        &plaintext_name_size,
+-                                                        dentry, lower_buf,
+-                                                        rc);
+-              if (rc) {
+-                      printk(KERN_ERR "%s: Error attempting to decode and "
+-                             "decrypt filename; rc = [%d]\n", __func__,
+-                              rc);
+-                      goto out_free_lower_buf;
+-              }
+-              /* Check for bufsiz <= 0 done in sys_readlinkat() */
+-              rc = copy_to_user(buf, plaintext_name,
+-                                min((size_t) bufsiz, plaintext_name_size));
+-              if (rc)
+-                      rc = -EFAULT;
+-              else
+-                      rc = plaintext_name_size;
+-              kfree(plaintext_name);
+-              fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);
+-      }
+-out_free_lower_buf:
++      if (rc < 0)
++              goto out;
++      lower_bufsiz = rc;
++      rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry,
++                                                lower_buf, lower_bufsiz);
++out:
+       kfree(lower_buf);
++      return rc;
++}
++
++static int
++ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
++{
++      char *kbuf;
++      size_t kbufsiz, copied;
++      int rc;
++
++      rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz);
++      if (rc)
++              goto out;
++      copied = min_t(size_t, bufsiz, kbufsiz);
++      rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied;
++      kfree(kbuf);
++      fsstack_copy_attr_atime(dentry->d_inode,
++                              ecryptfs_dentry_to_lower(dentry)->d_inode);
+ out:
+       return rc;
+ }
+@@ -1015,6 +996,28 @@ out:
+       return rc;
+ }
++int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
++                        struct kstat *stat)
++{
++      struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
++      int rc = 0;
++
++      mount_crypt_stat = &ecryptfs_superblock_to_private(
++                                              dentry->d_sb)->mount_crypt_stat;
++      generic_fillattr(dentry->d_inode, stat);
++      if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
++              char *target;
++              size_t targetsiz;
++
++              rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz);
++              if (!rc) {
++                      kfree(target);
++                      stat->size = targetsiz;
++              }
++      }
++      return rc;
++}
++
+ int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                    struct kstat *stat)
+ {
+@@ -1132,6 +1135,7 @@ const struct inode_operations ecryptfs_s
+       .put_link = ecryptfs_put_link,
+       .permission = ecryptfs_permission,
+       .setattr = ecryptfs_setattr,
++      .getattr = ecryptfs_getattr_link,
+       .setxattr = ecryptfs_setxattr,
+       .getxattr = ecryptfs_getxattr,
+       .listxattr = ecryptfs_listxattr,
diff --git a/queue-2.6.33/ecryptfs-fix-error-code-for-missing-xattrs-in-lower-fs.patch b/queue-2.6.33/ecryptfs-fix-error-code-for-missing-xattrs-in-lower-fs.patch
new file mode 100644 (file)
index 0000000..59c28e2
--- /dev/null
@@ -0,0 +1,61 @@
+From cfce08c6bdfb20ade979284e55001ca1f100ed51 Mon Sep 17 00:00:00 2001
+From: Christian Pulvermacher <pulvermacher@gmx.de>
+Date: Tue, 23 Mar 2010 11:51:38 -0500
+Subject: ecryptfs: fix error code for missing xattrs in lower fs
+
+From: Christian Pulvermacher <pulvermacher@gmx.de>
+
+commit cfce08c6bdfb20ade979284e55001ca1f100ed51 upstream.
+
+If the lower file system driver has extended attributes disabled,
+ecryptfs' own access functions return -ENOSYS instead of -EOPNOTSUPP.
+This breaks execution of programs in the ecryptfs mount, since the
+kernel expects the latter error when checking for security
+capabilities in xattrs.
+
+Signed-off-by: Christian Pulvermacher <pulvermacher@gmx.de>
+Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ecryptfs/inode.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -1042,7 +1042,7 @@ ecryptfs_setxattr(struct dentry *dentry,
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       if (!lower_dentry->d_inode->i_op->setxattr) {
+-              rc = -ENOSYS;
++              rc = -EOPNOTSUPP;
+               goto out;
+       }
+       mutex_lock(&lower_dentry->d_inode->i_mutex);
+@@ -1060,7 +1060,7 @@ ecryptfs_getxattr_lower(struct dentry *l
+       int rc = 0;
+       if (!lower_dentry->d_inode->i_op->getxattr) {
+-              rc = -ENOSYS;
++              rc = -EOPNOTSUPP;
+               goto out;
+       }
+       mutex_lock(&lower_dentry->d_inode->i_mutex);
+@@ -1087,7 +1087,7 @@ ecryptfs_listxattr(struct dentry *dentry
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       if (!lower_dentry->d_inode->i_op->listxattr) {
+-              rc = -ENOSYS;
++              rc = -EOPNOTSUPP;
+               goto out;
+       }
+       mutex_lock(&lower_dentry->d_inode->i_mutex);
+@@ -1104,7 +1104,7 @@ static int ecryptfs_removexattr(struct d
+       lower_dentry = ecryptfs_dentry_to_lower(dentry);
+       if (!lower_dentry->d_inode->i_op->removexattr) {
+-              rc = -ENOSYS;
++              rc = -EOPNOTSUPP;
+               goto out;
+       }
+       mutex_lock(&lower_dentry->d_inode->i_mutex);
diff --git a/queue-2.6.33/ecryptfs-fix-use-with-tmpfs-by-removing-d_drop-from-ecryptfs_destroy_inode.patch b/queue-2.6.33/ecryptfs-fix-use-with-tmpfs-by-removing-d_drop-from-ecryptfs_destroy_inode.patch
new file mode 100644 (file)
index 0000000..d9cf361
--- /dev/null
@@ -0,0 +1,59 @@
+From 133b8f9d632cc23715c6d72d1c5ac449e054a12a Mon Sep 17 00:00:00 2001
+From: Jeff Mahoney <jeffm@jeffreymahoney.com>
+Date: Fri, 19 Mar 2010 15:35:46 -0400
+Subject: ecryptfs: fix use with tmpfs by removing d_drop from ecryptfs_destroy_inode
+
+From: Jeff Mahoney <jeffm@jeffreymahoney.com>
+
+commit 133b8f9d632cc23715c6d72d1c5ac449e054a12a upstream.
+
+Since tmpfs has no persistent storage, it pins all its dentries in memory
+so they have d_count=1 when other file systems would have d_count=0.
+->lookup is only used to create new dentries. If the caller doesn't
+instantiate it, it's freed immediately at dput(). ->readdir reads
+directly from the dcache and depends on the dentries being hashed.
+
+When an ecryptfs mount is mounted, it associates the lower file and dentry
+with the ecryptfs files as they're accessed. When it's umounted and
+destroys all the in-memory ecryptfs inodes, it fput's the lower_files and
+d_drop's the lower_dentries. Commit 4981e081 added this and a d_delete in
+2008 and several months later commit caeeeecf removed the d_delete. I
+believe the d_drop() needs to be removed as well.
+
+The d_drop effectively hides any file that has been accessed via ecryptfs
+from the underlying tmpfs since it depends on it being hashed for it to
+be accessible. I've removed the d_drop on my development node and see no
+ill effects with basic testing on both tmpfs and persistent storage.
+
+As a side effect, after ecryptfs d_drops the dentries on tmpfs, tmpfs
+BUGs on umount. This is due to the dentries being unhashed.
+tmpfs->kill_sb is kill_litter_super which calls d_genocide to drop
+the reference pinning the dentry. It skips unhashed and negative dentries,
+but shrink_dcache_for_umount_subtree doesn't. Since those dentries
+still have an elevated d_count, we get a BUG().
+
+This patch removes the d_drop call and fixes both issues.
+
+This issue was reported at:
+https://bugzilla.novell.com/show_bug.cgi?id=567887
+
+Reported-by:  Árpád Bíró <biroa@demasz.hu>
+Signed-off-by: Jeff Mahoney <jeffm@suse.com>
+Cc: Dustin Kirkland <kirkland@canonical.com>
+Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ecryptfs/super.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/fs/ecryptfs/super.c
++++ b/fs/ecryptfs/super.c
+@@ -85,7 +85,6 @@ static void ecryptfs_destroy_inode(struc
+               if (lower_dentry->d_inode) {
+                       fput(inode_info->lower_file);
+                       inode_info->lower_file = NULL;
+-                      d_drop(lower_dentry);
+               }
+       }
+       ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
diff --git a/queue-2.6.33/iwlwifi-clear-all-tx-queues-when-firmware-ready.patch b/queue-2.6.33/iwlwifi-clear-all-tx-queues-when-firmware-ready.patch
new file mode 100644 (file)
index 0000000..64e22bc
--- /dev/null
@@ -0,0 +1,44 @@
+From dff010ac8e57e43669518a14c0e945dfeb80c2a7 Mon Sep 17 00:00:00 2001
+From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+Date: Tue, 2 Feb 2010 16:58:34 -0800
+Subject: iwlwifi: clear all tx queues when firmware ready
+
+From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+
+commit dff010ac8e57e43669518a14c0e945dfeb80c2a7 upstream.
+
+Reset and clear all the tx queues when finished downloading runtime
+uCode and ready to go into operation mode.
+
+Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+Cc: maximilian attems <max@stro.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-4965.c |    2 ++
+ drivers/net/wireless/iwlwifi/iwl-5000.c |    2 ++
+ 2 files changed, 4 insertions(+)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
++++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
+@@ -581,6 +581,8 @@ static int iwl4965_alive_notify(struct i
+       iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
++      /* reset to 0 to enable all the queue first */
++      priv->txq_ctx_active_msk = 0;
+       /* Map each Tx/cmd queue to its corresponding fifo */
+       for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
+               int ac = default_queue_to_tx_fifo[i];
+--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
+@@ -657,6 +657,8 @@ int iwl5000_alive_notify(struct iwl_priv
+       iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
++      /* reset to 0 to enable all the queue first */
++      priv->txq_ctx_active_msk = 0;
+       /* map qos queues to fifos one-to-one */
+       for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) {
+               int ac = iwl5000_default_queue_to_tx_fifo[i];
diff --git a/queue-2.6.33/iwlwifi-fix-scan-race.patch b/queue-2.6.33/iwlwifi-fix-scan-race.patch
new file mode 100644 (file)
index 0000000..37a37ab
--- /dev/null
@@ -0,0 +1,74 @@
+From bbcbb9ef9735c67da303d30bd6beb9e699f0f508 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 2 Feb 2010 10:57:12 -0800
+Subject: iwlwifi: fix scan race
+
+From: Reinette Chatre <reinette.chatre@intel.com>
+
+commit bbcbb9ef9735c67da303d30bd6beb9e699f0f508 upstream.
+
+There is a problem if an "internal short scan" is in progress when a
+mac80211 requested scan arrives. If this new scan request arrives within
+the "next_scan_jiffies" period then driver will immediately return success
+and complete the scan. The problem here is that the scan has not been
+fully initialized at this time (is_internal_short_scan is still set to true
+because of the currently running scan), which results in the scan
+completion never to be sent to mac80211. At this time also, evan though the
+internal short scan is still running the state (is_internal_short_scan)
+will be set to false, so when the internal scan does complete then mac80211
+will receive a scan completion.
+
+Fix this by checking right away if a scan is in progress when a scan
+request arrives from mac80211.
+
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+Cc: maximilian attems <max@stro.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-scan.c |   27 ++++++++++++---------------
+ 1 file changed, 12 insertions(+), 15 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
++++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
+@@ -404,21 +404,6 @@ EXPORT_SYMBOL(iwl_init_scan_params);
+ static int iwl_scan_initiate(struct iwl_priv *priv)
+ {
+-      if (!iwl_is_ready_rf(priv)) {
+-              IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n");
+-              return -EIO;
+-      }
+-
+-      if (test_bit(STATUS_SCANNING, &priv->status)) {
+-              IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
+-              return -EAGAIN;
+-      }
+-
+-      if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+-              IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
+-              return -EAGAIN;
+-      }
+-
+       IWL_DEBUG_INFO(priv, "Starting scan...\n");
+       set_bit(STATUS_SCANNING, &priv->status);
+       priv->scan_start = jiffies;
+@@ -449,6 +434,18 @@ int iwl_mac_hw_scan(struct ieee80211_hw
+               goto out_unlock;
+       }
++      if (test_bit(STATUS_SCANNING, &priv->status)) {
++              IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
++              ret = -EAGAIN;
++              goto out_unlock;
++      }
++
++      if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
++              IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
++              ret = -EAGAIN;
++              goto out_unlock;
++      }
++
+       /* We don't schedule scan within next_scan_jiffies period.
+        * Avoid scanning during possible EAPOL exchange, return
+        * success immediately.
diff --git a/queue-2.6.33/perf_events-x86-implement-intel-westmere-nehalem-ex-support.patch b/queue-2.6.33/perf_events-x86-implement-intel-westmere-nehalem-ex-support.patch
new file mode 100644 (file)
index 0000000..dd4aa93
--- /dev/null
@@ -0,0 +1,189 @@
+From youquan.song@linux.intel.com  Wed Apr 21 11:57:31 2010
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Date: Fri, 16 Apr 2010 05:14:41 -0400
+Subject: perf_events, x86: Implement Intel Westmere/Nehalem-EX support
+To: Vince Weaver <vweaver1@eecs.utk.edu>, gregkh@novell.com
+Cc: youquan.song@intel.com, a.p.zijlstra@chello.nl, gregkh@novell.com, "Youquan, Song" <youquan.song@linux.intel.com>, trenn@novell.com, stable@kernel.org
+Message-ID: <20100416091441.GA14199@youquan-linux.bj.intel.com>
+Content-Disposition: inline
+
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+
+original patch commit ids: 452a339a976e7f782c786eb3f73080401e2fa3a6 and
+134fbadf028a5977a1b06b0253d3ee33e6f0c642 
+
+perf_events, x86: Implement Intel Westmere support
+
+The new Intel documentation includes Westmere arch specific
+event maps that are significantly different from the Nehalem
+ones. Add support for this generation.
+
+Found the CPUID model numbers on wikipedia.
+
+Also ammend some Nehalem constraints, spotted those when looking
+for the differences between Nehalem and Westmere.
+
+Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Arjan van de Ven <arjan@linux.intel.com>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Stephane Eranian <eranian@google.com>
+LKML-Reference: <20100127221122.151865645@chello.nl>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+
+perf, x86: Enable Nehalem-EX support
+
+According to Intel Software Devel Manual Volume 3B, the
+Nehalem-EX PMU is just like regular Nehalem (except for the
+uncore support, which is completely different).
+
+Signed-off-by:  Vince Weaver <vweaver1@eecs.utk.edu>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Arjan van de Ven <arjan@linux.intel.com>
+Cc: Lin Ming <ming.m.lin@intel.com>
+LKML-Reference: <alpine.DEB.2.00.1004060956580.1417@cl320.eecs.utk.edu>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Cc: Youquan Song <youquan.song@linux.intel.com>
+---
+
+
+---
+ arch/x86/kernel/cpu/perf_event.c |  104 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 103 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/cpu/perf_event.c
++++ b/arch/x86/kernel/cpu/perf_event.c
+@@ -245,6 +245,97 @@ static u64 __read_mostly hw_cache_event_
+                               [PERF_COUNT_HW_CACHE_OP_MAX]
+                               [PERF_COUNT_HW_CACHE_RESULT_MAX];
++static const u64 westmere_hw_cache_event_ids
++                              [PERF_COUNT_HW_CACHE_MAX]
++                              [PERF_COUNT_HW_CACHE_OP_MAX]
++                              [PERF_COUNT_HW_CACHE_RESULT_MAX] =
++{
++ [ C(L1D) ] = {
++      [ C(OP_READ) ] = {
++              [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS       */
++              [ C(RESULT_MISS)   ] = 0x0151, /* L1D.REPL                     */
++      },
++      [ C(OP_WRITE) ] = {
++              [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES      */
++              [ C(RESULT_MISS)   ] = 0x0251, /* L1D.M_REPL                   */
++      },
++      [ C(OP_PREFETCH) ] = {
++              [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS        */
++              [ C(RESULT_MISS)   ] = 0x024e, /* L1D_PREFETCH.MISS            */
++      },
++ },
++ [ C(L1I ) ] = {
++      [ C(OP_READ) ] = {
++              [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                    */
++              [ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                   */
++      },
++      [ C(OP_WRITE) ] = {
++              [ C(RESULT_ACCESS) ] = -1,
++              [ C(RESULT_MISS)   ] = -1,
++      },
++      [ C(OP_PREFETCH) ] = {
++              [ C(RESULT_ACCESS) ] = 0x0,
++              [ C(RESULT_MISS)   ] = 0x0,
++      },
++ },
++ [ C(LL  ) ] = {
++      [ C(OP_READ) ] = {
++              [ C(RESULT_ACCESS) ] = 0x0324, /* L2_RQSTS.LOADS               */
++              [ C(RESULT_MISS)   ] = 0x0224, /* L2_RQSTS.LD_MISS             */
++      },
++      [ C(OP_WRITE) ] = {
++              [ C(RESULT_ACCESS) ] = 0x0c24, /* L2_RQSTS.RFOS                */
++              [ C(RESULT_MISS)   ] = 0x0824, /* L2_RQSTS.RFO_MISS            */
++      },
++      [ C(OP_PREFETCH) ] = {
++              [ C(RESULT_ACCESS) ] = 0x4f2e, /* LLC Reference                */
++              [ C(RESULT_MISS)   ] = 0x412e, /* LLC Misses                   */
++      },
++ },
++ [ C(DTLB) ] = {
++      [ C(OP_READ) ] = {
++              [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS       */
++              [ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.ANY         */
++      },
++      [ C(OP_WRITE) ] = {
++              [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES      */
++              [ C(RESULT_MISS)   ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS  */
++      },
++      [ C(OP_PREFETCH) ] = {
++              [ C(RESULT_ACCESS) ] = 0x0,
++              [ C(RESULT_MISS)   ] = 0x0,
++      },
++ },
++ [ C(ITLB) ] = {
++      [ C(OP_READ) ] = {
++              [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P           */
++              [ C(RESULT_MISS)   ] = 0x0185, /* ITLB_MISSES.ANY              */
++      },
++      [ C(OP_WRITE) ] = {
++              [ C(RESULT_ACCESS) ] = -1,
++              [ C(RESULT_MISS)   ] = -1,
++      },
++      [ C(OP_PREFETCH) ] = {
++              [ C(RESULT_ACCESS) ] = -1,
++              [ C(RESULT_MISS)   ] = -1,
++      },
++ },
++ [ C(BPU ) ] = {
++      [ C(OP_READ) ] = {
++              [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
++              [ C(RESULT_MISS)   ] = 0x03e8, /* BPU_CLEARS.ANY               */
++      },
++      [ C(OP_WRITE) ] = {
++              [ C(RESULT_ACCESS) ] = -1,
++              [ C(RESULT_MISS)   ] = -1,
++      },
++      [ C(OP_PREFETCH) ] = {
++              [ C(RESULT_ACCESS) ] = -1,
++              [ C(RESULT_MISS)   ] = -1,
++      },
++ },
++};
++
+ static __initconst u64 nehalem_hw_cache_event_ids
+                               [PERF_COUNT_HW_CACHE_MAX]
+                               [PERF_COUNT_HW_CACHE_OP_MAX]
+@@ -2118,6 +2209,7 @@ static __init int intel_pmu_init(void)
+        * Install the hw-cache-events table:
+        */
+       switch (boot_cpu_data.x86_model) {
++
+       case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
+       case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
+       case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
+@@ -2129,7 +2221,9 @@ static __init int intel_pmu_init(void)
+               event_constraints = intel_core_event_constraints;
+               break;
+       default:
+-      case 26:
++      case 26: /* 45 nm nehalem, "Bloomfield" */
++      case 30: /* 45 nm nehalem, "Lynnfield" */
++      case 46: /* 45 nm nehalem-ex, "Beckton" */
+               memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
+                      sizeof(hw_cache_event_ids));
+@@ -2142,6 +2236,14 @@ static __init int intel_pmu_init(void)
+               pr_cont("Atom events, ");
+               break;
++
++      case 37: /* 32 nm nehalem, "Clarkdale" */
++      case 44: /* 32 nm nehalem, "Gulftown" */
++              memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
++                     sizeof(hw_cache_event_ids));
++
++              pr_cont("Westmere events, ");
++              break;
+       }
+       return 0;
+ }
index 6093551205444fb221377bb9c50996f745c75836..1cccc6eea52533260caf7148773b269c110eb993 100644 (file)
@@ -104,3 +104,16 @@ i2c-i801-add-intel-cougar-point-device-ids.patch
 b43-allow-pio-mode-to-be-selected-at-module-load.patch
 b43-fall-back-gracefully-to-pio-mode-after-fatal-dma-errors.patch
 alsa-hda-add-position_fix-quirk-for-biostar-mobo.patch
+ecryptfs-fix-use-with-tmpfs-by-removing-d_drop-from-ecryptfs_destroy_inode.patch
+ecryptfs-decrypt-symlink-target-for-stat-size.patch
+ecryptfs-fix-error-code-for-missing-xattrs-in-lower-fs.patch
+usb-cdc-acm-update-to-new-autopm-api.patch
+usb-cdc-acm-fix-stupid-null-pointer-in-resume.patch
+iwlwifi-clear-all-tx-queues-when-firmware-ready.patch
+iwlwifi-fix-scan-race.patch
+e1000e-stop-cleaning-when-we-reach-tx_ring-next_to_use.patch
+perf_events-x86-implement-intel-westmere-nehalem-ex-support.patch
+xfs-non-blocking-inode-locking-in-io-completion.patch
+xfs-fix-locking-for-inode-cache-radix-tree-tag-updates.patch
+xfs-check-for-more-work-before-sleeping-in-xfssyncd.patch
+acpi-ec-allow-multibyte-access-to-ec.patch
diff --git a/queue-2.6.33/usb-cdc-acm-fix-stupid-null-pointer-in-resume.patch b/queue-2.6.33/usb-cdc-acm-fix-stupid-null-pointer-in-resume.patch
new file mode 100644 (file)
index 0000000..6ef94da
--- /dev/null
@@ -0,0 +1,30 @@
+From f0730924e9e32bb8935c60040a26d94179355088 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oliver@neukum.org>
+Date: Wed, 3 Mar 2010 00:37:56 +0100
+Subject: USB: cdc-acm: Fix stupid NULL pointer in resume()
+
+From: Oliver Neukum <oliver@neukum.org>
+
+commit f0730924e9e32bb8935c60040a26d94179355088 upstream.
+
+Stupid logic bug passing a just nulled pointer
+
+Signed-off-by: Oliver Neukum <neukum@b1-systems.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/class/cdc-acm.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1441,7 +1441,7 @@ static int acm_resume(struct usb_interfa
+                       wb = acm->delayed_wb;
+                       acm->delayed_wb = NULL;
+                       spin_unlock_irq(&acm->write_lock);
+-                      acm_start_wb(acm, acm->delayed_wb);
++                      acm_start_wb(acm, wb);
+               } else {
+                       spin_unlock_irq(&acm->write_lock);
+               }
diff --git a/queue-2.6.33/usb-cdc-acm-update-to-new-autopm-api.patch b/queue-2.6.33/usb-cdc-acm-update-to-new-autopm-api.patch
new file mode 100644 (file)
index 0000000..0f0992e
--- /dev/null
@@ -0,0 +1,126 @@
+From 97d35f95552c9a0ee4777a7f04431a9fd1260478 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oliver@neukum.org>
+Date: Wed, 16 Dec 2009 17:05:57 +0100
+Subject: USB: cdc-acm: Update to new autopm API
+
+From: Oliver Neukum <oliver@neukum.org>
+
+commit 97d35f95552c9a0ee4777a7f04431a9fd1260478 upstream.
+
+Update cdc-acm to the async methods eliminating the workqueue
+
+[This fixes a reported lockup for the cdc-acm driver - gregkh]
+
+Signed-off-by: Oliver Neukum <oliver@neukum.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/class/cdc-acm.c |   43 ++++++++++++++++++++++---------------------
+ drivers/usb/class/cdc-acm.h |    1 -
+ 2 files changed, 22 insertions(+), 22 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -170,6 +170,7 @@ static void acm_write_done(struct acm *a
+ {
+       wb->use = 0;
+       acm->transmitting--;
++      usb_autopm_put_interface_async(acm->control);
+ }
+ /*
+@@ -211,9 +212,12 @@ static int acm_write_start(struct acm *a
+       }
+       dbg("%s susp_count: %d", __func__, acm->susp_count);
++      usb_autopm_get_interface_async(acm->control);
+       if (acm->susp_count) {
+-              acm->delayed_wb = wb;
+-              schedule_work(&acm->waker);
++              if (!acm->delayed_wb)
++                      acm->delayed_wb = wb;
++              else
++                      usb_autopm_put_interface_async(acm->control);
+               spin_unlock_irqrestore(&acm->write_lock, flags);
+               return 0;       /* A white lie */
+       }
+@@ -534,23 +538,6 @@ static void acm_softint(struct work_stru
+       tty_kref_put(tty);
+ }
+-static void acm_waker(struct work_struct *waker)
+-{
+-      struct acm *acm = container_of(waker, struct acm, waker);
+-      int rv;
+-
+-      rv = usb_autopm_get_interface(acm->control);
+-      if (rv < 0) {
+-              dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__);
+-              return;
+-      }
+-      if (acm->delayed_wb) {
+-              acm_start_wb(acm, acm->delayed_wb);
+-              acm->delayed_wb = NULL;
+-      }
+-      usb_autopm_put_interface(acm->control);
+-}
+-
+ /*
+  * TTY handlers
+  */
+@@ -1178,7 +1165,6 @@ made_compressed_probe:
+       acm->urb_task.func = acm_rx_tasklet;
+       acm->urb_task.data = (unsigned long) acm;
+       INIT_WORK(&acm->work, acm_softint);
+-      INIT_WORK(&acm->waker, acm_waker);
+       init_waitqueue_head(&acm->drain_wait);
+       spin_lock_init(&acm->throttle_lock);
+       spin_lock_init(&acm->write_lock);
+@@ -1343,7 +1329,6 @@ static void stop_data_traffic(struct acm
+       tasklet_enable(&acm->urb_task);
+       cancel_work_sync(&acm->work);
+-      cancel_work_sync(&acm->waker);
+ }
+ static void acm_disconnect(struct usb_interface *intf)
+@@ -1435,6 +1420,7 @@ static int acm_suspend(struct usb_interf
+ static int acm_resume(struct usb_interface *intf)
+ {
+       struct acm *acm = usb_get_intfdata(intf);
++      struct acm_wb *wb;
+       int rv = 0;
+       int cnt;
+@@ -1449,6 +1435,21 @@ static int acm_resume(struct usb_interfa
+       mutex_lock(&acm->mutex);
+       if (acm->port.count) {
+               rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
++
++              spin_lock_irq(&acm->write_lock);
++              if (acm->delayed_wb) {
++                      wb = acm->delayed_wb;
++                      acm->delayed_wb = NULL;
++                      spin_unlock_irq(&acm->write_lock);
++                      acm_start_wb(acm, acm->delayed_wb);
++              } else {
++                      spin_unlock_irq(&acm->write_lock);
++              }
++
++              /*
++               * delayed error checking because we must
++               * do the write path at all cost
++               */
+               if (rv < 0)
+                       goto err_out;
+--- a/drivers/usb/class/cdc-acm.h
++++ b/drivers/usb/class/cdc-acm.h
+@@ -112,7 +112,6 @@ struct acm {
+       struct mutex mutex;
+       struct usb_cdc_line_coding line;                /* bits, stop, parity */
+       struct work_struct work;                        /* work queue entry for line discipline waking up */
+-      struct work_struct waker;
+       wait_queue_head_t drain_wait;                   /* close processing */
+       struct tasklet_struct urb_task;                 /* rx processing */
+       spinlock_t throttle_lock;                       /* synchronize throtteling and read callback */
diff --git a/queue-2.6.33/xfs-check-for-more-work-before-sleeping-in-xfssyncd.patch b/queue-2.6.33/xfs-check-for-more-work-before-sleeping-in-xfssyncd.patch
new file mode 100644 (file)
index 0000000..39973ba
--- /dev/null
@@ -0,0 +1,49 @@
+From 20f6b2c785cf187445f126321638ab8ba7aa7494 Mon Sep 17 00:00:00 2001
+From: Dave Chinner <david@fromorbit.com>
+Date: Thu, 4 Mar 2010 01:46:23 +0000
+Subject: xfs: check for more work before sleeping in xfssyncd
+
+From: Dave Chinner <david@fromorbit.com>
+
+commit 20f6b2c785cf187445f126321638ab8ba7aa7494 upstream.
+
+xfssyncd processes a queue of work by detaching the queue and
+then iterating over all the work items. It then sleeps for a
+time period or until new work comes in. If new work is queued
+while xfssyncd is actively processing the detached work queue,
+it will not process that new work until after a sleep timeout
+or the next work event queued wakes it.
+
+Fix this by checking the work queue again before going to sleep.
+
+Signed-off-by: Dave Chinner <david@fromorbit.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Alex Elder <aelder@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/xfs/linux-2.6/xfs_sync.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/xfs/linux-2.6/xfs_sync.c
++++ b/fs/xfs/linux-2.6/xfs_sync.c
+@@ -613,7 +613,8 @@ xfssyncd(
+       set_freezable();
+       timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10);
+       for (;;) {
+-              timeleft = schedule_timeout_interruptible(timeleft);
++              if (list_empty(&mp->m_sync_list))
++                      timeleft = schedule_timeout_interruptible(timeleft);
+               /* swsusp */
+               try_to_freeze();
+               if (kthread_should_stop() && list_empty(&mp->m_sync_list))
+@@ -633,8 +634,7 @@ xfssyncd(
+                       list_add_tail(&mp->m_sync_work.w_list,
+                                       &mp->m_sync_list);
+               }
+-              list_for_each_entry_safe(work, n, &mp->m_sync_list, w_list)
+-                      list_move(&work->w_list, &tmp);
++              list_splice_init(&mp->m_sync_list, &tmp);
+               spin_unlock(&mp->m_sync_lock);
+               list_for_each_entry_safe(work, n, &tmp, w_list) {
diff --git a/queue-2.6.33/xfs-fix-locking-for-inode-cache-radix-tree-tag-updates.patch b/queue-2.6.33/xfs-fix-locking-for-inode-cache-radix-tree-tag-updates.patch
new file mode 100644 (file)
index 0000000..b984326
--- /dev/null
@@ -0,0 +1,82 @@
+From f1f724e4b523d444c5a598d74505aefa3d6844d2 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@infradead.org>
+Date: Mon, 1 Mar 2010 11:30:31 +0000
+Subject: xfs: fix locking for inode cache radix tree tag updates
+
+From: Christoph Hellwig <hch@infradead.org>
+
+commit f1f724e4b523d444c5a598d74505aefa3d6844d2 upstream.
+
+The radix-tree code requires it's users to serialize tag updates
+against other updates to the tree.  While XFS protects tag updates
+against each other it does not serialize them against updates of the
+tree contents, which can lead to tag corruption.  Fix the inode
+cache to always take pag_ici_lock in exclusive mode when updating
+radix tree tags.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reported-by: Patrick Schreurs <patrick@news-service.com>
+Tested-by: Patrick Schreurs <patrick@news-service.com>
+Signed-off-by: Alex Elder <aelder@sgi.com>
+Cc: Dave Chinner <david@fromorbit.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/xfs/linux-2.6/xfs_sync.c |    4 ++--
+ fs/xfs/xfs_iget.c           |   19 +++++++++++++------
+ 2 files changed, 15 insertions(+), 8 deletions(-)
+
+--- a/fs/xfs/linux-2.6/xfs_sync.c
++++ b/fs/xfs/linux-2.6/xfs_sync.c
+@@ -693,12 +693,12 @@ xfs_inode_set_reclaim_tag(
+       xfs_mount_t     *mp = ip->i_mount;
+       xfs_perag_t     *pag = xfs_get_perag(mp, ip->i_ino);
+-      read_lock(&pag->pag_ici_lock);
++      write_lock(&pag->pag_ici_lock);
+       spin_lock(&ip->i_flags_lock);
+       __xfs_inode_set_reclaim_tag(pag, ip);
+       __xfs_iflags_set(ip, XFS_IRECLAIMABLE);
+       spin_unlock(&ip->i_flags_lock);
+-      read_unlock(&pag->pag_ici_lock);
++      write_unlock(&pag->pag_ici_lock);
+       xfs_put_perag(mp, pag);
+ }
+--- a/fs/xfs/xfs_iget.c
++++ b/fs/xfs/xfs_iget.c
+@@ -190,13 +190,12 @@ xfs_iget_cache_hit(
+               trace_xfs_iget_reclaim(ip);
+               /*
+-               * We need to set XFS_INEW atomically with clearing the
+-               * reclaimable tag so that we do have an indicator of the
+-               * inode still being initialized.
++               * We need to set XFS_IRECLAIM to prevent xfs_reclaim_inode
++               * from stomping over us while we recycle the inode.  We can't
++               * clear the radix tree reclaimable tag yet as it requires
++               * pag_ici_lock to be held exclusive.
+                */
+-              ip->i_flags |= XFS_INEW;
+-              ip->i_flags &= ~XFS_IRECLAIMABLE;
+-              __xfs_inode_clear_reclaim_tag(mp, pag, ip);
++              ip->i_flags |= XFS_IRECLAIM;
+               spin_unlock(&ip->i_flags_lock);
+               read_unlock(&pag->pag_ici_lock);
+@@ -216,7 +215,15 @@ xfs_iget_cache_hit(
+                       trace_xfs_iget_reclaim(ip);
+                       goto out_error;
+               }
++
++              write_lock(&pag->pag_ici_lock);
++              spin_lock(&ip->i_flags_lock);
++              ip->i_flags &= ~(XFS_IRECLAIMABLE | XFS_IRECLAIM);
++              ip->i_flags |= XFS_INEW;
++              __xfs_inode_clear_reclaim_tag(mp, pag, ip);
+               inode->i_state = I_NEW;
++              spin_unlock(&ip->i_flags_lock);
++              write_unlock(&pag->pag_ici_lock);
+       } else {
+               /* If the VFS inode is being torn down, pause and try again. */
+               if (!igrab(inode)) {
diff --git a/queue-2.6.33/xfs-non-blocking-inode-locking-in-io-completion.patch b/queue-2.6.33/xfs-non-blocking-inode-locking-in-io-completion.patch
new file mode 100644 (file)
index 0000000..65961b0
--- /dev/null
@@ -0,0 +1,183 @@
+From 77d7a0c2eeb285c9069e15396703d0cb9690ac50 Mon Sep 17 00:00:00 2001
+From: Dave Chinner <david@fromorbit.com>
+Date: Wed, 17 Feb 2010 05:36:29 +0000
+Subject: xfs: Non-blocking inode locking in IO completion
+
+From: Dave Chinner <david@fromorbit.com>
+
+commit 77d7a0c2eeb285c9069e15396703d0cb9690ac50 upstream.
+
+The introduction of barriers to loop devices has created a new IO
+order completion dependency that XFS does not handle. The loop
+device implements barriers using fsync and so turns a log IO in the
+XFS filesystem on the loop device into a data IO in the backing
+filesystem. That is, the completion of log IOs in the loop
+filesystem are now dependent on completion of data IO in the backing
+filesystem.
+
+This can cause deadlocks when a flush daemon issues a log force with
+an inode locked because the IO completion of IO on the inode is
+blocked by the inode lock. This in turn prevents further data IO
+completion from occuring on all XFS filesystems on that CPU (due to
+the shared nature of the completion queues). This then prevents the
+log IO from completing because the log is waiting for data IO
+completion as well.
+
+The fix for this new completion order dependency issue is to make
+the IO completion inode locking non-blocking. If the inode lock
+can't be grabbed, simply requeue the IO completion back to the work
+queue so that it can be processed later. This prevents the
+completion queue from being blocked and allows data IO completion on
+other inodes to proceed, hence avoiding completion order dependent
+deadlocks.
+
+Signed-off-by: Dave Chinner <david@fromorbit.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Alex Elder <aelder@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/xfs/linux-2.6/xfs_aops.c |   93 ++++++++++++++++++++++++++------------------
+ 1 file changed, 56 insertions(+), 37 deletions(-)
+
+--- a/fs/xfs/linux-2.6/xfs_aops.c
++++ b/fs/xfs/linux-2.6/xfs_aops.c
+@@ -163,14 +163,17 @@ xfs_ioend_new_eof(
+ }
+ /*
+- * Update on-disk file size now that data has been written to disk.
+- * The current in-memory file size is i_size.  If a write is beyond
+- * eof i_new_size will be the intended file size until i_size is
+- * updated.  If this write does not extend all the way to the valid
+- * file size then restrict this update to the end of the write.
++ * Update on-disk file size now that data has been written to disk.  The
++ * current in-memory file size is i_size.  If a write is beyond eof i_new_size
++ * will be the intended file size until i_size is updated.  If this write does
++ * not extend all the way to the valid file size then restrict this update to
++ * the end of the write.
++ *
++ * This function does not block as blocking on the inode lock in IO completion
++ * can lead to IO completion order dependency deadlocks.. If it can't get the
++ * inode ilock it will return EAGAIN. Callers must handle this.
+  */
+-
+-STATIC void
++STATIC int
+ xfs_setfilesize(
+       xfs_ioend_t             *ioend)
+ {
+@@ -181,9 +184,11 @@ xfs_setfilesize(
+       ASSERT(ioend->io_type != IOMAP_READ);
+       if (unlikely(ioend->io_error))
+-              return;
++              return 0;
++
++      if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL))
++              return EAGAIN;
+-      xfs_ilock(ip, XFS_ILOCK_EXCL);
+       isize = xfs_ioend_new_eof(ioend);
+       if (isize) {
+               ip->i_d.di_size = isize;
+@@ -191,6 +196,28 @@ xfs_setfilesize(
+       }
+       xfs_iunlock(ip, XFS_ILOCK_EXCL);
++      return 0;
++}
++
++/*
++ * Schedule IO completion handling on a xfsdatad if this was
++ * the final hold on this ioend. If we are asked to wait,
++ * flush the workqueue.
++ */
++STATIC void
++xfs_finish_ioend(
++      xfs_ioend_t     *ioend,
++      int             wait)
++{
++      if (atomic_dec_and_test(&ioend->io_remaining)) {
++              struct workqueue_struct *wq;
++
++              wq = (ioend->io_type == IOMAP_UNWRITTEN) ?
++                      xfsconvertd_workqueue : xfsdatad_workqueue;
++              queue_work(wq, &ioend->io_work);
++              if (wait)
++                      flush_workqueue(wq);
++      }
+ }
+ /*
+@@ -198,11 +225,11 @@ xfs_setfilesize(
+  */
+ STATIC void
+ xfs_end_io(
+-      struct work_struct      *work)
++      struct work_struct *work)
+ {
+-      xfs_ioend_t             *ioend =
+-              container_of(work, xfs_ioend_t, io_work);
+-      struct xfs_inode        *ip = XFS_I(ioend->io_inode);
++      xfs_ioend_t     *ioend = container_of(work, xfs_ioend_t, io_work);
++      struct xfs_inode *ip = XFS_I(ioend->io_inode);
++      int             error;
+       /*
+        * For unwritten extents we need to issue transactions to convert a
+@@ -210,7 +237,6 @@ xfs_end_io(
+        */
+       if (ioend->io_type == IOMAP_UNWRITTEN &&
+           likely(!ioend->io_error && !XFS_FORCED_SHUTDOWN(ip->i_mount))) {
+-              int error;
+               error = xfs_iomap_write_unwritten(ip, ioend->io_offset,
+                                                ioend->io_size);
+@@ -222,30 +248,23 @@ xfs_end_io(
+        * We might have to update the on-disk file size after extending
+        * writes.
+        */
+-      if (ioend->io_type != IOMAP_READ)
+-              xfs_setfilesize(ioend);
+-      xfs_destroy_ioend(ioend);
+-}
+-
+-/*
+- * Schedule IO completion handling on a xfsdatad if this was
+- * the final hold on this ioend. If we are asked to wait,
+- * flush the workqueue.
+- */
+-STATIC void
+-xfs_finish_ioend(
+-      xfs_ioend_t     *ioend,
+-      int             wait)
+-{
+-      if (atomic_dec_and_test(&ioend->io_remaining)) {
+-              struct workqueue_struct *wq;
+-
+-              wq = (ioend->io_type == IOMAP_UNWRITTEN) ?
+-                      xfsconvertd_workqueue : xfsdatad_workqueue;
+-              queue_work(wq, &ioend->io_work);
+-              if (wait)
+-                      flush_workqueue(wq);
++      if (ioend->io_type != IOMAP_READ) {
++              error = xfs_setfilesize(ioend);
++              ASSERT(!error || error == EAGAIN);
+       }
++
++      /*
++       * If we didn't complete processing of the ioend, requeue it to the
++       * tail of the workqueue for another attempt later. Otherwise destroy
++       * it.
++       */
++      if (error == EAGAIN) {
++              atomic_inc(&ioend->io_remaining);
++              xfs_finish_ioend(ioend, 0);
++              /* ensure we don't spin on blocked ioends */
++              delay(1);
++      } else
++              xfs_destroy_ioend(ioend);
+ }
+ /*