Commit 0e9f1916 authored by Steve French's avatar Steve French Committed by Steve French

Do not kill cifsd thread until last smb session on tcp session is

SMBulogged off.  Fixes umounting bug (pointed out by Nick Millington)
when multiple mounts with different userids are mounted to the same
server from the client.  

Signed-off-by: Steve French (sfrench@us.ibm.com)
parent c0fb8b10
...@@ -31,7 +31,7 @@ Thanks to those in the community who have submitted detailed bug reports ...@@ -31,7 +31,7 @@ Thanks to those in the community who have submitted detailed bug reports
and debug of problems they have found: Jochen Dolze, David Blaine, and debug of problems they have found: Jochen Dolze, David Blaine,
Rene Scharfe, Martin Josefsson, Alexander Wild, Anthony Liguori, Rene Scharfe, Martin Josefsson, Alexander Wild, Anthony Liguori,
Lars Muller, Urban Widmark, Massimiliano Ferrero, Howard Owen, Lars Muller, Urban Widmark, Massimiliano Ferrero, Howard Owen,
Olaf Kirch, Kieron Briggs and others. Olaf Kirch, Kieron Briggs, Nick Millington and others.
And thanks to the IBM LTC and Power test teams and SuSE testers for And thanks to the IBM LTC and Power test teams and SuSE testers for
finding multiple bugs during excellent stress test runs. finding multiple bugs during excellent stress test runs.
...@@ -3,6 +3,9 @@ Version 1.19 ...@@ -3,6 +3,9 @@ Version 1.19
Fix /proc/fs/cifs/Stats and DebugData display to handle larger Fix /proc/fs/cifs/Stats and DebugData display to handle larger
amounts of return data. Properly limit requests to MAX_REQ (50 amounts of return data. Properly limit requests to MAX_REQ (50
is the usual maximum active multiplex SMB/CIFS requests per server). is the usual maximum active multiplex SMB/CIFS requests per server).
Do not kill cifsd (and thus hurt the other SMB session) when more than one
session to the same server (but with different userids) exists and one
of the two user's smb sessions is being removed while leaving the other.
Version 1.18 Version 1.18
......
...@@ -387,6 +387,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) ...@@ -387,6 +387,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
spin_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
ses->server->tcpStatus = CifsExiting; ses->server->tcpStatus = CifsExiting;
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
rc = -ESHUTDOWN;
} }
} }
if (pSMB) if (pSMB)
......
...@@ -453,7 +453,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -453,7 +453,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
/* 1/8th of sec should be more than enough time for them to exit */ /* 1/8th of sec is more than enough time for them to exit */
schedule_timeout(HZ/8); schedule_timeout(HZ/8);
} }
...@@ -468,7 +468,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -468,7 +468,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
} }
kfree(server); kfree(server);
cFYI(1, ("About to exit from demultiplex thread")); set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/4);
return 0; return 0;
} }
...@@ -2769,6 +2770,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) ...@@ -2769,6 +2770,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
int rc = 0; int rc = 0;
int xid; int xid;
struct cifsSesInfo *ses = NULL; struct cifsSesInfo *ses = NULL;
struct task_struct *cifsd_task;
xid = GetXid(); xid = GetXid();
...@@ -2781,19 +2783,25 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) ...@@ -2781,19 +2783,25 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
} }
tconInfoFree(cifs_sb->tcon); tconInfoFree(cifs_sb->tcon);
if ((ses) && (ses->server)) { if ((ses) && (ses->server)) {
/* save off task so we do not refer to ses later */
cifsd_task = ses->server->tsk;
cFYI(1, ("About to do SMBLogoff ")); cFYI(1, ("About to do SMBLogoff "));
rc = CIFSSMBLogoff(xid, ses); rc = CIFSSMBLogoff(xid, ses);
if (rc == -EBUSY) { if (rc == -EBUSY) {
FreeXid(xid); FreeXid(xid);
return 0; return 0;
} } else if (rc == -ESHUTDOWN) {
/* should we add wake_up_all(&server->request_q);
set_current_state(TASK_INTERRUPTIBLE); and add a check in the check inFlight loop
schedule_timeout(HZ / 4); /* give captive thread time to exit */ for the session ending */
if((ses->server) && (ses->server->ssocket)) { set_current_state(TASK_INTERRUPTIBLE);
cFYI(1,("Waking up socket by sending it signal ")); /* give captive thread time to exit */
send_sig(SIGKILL,ses->server->tsk,1); schedule_timeout(HZ / 4);
} cFYI(1,("Waking up socket by sending it signal"));
send_sig(SIGKILL,cifsd_task,1);
rc = 0;
} /* else - we have an smb session
left on this socket do not kill cifsd */
} else } else
cFYI(1, ("No session or bad tcon")); cFYI(1, ("No session or bad tcon"));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment