aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r--fs/cifs/cifsfs.c80
1 files changed, 72 insertions, 8 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 1ebf7dafc1d7..877095a1192a 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -59,6 +59,8 @@ unsigned int ntlmv2_support = 0;
59unsigned int sign_CIFS_PDUs = 1; 59unsigned int sign_CIFS_PDUs = 1;
60extern struct task_struct * oplockThread; /* remove sparse warning */ 60extern struct task_struct * oplockThread; /* remove sparse warning */
61struct task_struct * oplockThread = NULL; 61struct task_struct * oplockThread = NULL;
62extern struct task_struct * dnotifyThread; /* remove sparse warning */
63struct task_struct * dnotifyThread = NULL;
62unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 64unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
63module_param(CIFSMaxBufSize, int, 0); 65module_param(CIFSMaxBufSize, int, 0);
64MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); 66MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
@@ -73,6 +75,7 @@ module_param(cifs_max_pending, int, 0);
73MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); 75MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
74 76
75static DECLARE_COMPLETION(cifs_oplock_exited); 77static DECLARE_COMPLETION(cifs_oplock_exited);
78static DECLARE_COMPLETION(cifs_dnotify_exited);
76 79
77extern mempool_t *cifs_sm_req_poolp; 80extern mempool_t *cifs_sm_req_poolp;
78extern mempool_t *cifs_req_poolp; 81extern mempool_t *cifs_req_poolp;
@@ -202,6 +205,10 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf)
202#endif /* CIFS_EXPERIMENTAL */ 205#endif /* CIFS_EXPERIMENTAL */
203 rc = CIFSSMBQFSInfo(xid, pTcon, buf); 206 rc = CIFSSMBQFSInfo(xid, pTcon, buf);
204 207
208 /* Old Windows servers do not support level 103, retry with level
209 one if old server failed the previous call */
210 if(rc)
211 rc = SMBOldQFSInfo(xid, pTcon, buf);
205 /* 212 /*
206 int f_type; 213 int f_type;
207 __fsid_t f_fsid; 214 __fsid_t f_fsid;
@@ -253,7 +260,7 @@ cifs_alloc_inode(struct super_block *sb)
253 cifs_inode->clientCanCacheAll = FALSE; 260 cifs_inode->clientCanCacheAll = FALSE;
254 cifs_inode->vfs_inode.i_blksize = CIFS_MAX_MSGSIZE; 261 cifs_inode->vfs_inode.i_blksize = CIFS_MAX_MSGSIZE;
255 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 262 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
256 263 cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;
257 INIT_LIST_HEAD(&cifs_inode->openFileList); 264 INIT_LIST_HEAD(&cifs_inode->openFileList);
258 return &cifs_inode->vfs_inode; 265 return &cifs_inode->vfs_inode;
259} 266}
@@ -398,6 +405,34 @@ static struct quotactl_ops cifs_quotactl_ops = {
398}; 405};
399#endif 406#endif
400 407
408static void cifs_umount_begin(struct super_block * sblock)
409{
410 struct cifs_sb_info *cifs_sb;
411 struct cifsTconInfo * tcon;
412
413 cifs_sb = CIFS_SB(sblock);
414 if(cifs_sb == NULL)
415 return;
416
417 tcon = cifs_sb->tcon;
418 if(tcon == NULL)
419 return;
420 down(&tcon->tconSem);
421 if (atomic_read(&tcon->useCount) == 1)
422 tcon->tidStatus = CifsExiting;
423 up(&tcon->tconSem);
424
425 if(tcon->ses && tcon->ses->server)
426 {
427 cERROR(1,("wake up tasks now - umount begin not complete"));
428 wake_up_all(&tcon->ses->server->request_q);
429 }
430/* BB FIXME - finish add checks for tidStatus BB */
431
432 return;
433}
434
435
401static int cifs_remount(struct super_block *sb, int *flags, char *data) 436static int cifs_remount(struct super_block *sb, int *flags, char *data)
402{ 437{
403 *flags |= MS_NODIRATIME; 438 *flags |= MS_NODIRATIME;
@@ -415,7 +450,7 @@ struct super_operations cifs_super_ops = {
415 unless later we add lazy close of inodes or unless the kernel forgets to call 450 unless later we add lazy close of inodes or unless the kernel forgets to call
416 us with the same number of releases (closes) as opens */ 451 us with the same number of releases (closes) as opens */
417 .show_options = cifs_show_options, 452 .show_options = cifs_show_options,
418/* .umount_begin = cifs_umount_begin, *//* consider adding in the future */ 453/* .umount_begin = cifs_umount_begin, */ /* BB finish in the future */
419 .remount_fs = cifs_remount, 454 .remount_fs = cifs_remount,
420}; 455};
421 456
@@ -783,9 +818,7 @@ static int cifs_oplock_thread(void * dummyarg)
783 do { 818 do {
784 if (try_to_freeze()) 819 if (try_to_freeze())
785 continue; 820 continue;
786 set_current_state(TASK_INTERRUPTIBLE);
787 821
788 schedule_timeout(1*HZ);
789 spin_lock(&GlobalMid_Lock); 822 spin_lock(&GlobalMid_Lock);
790 if(list_empty(&GlobalOplock_Q)) { 823 if(list_empty(&GlobalOplock_Q)) {
791 spin_unlock(&GlobalMid_Lock); 824 spin_unlock(&GlobalMid_Lock);
@@ -834,10 +867,27 @@ static int cifs_oplock_thread(void * dummyarg)
834 } 867 }
835 } else 868 } else
836 spin_unlock(&GlobalMid_Lock); 869 spin_unlock(&GlobalMid_Lock);
870 set_current_state(TASK_INTERRUPTIBLE);
871 schedule_timeout(1); /* yield in case q were corrupt */
837 } 872 }
838 } while(!signal_pending(current)); 873 } while(!signal_pending(current));
839 complete_and_exit (&cifs_oplock_exited, 0);
840 oplockThread = NULL; 874 oplockThread = NULL;
875 complete_and_exit (&cifs_oplock_exited, 0);
876}
877
878static int cifs_dnotify_thread(void * dummyarg)
879{
880 daemonize("cifsdnotifyd");
881 allow_signal(SIGTERM);
882
883 dnotifyThread = current;
884 do {
885 if(try_to_freeze())
886 continue;
887 set_current_state(TASK_INTERRUPTIBLE);
888 schedule_timeout(39*HZ);
889 } while(!signal_pending(current));
890 complete_and_exit (&cifs_dnotify_exited, 0);
841} 891}
842 892
843static int __init 893static int __init
@@ -851,6 +901,10 @@ init_cifs(void)
851 INIT_LIST_HEAD(&GlobalSMBSessionList); 901 INIT_LIST_HEAD(&GlobalSMBSessionList);
852 INIT_LIST_HEAD(&GlobalTreeConnectionList); 902 INIT_LIST_HEAD(&GlobalTreeConnectionList);
853 INIT_LIST_HEAD(&GlobalOplock_Q); 903 INIT_LIST_HEAD(&GlobalOplock_Q);
904#ifdef CONFIG_CIFS_EXPERIMENTAL
905 INIT_LIST_HEAD(&GlobalDnotifyReqList);
906 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
907#endif
854/* 908/*
855 * Initialize Global counters 909 * Initialize Global counters
856 */ 910 */
@@ -886,10 +940,16 @@ init_cifs(void)
886 if (!rc) { 940 if (!rc) {
887 rc = (int)kernel_thread(cifs_oplock_thread, NULL, 941 rc = (int)kernel_thread(cifs_oplock_thread, NULL,
888 CLONE_FS | CLONE_FILES | CLONE_VM); 942 CLONE_FS | CLONE_FILES | CLONE_VM);
889 if(rc > 0) 943 if(rc > 0) {
890 return 0; 944 rc = (int)kernel_thread(cifs_dnotify_thread, NULL,
891 else 945 CLONE_FS | CLONE_FILES | CLONE_VM);
946 if(rc > 0)
947 return 0;
948 else
949 cERROR(1,("error %d create dnotify thread", rc));
950 } else {
892 cERROR(1,("error %d create oplock thread",rc)); 951 cERROR(1,("error %d create oplock thread",rc));
952 }
893 } 953 }
894 cifs_destroy_request_bufs(); 954 cifs_destroy_request_bufs();
895 } 955 }
@@ -918,6 +978,10 @@ exit_cifs(void)
918 send_sig(SIGTERM, oplockThread, 1); 978 send_sig(SIGTERM, oplockThread, 1);
919 wait_for_completion(&cifs_oplock_exited); 979 wait_for_completion(&cifs_oplock_exited);
920 } 980 }
981 if(dnotifyThread) {
982 send_sig(SIGTERM, dnotifyThread, 1);
983 wait_for_completion(&cifs_dnotify_exited);
984 }
921} 985}
922 986
923MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); 987MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");