[CIFS] rmmod cifs can oops if done soon after the last cifs unmount

Signed-off-by: Shaggy (shaggy@austin.ibm.com)
Signed-off-by: Steve French (sfrench@us.ibm.com)
This commit is contained in:
Steve French 2005-08-18 09:37:34 -07:00
parent 1982c344f1
commit f191401f59
2 changed files with 19 additions and 8 deletions

View File

@ -834,8 +834,8 @@ static int cifs_oplock_thread(void * dummyarg)
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
} }
} while(!signal_pending(current)); } while(!signal_pending(current));
complete_and_exit (&cifs_oplock_exited, 0);
oplockThread = NULL; oplockThread = NULL;
complete_and_exit (&cifs_oplock_exited, 0);
} }
static int __init static int __init

View File

@ -29,6 +29,7 @@
#include <linux/utsname.h> #include <linux/utsname.h>
#include <linux/mempool.h> #include <linux/mempool.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/completion.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/processor.h> #include <asm/processor.h>
#include "cifspdu.h" #include "cifspdu.h"
@ -44,6 +45,8 @@
#define CIFS_PORT 445 #define CIFS_PORT 445
#define RFC1001_PORT 139 #define RFC1001_PORT 139
static DECLARE_COMPLETION(cifsd_complete);
extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
unsigned char *p24); unsigned char *p24);
extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
@ -339,6 +342,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
atomic_inc(&tcpSesAllocCount); atomic_inc(&tcpSesAllocCount);
length = tcpSesAllocCount.counter; length = tcpSesAllocCount.counter;
write_unlock(&GlobalSMBSeslock); write_unlock(&GlobalSMBSeslock);
complete(&cifsd_complete);
if(length > 1) { if(length > 1) {
mempool_resize(cifs_req_poolp, mempool_resize(cifs_req_poolp,
length + cifs_min_rcv, length + cifs_min_rcv,
@ -676,7 +680,7 @@ multi_t2_fnd:
msleep(125); msleep(125);
} }
if (list_empty(&server->pending_mid_q)) { if (!list_empty(&server->pending_mid_q)) {
/* mpx threads have not exited yet give them /* mpx threads have not exited yet give them
at least the smb send timeout time for long ops */ at least the smb send timeout time for long ops */
/* due to delays on oplock break requests, we need /* due to delays on oplock break requests, we need
@ -713,7 +717,7 @@ multi_t2_fnd:
GFP_KERNEL); GFP_KERNEL);
} }
msleep(250); complete_and_exit(&cifsd_complete, 0);
return 0; return 0;
} }
@ -1617,8 +1621,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
kfree(volume_info.password); kfree(volume_info.password);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} else }
rc = 0; wait_for_completion(&cifsd_complete);
rc = 0;
memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
srvTcp->sequence_number = 0; srvTcp->sequence_number = 0;
} }
@ -1759,8 +1764,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
spin_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
srvTcp->tcpStatus = CifsExiting; srvTcp->tcpStatus = CifsExiting;
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
if(srvTcp->tsk) if(srvTcp->tsk) {
send_sig(SIGKILL,srvTcp->tsk,1); send_sig(SIGKILL,srvTcp->tsk,1);
wait_for_completion(&cifsd_complete);
}
} }
/* If find_unc succeeded then rc == 0 so we can not end */ /* If find_unc succeeded then rc == 0 so we can not end */
if (tcon) /* up accidently freeing someone elses tcon struct */ if (tcon) /* up accidently freeing someone elses tcon struct */
@ -1773,8 +1780,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
temp_rc = CIFSSMBLogoff(xid, pSesInfo); temp_rc = CIFSSMBLogoff(xid, pSesInfo);
/* if the socketUseCount is now zero */ /* if the socketUseCount is now zero */
if((temp_rc == -ESHUTDOWN) && if((temp_rc == -ESHUTDOWN) &&
(pSesInfo->server->tsk)) (pSesInfo->server->tsk)) {
send_sig(SIGKILL,pSesInfo->server->tsk,1); send_sig(SIGKILL,pSesInfo->server->tsk,1);
wait_for_completion(&cifsd_complete);
}
} else } else
cFYI(1, ("No session or bad tcon")); cFYI(1, ("No session or bad tcon"));
sesInfoFree(pSesInfo); sesInfoFree(pSesInfo);
@ -3241,8 +3250,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
return 0; return 0;
} else if (rc == -ESHUTDOWN) { } else if (rc == -ESHUTDOWN) {
cFYI(1,("Waking up socket by sending it signal")); cFYI(1,("Waking up socket by sending it signal"));
if(cifsd_task) if(cifsd_task) {
send_sig(SIGKILL,cifsd_task,1); send_sig(SIGKILL,cifsd_task,1);
wait_for_completion(&cifsd_complete);
}
rc = 0; rc = 0;
} /* else - we have an smb session } /* else - we have an smb session
left on this socket do not kill cifsd */ left on this socket do not kill cifsd */