]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-regressions.patch
- regressions introduced by the new stable kernel
[packages/kernel.git] / kernel-regressions.patch
1 From jlayton@redhat.com  Thu Dec 11 08:49:55 2008
2 From: Jeff Layton <jlayton@redhat.com>
3 Date: Wed, 10 Dec 2008 06:44:29 -0500
4 Subject: cifs: fix a regression in cifs umount codepath
5 To: greg@kroah.com, stable@kernel.org
6 Cc: smfrench@gmail.com, shirishp@us.ibm.com, sjayaraman@suse.de
7 Message-ID: <1228909469-438-1-git-send-email-jlayton@redhat.com>
8
9 From: Jeff Layton <jlayton@redhat.com>
10
11 backport of 469ee614aaa367d9cde01cbdd2027212f56c6cc6 upstream.
12
13 Several cifs patches were added to 2.6.27.8 to fix some races in the
14 mount/umount codepath. When this was done, a couple of prerequisite
15 patches were missed causing a minor regression.
16
17 When the last cifs mount to a server goes away, the kthread that manages
18 the socket is supposed to come down. The patches that went into 2.6.27.8
19 removed the kthread_stop calls that used to take down these threads, but
20 left the thread function expecting them. This made the thread stay up
21 even after the last mount was gone.
22
23 This patch should fix up this regression and also prevent a possible
24 race where a dead task could be signalled.
25
26 Signed-off-by: Jeff Layton <jlayton@redhat.com>
27 Cc: Suresh Jayaraman <sjayaraman@suse.de>
28 Acked-by: Steve French <smfrench@gmail.com>
29 Signed-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:
152 From 218d11a8b071b23b76c484fd5f72a4fe3306801e Mon Sep 17 00:00:00 2001
153 From: Jonathan Corbet <corbet@lwn.net>
154 Date: Fri, 5 Dec 2008 16:12:48 -0700
155 Subject: Fix a race condition in FASYNC handling
156
157 From: Jonathan Corbet <corbet@lwn.net>
158
159 commit 218d11a8b071b23b76c484fd5f72a4fe3306801e upstream.
160
161 Changeset a238b790d5f99c7832f9b73ac8847025815b85f7 (Call fasync()
162 functions without the BKL) introduced a race which could leave
163 file->f_flags in a state inconsistent with what the underlying
164 driver/filesystem believes.  Revert that change, and also fix the same
165 races in ioctl_fioasync() and ioctl_fionbio().
166
167 This is a minimal, short-term fix; the real fix will not involve the
168 BKL.
169
170 Reported-by: Oleg Nesterov <oleg@redhat.com>
171 Cc: Andi Kleen <ak@linux.intel.com>
172 Cc: Al Viro <viro@zeniv.linux.org.uk>
173 Signed-off-by: Jonathan Corbet <corbet@lwn.net>
174 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
175 Signed-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:
246 From 49c50342c728344b79c8f9e8293637fe80ef5ad5 Mon Sep 17 00:00:00 2001
247 From: Matt Mackall <mpm@selenic.com>
248 Date: Tue, 9 Dec 2008 13:14:21 -0800
249 Subject: pagemap: fix 32-bit pagemap regression
250
251 From: Matt Mackall <mpm@selenic.com>
252
253 commit 49c50342c728344b79c8f9e8293637fe80ef5ad5 upstream.
254
255 The large pages fix from bcf8039ed45 broke 32-bit pagemap by pulling the
256 pagemap entry code out into a function with the wrong return type.
257 Pagemap entries are 64 bits on all systems and unsigned long is only 32
258 bits on 32-bit systems.
259
260 Signed-off-by: Matt Mackall <mpm@selenic.com>
261 Reported-by: Doug Graham <dgraham@nortel.com>
262 Cc: Alexey Dobriyan <adobriyan@gmail.com>
263 Cc: Dave Hansen <dave@linux.vnet.ibm.com>
264 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
265 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
266 Signed-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;
286 rom ae060e0b7bc071bd73dd5319b93c3344d9e10212 Mon Sep 17 00:00:00 2001
287 From: Manfred Spraul <manfred@colorfullife.com>
288 To: torvalds@linux-foundation.org
289 Cc: linux-kernel@vger.kernel.org
290 Cc: cebbert@redhat.com
291 Cc: airlied@gmail.com
292 Cc: akpm@linux-foundation.org
293 Bcc: manfred@colorfullife.com
294 Date: Wed, 10 Dec 2008 18:17:06 +0100
295 Subject: [PATCH] lib/idr.c: Fix bug introduced by RCU fix
296
297 The last patch to lib/idr.c caused a bug if idr_get_new_above() was
298 called on an empty idr:
299 Usually, nodes stay on the same layer. New layers are added to the top
300 of the tree.
301 The exception is idr_get_new_above() on an empty tree: In this case,
302 the new root node is first added on layer 0, then moved upwards.
303 p->layer was not updated.
304
305 As usual: You shall never rely on the source code comments, they
306 will only mislead you.
307
308 Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
309 ---
310  lib/idr.c |    8 +++++++-
311  1 files changed, 7 insertions(+), 1 deletions(-)
312
313 diff --git a/lib/idr.c b/lib/idr.c
314 index 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 -- 
334 1.5.6.5
335
This page took 0.08964 seconds and 4 git commands to generate.