aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-08-18 12:37:34 -0400
committerSteve French <sfrench@us.ibm.com>2005-08-18 12:37:34 -0400
commitf191401f5906f4d942fac87ebeb4671faf1ba7d6 (patch)
tree5d918edb41604cde78668e3fba2cfd9fb4f11641
parent1982c344f1bf08118f7c224958b30c64e162009e (diff)
[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)
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/connect.c25
2 files changed, 19 insertions, 8 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 8cc23e7d0d5d..7fda0f7d9c00 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -834,8 +834,8 @@ static int cifs_oplock_thread(void * dummyarg)
834 spin_unlock(&GlobalMid_Lock); 834 spin_unlock(&GlobalMid_Lock);
835 } 835 }
836 } while(!signal_pending(current)); 836 } while(!signal_pending(current));
837 complete_and_exit (&cifs_oplock_exited, 0);
838 oplockThread = NULL; 837 oplockThread = NULL;
838 complete_and_exit (&cifs_oplock_exited, 0);
839} 839}
840 840
841static int __init 841static int __init
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 9e8256003f73..ef0432c44482 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -29,6 +29,7 @@
29#include <linux/utsname.h> 29#include <linux/utsname.h>
30#include <linux/mempool.h> 30#include <linux/mempool.h>
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/completion.h>
32#include <asm/uaccess.h> 33#include <asm/uaccess.h>
33#include <asm/processor.h> 34#include <asm/processor.h>
34#include "cifspdu.h" 35#include "cifspdu.h"
@@ -44,6 +45,8 @@
44#define CIFS_PORT 445 45#define CIFS_PORT 445
45#define RFC1001_PORT 139 46#define RFC1001_PORT 139
46 47
48static DECLARE_COMPLETION(cifsd_complete);
49
47extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, 50extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
48 unsigned char *p24); 51 unsigned char *p24);
49extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, 52extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
@@ -339,6 +342,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
339 atomic_inc(&tcpSesAllocCount); 342 atomic_inc(&tcpSesAllocCount);
340 length = tcpSesAllocCount.counter; 343 length = tcpSesAllocCount.counter;
341 write_unlock(&GlobalSMBSeslock); 344 write_unlock(&GlobalSMBSeslock);
345 complete(&cifsd_complete);
342 if(length > 1) { 346 if(length > 1) {
343 mempool_resize(cifs_req_poolp, 347 mempool_resize(cifs_req_poolp,
344 length + cifs_min_rcv, 348 length + cifs_min_rcv,
@@ -676,7 +680,7 @@ multi_t2_fnd:
676 msleep(125); 680 msleep(125);
677 } 681 }
678 682
679 if (list_empty(&server->pending_mid_q)) { 683 if (!list_empty(&server->pending_mid_q)) {
680 /* mpx threads have not exited yet give them 684 /* mpx threads have not exited yet give them
681 at least the smb send timeout time for long ops */ 685 at least the smb send timeout time for long ops */
682 /* due to delays on oplock break requests, we need 686 /* due to delays on oplock break requests, we need
@@ -713,7 +717,7 @@ multi_t2_fnd:
713 GFP_KERNEL); 717 GFP_KERNEL);
714 } 718 }
715 719
716 msleep(250); 720 complete_and_exit(&cifsd_complete, 0);
717 return 0; 721 return 0;
718} 722}
719 723
@@ -1617,8 +1621,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1617 kfree(volume_info.password); 1621 kfree(volume_info.password);
1618 FreeXid(xid); 1622 FreeXid(xid);
1619 return rc; 1623 return rc;
1620 } else 1624 }
1621 rc = 0; 1625 wait_for_completion(&cifsd_complete);
1626 rc = 0;
1622 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); 1627 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
1623 srvTcp->sequence_number = 0; 1628 srvTcp->sequence_number = 0;
1624 } 1629 }
@@ -1759,8 +1764,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1759 spin_lock(&GlobalMid_Lock); 1764 spin_lock(&GlobalMid_Lock);
1760 srvTcp->tcpStatus = CifsExiting; 1765 srvTcp->tcpStatus = CifsExiting;
1761 spin_unlock(&GlobalMid_Lock); 1766 spin_unlock(&GlobalMid_Lock);
1762 if(srvTcp->tsk) 1767 if(srvTcp->tsk) {
1763 send_sig(SIGKILL,srvTcp->tsk,1); 1768 send_sig(SIGKILL,srvTcp->tsk,1);
1769 wait_for_completion(&cifsd_complete);
1770 }
1764 } 1771 }
1765 /* If find_unc succeeded then rc == 0 so we can not end */ 1772 /* If find_unc succeeded then rc == 0 so we can not end */
1766 if (tcon) /* up accidently freeing someone elses tcon struct */ 1773 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,
1773 temp_rc = CIFSSMBLogoff(xid, pSesInfo); 1780 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
1774 /* if the socketUseCount is now zero */ 1781 /* if the socketUseCount is now zero */
1775 if((temp_rc == -ESHUTDOWN) && 1782 if((temp_rc == -ESHUTDOWN) &&
1776 (pSesInfo->server->tsk)) 1783 (pSesInfo->server->tsk)) {
1777 send_sig(SIGKILL,pSesInfo->server->tsk,1); 1784 send_sig(SIGKILL,pSesInfo->server->tsk,1);
1785 wait_for_completion(&cifsd_complete);
1786 }
1778 } else 1787 } else
1779 cFYI(1, ("No session or bad tcon")); 1788 cFYI(1, ("No session or bad tcon"));
1780 sesInfoFree(pSesInfo); 1789 sesInfoFree(pSesInfo);
@@ -3241,8 +3250,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3241 return 0; 3250 return 0;
3242 } else if (rc == -ESHUTDOWN) { 3251 } else if (rc == -ESHUTDOWN) {
3243 cFYI(1,("Waking up socket by sending it signal")); 3252 cFYI(1,("Waking up socket by sending it signal"));
3244 if(cifsd_task) 3253 if(cifsd_task) {
3245 send_sig(SIGKILL,cifsd_task,1); 3254 send_sig(SIGKILL,cifsd_task,1);
3255 wait_for_completion(&cifsd_complete);
3256 }
3246 rc = 0; 3257 rc = 0;
3247 } /* else - we have an smb session 3258 } /* else - we have an smb session
3248 left on this socket do not kill cifsd */ 3259 left on this socket do not kill cifsd */