diff options
author | Steve French <sfrench@us.ibm.com> | 2007-05-23 14:45:36 +0000 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2007-05-23 14:45:36 +0000 |
commit | 28356a1679006b110215596e057f304ef3083922 (patch) | |
tree | a0fb257bab98c9fe5057462ee4f9cf84b88100a6 /fs | |
parent | ad9ddd66c6e8a79630a975ff0bb8d45a11abe630 (diff) | |
download | kernel_samsung_smdk4412-28356a1679006b110215596e057f304ef3083922.zip kernel_samsung_smdk4412-28356a1679006b110215596e057f304ef3083922.tar.gz kernel_samsung_smdk4412-28356a1679006b110215596e057f304ef3083922.tar.bz2 |
[CIFS] Fix oops on failed cifs mount (in kthread_stop)
If the cifs demultiplex thread wakes up and exits
(zeroing server->tsk) before kthread_stop is called, the
cifs_mount code could pass a null pointer to kthread_stop
Thanks to akpm, Dave Young and Shaggy for suggesting
earlier versions of this patch.
CC: akpm@linux-foundatior.org
Signed-off-by: Dave Young <hidave.darkstar@gmail.com>
Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/connect.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 216fb62..f6963d1 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2069,8 +2069,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, srvTcp->tcpStatus = CifsExiting; spin_unlock(&GlobalMid_Lock); if (srvTcp->tsk) { + struct task_struct *tsk; + /* If we could verify that kthread_stop would + always wake up processes blocked in + tcp in recv_mesg then we could remove the + send_sig call */ send_sig(SIGKILL,srvTcp->tsk,1); - kthread_stop(srvTcp->tsk); + tsk = srvTcp->tsk; + if(tsk) + kthread_stop(srvTcp->tsk); } } /* If find_unc succeeded then rc == 0 so we can not end */ @@ -2085,8 +2092,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, /* if the socketUseCount is now zero */ if ((temp_rc == -ESHUTDOWN) && (pSesInfo->server) && (pSesInfo->server->tsk)) { + struct task_struct *tsk; send_sig(SIGKILL,pSesInfo->server->tsk,1); - kthread_stop(pSesInfo->server->tsk); + tsk = pSesInfo->server->tsk; + if(tsk) + kthread_stop(tsk); } } else cFYI(1, ("No session or bad tcon")); |