]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 18 May 2012 19:50:19 +0000 (12:50 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 18 May 2012 19:50:19 +0000 (12:50 -0700)
added patches:
cifs-fix-revalidation-test-in-cifs_llseek.patch
compat-fix-rt-signal-mask-corruption-via-sigprocmask.patch
ext4-avoid-deadlock-on-sync-mounted-fs-w-o-journal.patch
memcg-free-spare-array-to-avoid-memory-leak.patch

queue-3.3/cifs-fix-revalidation-test-in-cifs_llseek.patch [new file with mode: 0644]
queue-3.3/compat-fix-rt-signal-mask-corruption-via-sigprocmask.patch [new file with mode: 0644]
queue-3.3/ext4-avoid-deadlock-on-sync-mounted-fs-w-o-journal.patch [new file with mode: 0644]
queue-3.3/memcg-free-spare-array-to-avoid-memory-leak.patch [new file with mode: 0644]
queue-3.3/series

diff --git a/queue-3.3/cifs-fix-revalidation-test-in-cifs_llseek.patch b/queue-3.3/cifs-fix-revalidation-test-in-cifs_llseek.patch
new file mode 100644 (file)
index 0000000..dfd532a
--- /dev/null
@@ -0,0 +1,33 @@
+From 48a5730e5b71201e226ff06e245bf308feba5f10 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Mon, 30 Apr 2012 17:36:21 +0300
+Subject: cifs: fix revalidation test in cifs_llseek()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 48a5730e5b71201e226ff06e245bf308feba5f10 upstream.
+
+This test is always true so it means we revalidate the length every
+time, which generates more network traffic.  When it is SEEK_SET or
+SEEK_CUR, then we don't need to revalidate.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsfs.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -703,7 +703,7 @@ static loff_t cifs_llseek(struct file *f
+        * origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
+        * the cached file length
+        */
+-      if (origin != SEEK_SET || origin != SEEK_CUR) {
++      if (origin != SEEK_SET && origin != SEEK_CUR) {
+               int rc;
+               struct inode *inode = file->f_path.dentry->d_inode;
diff --git a/queue-3.3/compat-fix-rt-signal-mask-corruption-via-sigprocmask.patch b/queue-3.3/compat-fix-rt-signal-mask-corruption-via-sigprocmask.patch
new file mode 100644 (file)
index 0000000..e171ec2
--- /dev/null
@@ -0,0 +1,105 @@
+From b7dafa0ef3145c31d7753be0a08b3cbda51f0209 Mon Sep 17 00:00:00 2001
+From: Jan Kiszka <jan.kiszka@siemens.com>
+Date: Thu, 10 May 2012 10:04:36 -0300
+Subject: compat: Fix RT signal mask corruption via sigprocmask
+
+From: Jan Kiszka <jan.kiszka@siemens.com>
+
+commit b7dafa0ef3145c31d7753be0a08b3cbda51f0209 upstream.
+
+compat_sys_sigprocmask reads a smaller signal mask from userspace than
+sigprogmask accepts for setting.  So the high word of blocked.sig[0]
+will be cleared, releasing any potentially blocked RT signal.
+
+This was discovered via userspace code that relies on get/setcontext.
+glibc's i386 versions of those functions use sigprogmask instead of
+rt_sigprogmask to save/restore signal mask and caused RT signal
+unblocking this way.
+
+As suggested by Linus, this replaces the sys_sigprocmask based compat
+version with one that open-codes the required logic, including the merge
+of the existing blocked set with the new one provided on SIG_SETMASK.
+
+Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/compat.c |   65 ++++++++++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 47 insertions(+), 18 deletions(-)
+
+--- a/kernel/compat.c
++++ b/kernel/compat.c
+@@ -320,25 +320,54 @@ asmlinkage long compat_sys_sigpending(co
+ #ifdef __ARCH_WANT_SYS_SIGPROCMASK
+-asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set,
+-              compat_old_sigset_t __user *oset)
++/*
++ * sys_sigprocmask SIG_SETMASK sets the first (compat) word of the
++ * blocked set of signals to the supplied signal set
++ */
++static inline void compat_sig_setmask(sigset_t *blocked, compat_sigset_word set)
+ {
+-      old_sigset_t s;
+-      long ret;
+-      mm_segment_t old_fs;
+-
+-      if (set && get_user(s, set))
+-              return -EFAULT;
+-      old_fs = get_fs();
+-      set_fs(KERNEL_DS);
+-      ret = sys_sigprocmask(how,
+-                            set ? (old_sigset_t __user *) &s : NULL,
+-                            oset ? (old_sigset_t __user *) &s : NULL);
+-      set_fs(old_fs);
+-      if (ret == 0)
+-              if (oset)
+-                      ret = put_user(s, oset);
+-      return ret;
++      memcpy(blocked->sig, &set, sizeof(set));
++}
++
++asmlinkage long compat_sys_sigprocmask(int how,
++                                     compat_old_sigset_t __user *nset,
++                                     compat_old_sigset_t __user *oset)
++{
++      old_sigset_t old_set, new_set;
++      sigset_t new_blocked;
++
++      old_set = current->blocked.sig[0];
++
++      if (nset) {
++              if (get_user(new_set, nset))
++                      return -EFAULT;
++              new_set &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP));
++
++              new_blocked = current->blocked;
++
++              switch (how) {
++              case SIG_BLOCK:
++                      sigaddsetmask(&new_blocked, new_set);
++                      break;
++              case SIG_UNBLOCK:
++                      sigdelsetmask(&new_blocked, new_set);
++                      break;
++              case SIG_SETMASK:
++                      compat_sig_setmask(&new_blocked, new_set);
++                      break;
++              default:
++                      return -EINVAL;
++              }
++
++              set_current_blocked(&new_blocked);
++      }
++
++      if (oset) {
++              if (put_user(old_set, oset))
++                      return -EFAULT;
++      }
++
++      return 0;
+ }
+ #endif
diff --git a/queue-3.3/ext4-avoid-deadlock-on-sync-mounted-fs-w-o-journal.patch b/queue-3.3/ext4-avoid-deadlock-on-sync-mounted-fs-w-o-journal.patch
new file mode 100644 (file)
index 0000000..008c5e6
--- /dev/null
@@ -0,0 +1,62 @@
+From c1bb05a657fb3d8c6179a4ef7980261fae4521d7 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@redhat.com>
+Date: Mon, 20 Feb 2012 23:06:18 -0500
+Subject: ext4: avoid deadlock on sync-mounted FS w/o journal
+
+From: Eric Sandeen <sandeen@redhat.com>
+
+commit c1bb05a657fb3d8c6179a4ef7980261fae4521d7 upstream.
+
+Processes hang forever on a sync-mounted ext2 file system that
+is mounted with the ext4 module (default in Fedora 16).
+
+I can reproduce this reliably by mounting an ext2 partition with
+"-o sync" and opening a new file an that partition with vim. vim
+will hang in "D" state forever.  The same happens on ext4 without
+a journal.
+
+I am attaching a small patch here that solves this issue for me.
+In the sync mounted case without a journal,
+ext4_handle_dirty_metadata() may call sync_dirty_buffer(), which
+can't be called with buffer lock held.
+
+Also move mb_cache_entry_release inside lock to avoid race
+fixed previously by 8a2bfdcb ext[34]: EA block reference count racing fix
+Note too that ext2 fixed this same problem in 2006 with
+b2f49033 [PATCH] fix deadlock in ext2
+
+Signed-off-by: Martin.Wilck@ts.fujitsu.com
+[sandeen@redhat.com: move mb_cache_entry_release before unlock, edit commit msg]
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/xattr.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -487,18 +487,19 @@ ext4_xattr_release_block(handle_t *handl
+               ext4_free_blocks(handle, inode, bh, 0, 1,
+                                EXT4_FREE_BLOCKS_METADATA |
+                                EXT4_FREE_BLOCKS_FORGET);
++              unlock_buffer(bh);
+       } else {
+               le32_add_cpu(&BHDR(bh)->h_refcount, -1);
++              if (ce)
++                      mb_cache_entry_release(ce);
++              unlock_buffer(bh);
+               error = ext4_handle_dirty_metadata(handle, inode, bh);
+               if (IS_SYNC(inode))
+                       ext4_handle_sync(handle);
+               dquot_free_block(inode, 1);
+               ea_bdebug(bh, "refcount now=%d; releasing",
+                         le32_to_cpu(BHDR(bh)->h_refcount));
+-              if (ce)
+-                      mb_cache_entry_release(ce);
+       }
+-      unlock_buffer(bh);
+ out:
+       ext4_std_error(inode->i_sb, error);
+       return;
diff --git a/queue-3.3/memcg-free-spare-array-to-avoid-memory-leak.patch b/queue-3.3/memcg-free-spare-array-to-avoid-memory-leak.patch
new file mode 100644 (file)
index 0000000..6f7ac55
--- /dev/null
@@ -0,0 +1,38 @@
+From 8c7577637ca31385e92769a77e2ab5b428e8b99c Mon Sep 17 00:00:00 2001
+From: Sha Zhengju <handai.szj@taobao.com>
+Date: Thu, 10 May 2012 13:01:45 -0700
+Subject: memcg: free spare array to avoid memory leak
+
+From: Sha Zhengju <handai.szj@taobao.com>
+
+commit 8c7577637ca31385e92769a77e2ab5b428e8b99c upstream.
+
+When the last event is unregistered, there is no need to keep the spare
+array anymore.  So free it to avoid memory leak.
+
+Signed-off-by: Sha Zhengju <handai.szj@taobao.com>
+Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+Reviewed-by: Kirill A. Shutemov <kirill@shutemov.name>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/memcontrol.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -4480,6 +4480,12 @@ static void mem_cgroup_usage_unregister_
+ swap_buffers:
+       /* Swap primary and spare array */
+       thresholds->spare = thresholds->primary;
++      /* If all events are unregistered, free the spare array */
++      if (!new) {
++              kfree(thresholds->spare);
++              thresholds->spare = NULL;
++      }
++
+       rcu_assign_pointer(thresholds->primary, new);
+       /* To be sure that nobody uses thresholds */
index 6a87365fae60d162bce276fa3b9545c39b82e858..800dcd6f8f1e365a8d0fe2d6d5fff122099d0bf6 100644 (file)
@@ -32,3 +32,7 @@ e1000-prevent-reset-task-killing-itself.patch
 md-add-del_timer_sync-to-mddev_suspend-fix-nasty-panic.patch
 tcp-do_tcp_sendpages-must-try-to-push-data-out-on-oom-conditions.patch
 init-don-t-try-mounting-device-as-nfs-root-unless-type-fully-matches.patch
+ext4-avoid-deadlock-on-sync-mounted-fs-w-o-journal.patch
+memcg-free-spare-array-to-avoid-memory-leak.patch
+cifs-fix-revalidation-test-in-cifs_llseek.patch
+compat-fix-rt-signal-mask-corruption-via-sigprocmask.patch