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>
9 From: Jeff Layton <jlayton@redhat.com>
11 backport of 469ee614aaa367d9cde01cbdd2027212f56c6cc6 upstream.
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.
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.
23 This patch should fix up this regression and also prevent a possible
24 race where a dead task could be signalled.
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>
32 fs/cifs/connect.c | 36 +++++++++++++++++++++---------------
33 1 file changed, 21 insertions(+), 15 deletions(-)
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;
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);
50 - while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
51 + while ((server->tcpStatus != CifsExiting) &&
52 + (server->tcpStatus != CifsGood)) {
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
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
69 - while (!kthread_should_stop()) {
70 + while (server->tcpStatus != CifsExiting) {
74 @@ -396,7 +397,7 @@ incomplete_rcv:
75 kernel_recvmsg(csocket, &smb_msg,
76 &iov, 1, pdu_length, 0 /* BB other flags? */);
78 - if (kthread_should_stop()) {
79 + if (server->tcpStatus == CifsExiting) {
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) ||
92 @@ -661,14 +662,6 @@ multi_t2_fnd:
93 spin_unlock(&GlobalMid_Lock);
94 wake_up_all(&server->response_q);
96 - /* don't exit until kthread_stop is called */
97 - set_current_state(TASK_UNINTERRUPTIBLE);
98 - while (!kthread_should_stop()) {
100 - set_current_state(TASK_UNINTERRUPTIBLE);
102 - set_current_state(TASK_RUNNING);
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);
110 kfree(server->hostname);
111 + task_to_wake = xchg(&server->tsk, NULL);
114 length = atomic_dec_return(&tcpSesAllocCount);
115 @@ -771,6 +765,16 @@ multi_t2_fnd:
116 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
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)) {
124 + set_current_state(TASK_INTERRUPTIBLE);
126 + set_current_state(TASK_RUNNING);
132 @@ -2310,7 +2314,7 @@ cifs_mount(struct super_block *sb, struc
133 /* on error free sesinfo and tcon struct if needed */
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 */
141 @@ -3715,8 +3719,10 @@ int cifs_setup_session(unsigned int xid,
142 cERROR(1, ("Send error in SessSetup = %d", rc));
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);
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
157 From: Jonathan Corbet <corbet@lwn.net>
159 commit 218d11a8b071b23b76c484fd5f72a4fe3306801e upstream.
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().
167 This is a minimal, short-term fix; the real fix will not involve the
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>
178 fs/fcntl.c | 7 +++++++
179 fs/ioctl.c | 12 ++++++++----
180 2 files changed, 15 insertions(+), 4 deletions(-)
185 #include <linux/signal.h>
186 #include <linux/rcupdate.h>
187 #include <linux/pid_namespace.h>
188 +#include <linux/smp_lock.h>
190 #include <asm/poll.h>
191 #include <asm/siginfo.h>
192 @@ -175,6 +176,11 @@ static int setfl(int fd, struct file * f
197 + * We still need a lock here for now to keep multiple FASYNC calls
198 + * from racing with each other.
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
206 filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
214 @@ -123,11 +123,9 @@ static int ioctl_fioasync(unsigned int f
216 /* Did FASYNC state change ? */
217 if ((flag ^ filp->f_flags) & FASYNC) {
218 - if (filp->f_op && filp->f_op->fasync) {
220 + if (filp->f_op && filp->f_op->fasync)
221 error = filp->f_op->fasync(fd, filp, on);
228 @@ -163,11 +161,17 @@ int do_vfs_ioctl(struct file *filp, unsi
232 + /* BKL needed to avoid races tweaking f_flags */
234 error = ioctl_fionbio(filp, argp);
239 + /* BKL needed to avoid races tweaking f_flags */
241 error = ioctl_fioasync(fd, filp, argp);
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
251 From: Matt Mackall <mpm@selenic.com>
253 commit 49c50342c728344b79c8f9e8293637fe80ef5ad5 upstream.
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.
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>
269 fs/proc/task_mmu.c | 4 ++--
270 1 file changed, 2 insertions(+), 2 deletions(-)
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);
278 -static unsigned long pte_to_pagemap_entry(pte_t pte)
279 +static u64 pte_to_pagemap_entry(pte_t pte)
281 - unsigned long 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
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
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.
305 As usual: You shall never rely on the source code comments, they
306 will only mislead you.
308 Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
310 lib/idr.c | 8 +++++++-
311 1 files changed, 7 insertions(+), 1 deletions(-)
313 diff --git a/lib/idr.c b/lib/idr.c
314 index 7a785a0..1c4f928 100644
317 @@ -220,8 +220,14 @@ build_up:
319 while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) {
323 + /* special case: if the tree is currently empty,
324 + * then we grow the tree by moving the top node
330 if (!(new = get_from_free_list(idp))) {
332 * The allocation failed. If we built part of