]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-regressions.patch
- regressions introduced by the new stable kernel
[packages/kernel.git] / kernel-regressions.patch
CommitLineData
3b04b1f3
JR
1From jlayton@redhat.com Thu Dec 11 08:49:55 2008
2From: Jeff Layton <jlayton@redhat.com>
3Date: Wed, 10 Dec 2008 06:44:29 -0500
4Subject: cifs: fix a regression in cifs umount codepath
5To: greg@kroah.com, stable@kernel.org
6Cc: smfrench@gmail.com, shirishp@us.ibm.com, sjayaraman@suse.de
7Message-ID: <1228909469-438-1-git-send-email-jlayton@redhat.com>
8
9From: Jeff Layton <jlayton@redhat.com>
10
11backport of 469ee614aaa367d9cde01cbdd2027212f56c6cc6 upstream.
12
13Several cifs patches were added to 2.6.27.8 to fix some races in the
14mount/umount codepath. When this was done, a couple of prerequisite
15patches were missed causing a minor regression.
16
17When the last cifs mount to a server goes away, the kthread that manages
18the socket is supposed to come down. The patches that went into 2.6.27.8
19removed the kthread_stop calls that used to take down these threads, but
20left the thread function expecting them. This made the thread stay up
21even after the last mount was gone.
22
23This patch should fix up this regression and also prevent a possible
24race where a dead task could be signalled.
25
26Signed-off-by: Jeff Layton <jlayton@redhat.com>
27Cc: Suresh Jayaraman <sjayaraman@suse.de>
28Acked-by: Steve French <smfrench@gmail.com>
29Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
30
31---
32 fs/cifs/connect.c | 36 +++++++++++++++++++++---------------
33 1 file changed, 21 insertions(+), 15 deletions(-)
34
35--- a/fs/cifs/connect.c
36+++ b/fs/cifs/connect.c
37@@ -128,7 +128,7 @@ cifs_reconnect(struct TCP_Server_Info *s
38 struct mid_q_entry *mid_entry;
39
40 spin_lock(&GlobalMid_Lock);
41- if (kthread_should_stop()) {
42+ if (server->tcpStatus == CifsExiting) {
43 /* the demux thread will exit normally
44 next time through the loop */
45 spin_unlock(&GlobalMid_Lock);
46@@ -182,7 +182,8 @@ cifs_reconnect(struct TCP_Server_Info *s
47 spin_unlock(&GlobalMid_Lock);
48 up(&server->tcpSem);
49
50- while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
51+ while ((server->tcpStatus != CifsExiting) &&
52+ (server->tcpStatus != CifsGood)) {
53 try_to_freeze();
54 if (server->addr.sockAddr6.sin6_family == AF_INET6) {
55 rc = ipv6_connect(&server->addr.sockAddr6,
56@@ -200,7 +201,7 @@ cifs_reconnect(struct TCP_Server_Info *s
57 } else {
58 atomic_inc(&tcpSesReconnectCount);
59 spin_lock(&GlobalMid_Lock);
60- if (!kthread_should_stop())
61+ if (server->tcpStatus != CifsExiting)
62 server->tcpStatus = CifsGood;
63 server->sequence_number = 0;
64 spin_unlock(&GlobalMid_Lock);
65@@ -355,7 +356,7 @@ cifs_demultiplex_thread(struct TCP_Serve
66 GFP_KERNEL);
67
68 set_freezable();
69- while (!kthread_should_stop()) {
70+ while (server->tcpStatus != CifsExiting) {
71 if (try_to_freeze())
72 continue;
73 if (bigbuf == NULL) {
74@@ -396,7 +397,7 @@ incomplete_rcv:
75 kernel_recvmsg(csocket, &smb_msg,
76 &iov, 1, pdu_length, 0 /* BB other flags? */);
77
78- if (kthread_should_stop()) {
79+ if (server->tcpStatus == CifsExiting) {
80 break;
81 } else if (server->tcpStatus == CifsNeedReconnect) {
82 cFYI(1, ("Reconnect after server stopped responding"));
83@@ -527,7 +528,7 @@ incomplete_rcv:
84 total_read += length) {
85 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
86 pdu_length - total_read, 0);
87- if (kthread_should_stop() ||
88+ if ((server->tcpStatus == CifsExiting) ||
89 (length == -EINTR)) {
90 /* then will exit */
91 reconnect = 2;
92@@ -661,14 +662,6 @@ multi_t2_fnd:
93 spin_unlock(&GlobalMid_Lock);
94 wake_up_all(&server->response_q);
95
96- /* don't exit until kthread_stop is called */
97- set_current_state(TASK_UNINTERRUPTIBLE);
98- while (!kthread_should_stop()) {
99- schedule();
100- set_current_state(TASK_UNINTERRUPTIBLE);
101- }
102- set_current_state(TASK_RUNNING);
103-
104 /* check if we have blocked requests that need to free */
105 /* Note that cifs_max_pending is normally 50, but
106 can be set at module install time to as little as two */
107@@ -764,6 +757,7 @@ multi_t2_fnd:
108 read_unlock(&cifs_tcp_ses_lock);
109
110 kfree(server->hostname);
111+ task_to_wake = xchg(&server->tsk, NULL);
112 kfree(server);
113
114 length = atomic_dec_return(&tcpSesAllocCount);
115@@ -771,6 +765,16 @@ multi_t2_fnd:
116 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
117 GFP_KERNEL);
118
119+ /* if server->tsk was NULL then wait for a signal before exiting */
120+ if (!task_to_wake) {
121+ set_current_state(TASK_INTERRUPTIBLE);
122+ while (!signal_pending(current)) {
123+ schedule();
124+ set_current_state(TASK_INTERRUPTIBLE);
125+ }
126+ set_current_state(TASK_RUNNING);
127+ }
128+
129 return 0;
130 }
131
132@@ -2310,7 +2314,7 @@ cifs_mount(struct super_block *sb, struc
133 /* on error free sesinfo and tcon struct if needed */
134 mount_fail_check:
135 if (rc) {
136- /* If find_unc succeeded then rc == 0 so we can not end */
137+ /* If find_unc succeeded then rc == 0 so we can not end */
138 /* up accidently freeing someone elses tcon struct */
139 if (tcon)
140 cifs_put_tcon(tcon);
141@@ -3715,8 +3719,10 @@ int cifs_setup_session(unsigned int xid,
142 cERROR(1, ("Send error in SessSetup = %d", rc));
143 } else {
144 cFYI(1, ("CIFS Session Established successfully"));
145+ spin_lock(&GlobalMid_Lock);
146 pSesInfo->status = CifsGood;
147 pSesInfo->need_reconnect = false;
148+ spin_unlock(&GlobalMid_Lock);
149 }
150
151 ss_err_exit:
152From 218d11a8b071b23b76c484fd5f72a4fe3306801e Mon Sep 17 00:00:00 2001
153From: Jonathan Corbet <corbet@lwn.net>
154Date: Fri, 5 Dec 2008 16:12:48 -0700
155Subject: Fix a race condition in FASYNC handling
156
157From: Jonathan Corbet <corbet@lwn.net>
158
159commit 218d11a8b071b23b76c484fd5f72a4fe3306801e upstream.
160
161Changeset a238b790d5f99c7832f9b73ac8847025815b85f7 (Call fasync()
162functions without the BKL) introduced a race which could leave
163file->f_flags in a state inconsistent with what the underlying
164driver/filesystem believes. Revert that change, and also fix the same
165races in ioctl_fioasync() and ioctl_fionbio().
166
167This is a minimal, short-term fix; the real fix will not involve the
168BKL.
169
170Reported-by: Oleg Nesterov <oleg@redhat.com>
171Cc: Andi Kleen <ak@linux.intel.com>
172Cc: Al Viro <viro@zeniv.linux.org.uk>
173Signed-off-by: Jonathan Corbet <corbet@lwn.net>
174Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
175Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
176
177---
178 fs/fcntl.c | 7 +++++++
179 fs/ioctl.c | 12 ++++++++----
180 2 files changed, 15 insertions(+), 4 deletions(-)
181
182--- a/fs/fcntl.c
183+++ b/fs/fcntl.c
184@@ -19,6 +19,7 @@
185 #include <linux/signal.h>
186 #include <linux/rcupdate.h>
187 #include <linux/pid_namespace.h>
188+#include <linux/smp_lock.h>
189
190 #include <asm/poll.h>
191 #include <asm/siginfo.h>
192@@ -175,6 +176,11 @@ static int setfl(int fd, struct file * f
193 if (error)
194 return error;
195
196+ /*
197+ * We still need a lock here for now to keep multiple FASYNC calls
198+ * from racing with each other.
199+ */
200+ lock_kernel();
201 if ((arg ^ filp->f_flags) & FASYNC) {
202 if (filp->f_op && filp->f_op->fasync) {
203 error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
204@@ -185,6 +191,7 @@ static int setfl(int fd, struct file * f
205
206 filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
207 out:
208+ unlock_kernel();
209 return error;
210 }
211
212--- a/fs/ioctl.c
213+++ b/fs/ioctl.c
214@@ -123,11 +123,9 @@ static int ioctl_fioasync(unsigned int f
215
216 /* Did FASYNC state change ? */
217 if ((flag ^ filp->f_flags) & FASYNC) {
218- if (filp->f_op && filp->f_op->fasync) {
219- lock_kernel();
220+ if (filp->f_op && filp->f_op->fasync)
221 error = filp->f_op->fasync(fd, filp, on);
222- unlock_kernel();
223- } else
224+ else
225 error = -ENOTTY;
226 }
227 if (error)
228@@ -163,11 +161,17 @@ int do_vfs_ioctl(struct file *filp, unsi
229 break;
230
231 case FIONBIO:
232+ /* BKL needed to avoid races tweaking f_flags */
233+ lock_kernel();
234 error = ioctl_fionbio(filp, argp);
235+ unlock_kernel();
236 break;
237
238 case FIOASYNC:
239+ /* BKL needed to avoid races tweaking f_flags */
240+ lock_kernel();
241 error = ioctl_fioasync(fd, filp, argp);
242+ unlock_kernel();
243 break;
244
245 case FIOQSIZE:
246From 49c50342c728344b79c8f9e8293637fe80ef5ad5 Mon Sep 17 00:00:00 2001
247From: Matt Mackall <mpm@selenic.com>
248Date: Tue, 9 Dec 2008 13:14:21 -0800
249Subject: pagemap: fix 32-bit pagemap regression
250
251From: Matt Mackall <mpm@selenic.com>
252
253commit 49c50342c728344b79c8f9e8293637fe80ef5ad5 upstream.
254
255The large pages fix from bcf8039ed45 broke 32-bit pagemap by pulling the
256pagemap entry code out into a function with the wrong return type.
257Pagemap entries are 64 bits on all systems and unsigned long is only 32
258bits on 32-bit systems.
259
260Signed-off-by: Matt Mackall <mpm@selenic.com>
261Reported-by: Doug Graham <dgraham@nortel.com>
262Cc: Alexey Dobriyan <adobriyan@gmail.com>
263Cc: Dave Hansen <dave@linux.vnet.ibm.com>
264Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
265Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
266Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
267
268---
269 fs/proc/task_mmu.c | 4 ++--
270 1 file changed, 2 insertions(+), 2 deletions(-)
271
272--- a/fs/proc/task_mmu.c
273+++ b/fs/proc/task_mmu.c
274@@ -563,9 +563,9 @@ static u64 swap_pte_to_pagemap_entry(pte
275 return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT);
276 }
277
278-static unsigned long pte_to_pagemap_entry(pte_t pte)
279+static u64 pte_to_pagemap_entry(pte_t pte)
280 {
281- unsigned long pme = 0;
282+ u64 pme = 0;
283 if (is_swap_pte(pte))
284 pme = PM_PFRAME(swap_pte_to_pagemap_entry(pte))
285 | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP;
286rom ae060e0b7bc071bd73dd5319b93c3344d9e10212 Mon Sep 17 00:00:00 2001
287From: Manfred Spraul <manfred@colorfullife.com>
288To: torvalds@linux-foundation.org
289Cc: linux-kernel@vger.kernel.org
290Cc: cebbert@redhat.com
291Cc: airlied@gmail.com
292Cc: akpm@linux-foundation.org
293Bcc: manfred@colorfullife.com
294Date: Wed, 10 Dec 2008 18:17:06 +0100
295Subject: [PATCH] lib/idr.c: Fix bug introduced by RCU fix
296
297The last patch to lib/idr.c caused a bug if idr_get_new_above() was
298called on an empty idr:
299Usually, nodes stay on the same layer. New layers are added to the top
300of the tree.
301The exception is idr_get_new_above() on an empty tree: In this case,
302the new root node is first added on layer 0, then moved upwards.
303p->layer was not updated.
304
305As usual: You shall never rely on the source code comments, they
306will only mislead you.
307
308Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
309---
310 lib/idr.c | 8 +++++++-
311 1 files changed, 7 insertions(+), 1 deletions(-)
312
313diff --git a/lib/idr.c b/lib/idr.c
314index 7a785a0..1c4f928 100644
315--- a/lib/idr.c
316+++ b/lib/idr.c
317@@ -220,8 +220,14 @@ build_up:
318 */
319 while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) {
320 layers++;
321- if (!p->count)
322+ if (!p->count) {
323+ /* special case: if the tree is currently empty,
324+ * then we grow the tree by moving the top node
325+ * upwards.
326+ */
327+ p->layer++;
328 continue;
329+ }
330 if (!(new = get_from_free_list(idp))) {
331 /*
332 * The allocation failed. If we built part of
333--
3341.5.6.5
335
This page took 0.081948 seconds and 4 git commands to generate.