Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 454

kernel-2.6.18-238.el5.src.rpm

From: Jeff Layton <jlayton@redhat.com>
Date: Thu, 5 Jul 2007 10:22:46 -0400
Subject: [cifs] make demux thread ignore signals from userspace
Message-id: 20070705102246.e9298b16.jlayton@redhat.com
O-Subject: [RHEL5 PATCH] make cifs demux thread ignore signals from userspace
Bugzilla: 245674

Currently, the cifs_mount and cifs_umount functions send a SIGKILL to
the demuliplexer thread to make it break out of kernel_recvmsg. Without
this, there can be a long delay when mounting or unmounting filesystems
while the demux thread waits for the call to time out. In order to do
this, it explicitly does an allow_signal(SIGKILL) when the thread
starts.

The reproducer for this problem is pretty non-sensical, but it involves
mounting a cifs share that has dropped off the net and then sending a
SIGKILL to cifsd (exact steps are in the BZ). You might be wondering
"why would someone want to try to kill their kernel thread"? A very good
question and not one to which I've ever gotten a good answer.

In any case, the following patch corrects the issue by making the thread
ignore all signals and having cifs_mount and cifs_umount use force_sig
instead of send_sig. This insulates the thread from userspace signals,
while still allowing it to break out of kernel_recvmsg for mounts and
unmounts.

As a side note, the upstream cifs list is tossing around ideas for how to
make it so that signals aren't needed at all. There seems to be a general
idea that signals and kthreads shouldn't mix, though I've not gotten a
clear explanation of why this is.
---
 fs/cifs/connect.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index abcabb4..aba3f05 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -369,7 +369,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
 	sprintf(current->comm,"cifsd");
 #else
 	daemonize("cifsd");
-	allow_signal(SIGKILL);
 #endif
 	current->flags |= PF_MEMALLOC;
 	server->tsk = current;	/* save process info to wake at shutdown */
@@ -2055,7 +2054,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 			srvTcp->tcpStatus = CifsExiting;
 			spin_unlock(&GlobalMid_Lock);
 			if(srvTcp->tsk) {
-				send_sig(SIGKILL,srvTcp->tsk,1);
+				force_sig(SIGKILL,srvTcp->tsk);
 				wait_for_completion(&cifsd_complete);
 			}
 		}
@@ -2071,7 +2070,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 					/* if the socketUseCount is now zero */
 					if((temp_rc == -ESHUTDOWN) &&
 					   (pSesInfo->server->tsk)) {
-						send_sig(SIGKILL,pSesInfo->server->tsk,1);
+						force_sig(SIGKILL,pSesInfo->server->tsk);
 						wait_for_completion(&cifsd_complete);
 					}
 				} else
@@ -3392,7 +3391,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
 			} else if (rc == -ESHUTDOWN) {
 				cFYI(1,("Waking up socket by sending it signal"));
 				if(cifsd_task) {
-					send_sig(SIGKILL,cifsd_task,1);
+					force_sig(SIGKILL,cifsd_task);
 					wait_for_completion(&cifsd_complete);
 				}
 				rc = 0;
-- 
1.5.3.5.645.gbb47