diff options
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 80 |
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; | |||
59 | unsigned int sign_CIFS_PDUs = 1; | 59 | unsigned int sign_CIFS_PDUs = 1; |
60 | extern struct task_struct * oplockThread; /* remove sparse warning */ | 60 | extern struct task_struct * oplockThread; /* remove sparse warning */ |
61 | struct task_struct * oplockThread = NULL; | 61 | struct task_struct * oplockThread = NULL; |
62 | extern struct task_struct * dnotifyThread; /* remove sparse warning */ | ||
63 | struct task_struct * dnotifyThread = NULL; | ||
62 | unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; | 64 | unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; |
63 | module_param(CIFSMaxBufSize, int, 0); | 65 | module_param(CIFSMaxBufSize, int, 0); |
64 | MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); | 66 | MODULE_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); | |||
73 | MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); | 75 | MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); |
74 | 76 | ||
75 | static DECLARE_COMPLETION(cifs_oplock_exited); | 77 | static DECLARE_COMPLETION(cifs_oplock_exited); |
78 | static DECLARE_COMPLETION(cifs_dnotify_exited); | ||
76 | 79 | ||
77 | extern mempool_t *cifs_sm_req_poolp; | 80 | extern mempool_t *cifs_sm_req_poolp; |
78 | extern mempool_t *cifs_req_poolp; | 81 | extern 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 | ||
408 | static 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 | |||
401 | static int cifs_remount(struct super_block *sb, int *flags, char *data) | 436 | static 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 | |||
878 | static 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 | ||
843 | static int __init | 893 | static 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 | ||
923 | MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); | 987 | MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); |