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>"); |
